import cyrus-sasl-2.1.23 cyrus-sasl-2.1.23
authorLuke Howard <lukeh@padl.com>
Fri, 24 Sep 2010 14:47:20 +0000 (16:47 +0200)
committerLuke Howard <lukeh@padl.com>
Fri, 24 Sep 2010 14:47:20 +0000 (16:47 +0200)
626 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
INSTALL [new file with mode: 0644]
INSTALL.TXT [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.in [new file with mode: 0644]
NEWS [new file with mode: 0644]
NTMakefile [new file with mode: 0644]
README [new file with mode: 0644]
aclocal.m4 [new file with mode: 0644]
cmulocal/COPYING [new file with mode: 0644]
cmulocal/README.andrew [new file with mode: 0644]
cmulocal/afs.m4 [new file with mode: 0644]
cmulocal/agentx.m4 [new file with mode: 0644]
cmulocal/arx.m4 [new file with mode: 0644]
cmulocal/ax_path_bdb.m4 [new file with mode: 0644]
cmulocal/berkdb.m4 [new file with mode: 0644]
cmulocal/bsd_sockets.m4 [new file with mode: 0644]
cmulocal/c-attribute.m4 [new file with mode: 0644]
cmulocal/c-fpic.m4 [new file with mode: 0644]
cmulocal/clamav.m4 [new file with mode: 0644]
cmulocal/com_err.m4 [new file with mode: 0644]
cmulocal/com_err_link.m4 [new file with mode: 0644]
cmulocal/common.m4 [new file with mode: 0644]
cmulocal/cyrus.m4 [new file with mode: 0644]
cmulocal/db.m4 [new file with mode: 0644]
cmulocal/find-func-no-libs.m4 [new file with mode: 0644]
cmulocal/find-func-no-libs2.m4 [new file with mode: 0644]
cmulocal/find-func.m4 [new file with mode: 0644]
cmulocal/heimdal.m4 [new file with mode: 0644]
cmulocal/init_automake.m4 [new file with mode: 0644]
cmulocal/ipv6.m4 [new file with mode: 0644]
cmulocal/kafs.m4 [new file with mode: 0644]
cmulocal/kerberos_v4.m4 [new file with mode: 0644]
cmulocal/kerberos_v5.m4 [new file with mode: 0644]
cmulocal/libXau.m4 [new file with mode: 0644]
cmulocal/libcyrus.m4 [new file with mode: 0644]
cmulocal/libloguse.m4 [new file with mode: 0644]
cmulocal/libnet.m4 [new file with mode: 0644]
cmulocal/libpcap.m4 [new file with mode: 0644]
cmulocal/librestrict.m4 [new file with mode: 0644]
cmulocal/libssl.m4 [new file with mode: 0644]
cmulocal/libtoolhack.m4 [new file with mode: 0644]
cmulocal/libwrap.m4 [new file with mode: 0644]
cmulocal/mips-abi.m4 [new file with mode: 0644]
cmulocal/nadine.m4 [new file with mode: 0644]
cmulocal/nana.m4 [new file with mode: 0644]
cmulocal/openldap.m4 [new file with mode: 0644]
cmulocal/openssl.m4 [new file with mode: 0644]
cmulocal/pthreads.m4 [new file with mode: 0644]
cmulocal/sasl.m4 [new file with mode: 0644]
cmulocal/sasl2.m4 [new file with mode: 0644]
cmulocal/tcl.m4 [new file with mode: 0644]
cmulocal/telnet.m4 [new file with mode: 0644]
cmulocal/ucdsnmp.m4 [new file with mode: 0644]
cmulocal/util.m4 [new file with mode: 0644]
cmulocal/zephyr.m4 [new file with mode: 0644]
config.h.in [new file with mode: 0644]
config/.cvsignore [new file with mode: 0644]
config/Info.plist [new file with mode: 0644]
config/config.guess [new file with mode: 0755]
config/config.sub [new file with mode: 0755]
config/depcomp [new file with mode: 0755]
config/install-sh [new file with mode: 0755]
config/kerberos_v4.m4 [new file with mode: 0644]
config/libtool.m4 [new file with mode: 0644]
config/ltconfig [new file with mode: 0755]
config/ltmain.sh [new file with mode: 0644]
config/missing [new file with mode: 0755]
config/mkinstalldirs [new file with mode: 0755]
config/plain.m4 [new file with mode: 0644]
config/sasl.spec [new file with mode: 0644]
config/sasldb.m4 [new file with mode: 0644]
configure [new file with mode: 0755]
configure.in [new file with mode: 0644]
dlcompat-20010505/APPLE_LICENSE [new file with mode: 0644]
dlcompat-20010505/ChangeLog [new file with mode: 0644]
dlcompat-20010505/Makefile [new file with mode: 0644]
dlcompat-20010505/README [new file with mode: 0644]
dlcompat-20010505/dlfcn.h [new file with mode: 0644]
dlcompat-20010505/dlopen.c [new file with mode: 0644]
doc/Makefile.am [new file with mode: 0644]
doc/Makefile.in [new file with mode: 0644]
doc/NTMakefile [new file with mode: 0644]
doc/ONEWS [new file with mode: 0644]
doc/TODO [new file with mode: 0644]
doc/advanced.html [new file with mode: 0644]
doc/appconvert.html [new file with mode: 0644]
doc/components.html [new file with mode: 0644]
doc/draft-burdis-cat-srp-sasl-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-anon-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-crammd5-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-gssapi-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-plain-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-rfc2222bis-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-rfc2831bis-xx.txt [new file with mode: 0644]
doc/draft-ietf-sasl-saslprep-xx.txt [new file with mode: 0644]
doc/draft-murchison-sasl-login-xx.txt [new file with mode: 0644]
doc/draft-newman-sasl-c-api-xx.txt [new file with mode: 0644]
doc/draft-newman-sasl-passdss-xx.txt [new file with mode: 0644]
doc/gssapi.html [new file with mode: 0644]
doc/index.html [new file with mode: 0644]
doc/install.html [new file with mode: 0644]
doc/macosx.html [new file with mode: 0644]
doc/mechanisms.html [new file with mode: 0644]
doc/options.html [new file with mode: 0644]
doc/plugprog.html [new file with mode: 0644]
doc/programming.html [new file with mode: 0644]
doc/readme.html [new file with mode: 0644]
doc/rfc1321.txt [new file with mode: 0644]
doc/rfc1939.txt [new file with mode: 0644]
doc/rfc2104.txt [new file with mode: 0644]
doc/rfc2195.txt [new file with mode: 0644]
doc/rfc2222.txt [new file with mode: 0644]
doc/rfc2243.txt [new file with mode: 0644]
doc/rfc2245.txt [new file with mode: 0644]
doc/rfc2289.txt [new file with mode: 0644]
doc/rfc2444.txt [new file with mode: 0644]
doc/rfc2595.txt [new file with mode: 0644]
doc/rfc2831.txt [new file with mode: 0644]
doc/rfc2945.txt [new file with mode: 0644]
doc/rfc3174.txt [new file with mode: 0644]
doc/server-plugin-flow.fig [new file with mode: 0644]
doc/sysadmin.html [new file with mode: 0644]
doc/testing.txt [new file with mode: 0644]
doc/upgrading.html [new file with mode: 0644]
doc/windows.html [new file with mode: 0755]
include/Makefile.am [new file with mode: 0644]
include/Makefile.in [new file with mode: 0644]
include/NTMakefile [new file with mode: 0644]
include/exits.h [new file with mode: 0644]
include/gai.h [new file with mode: 0644]
include/hmac-md5.h [new file with mode: 0755]
include/makemd5.c [new file with mode: 0644]
include/md5.h [new file with mode: 0644]
include/md5global.h [new file with mode: 0644]
include/prop.h [new file with mode: 0644]
include/sasl.h [new file with mode: 0755]
include/saslplug.h [new file with mode: 0755]
include/saslutil.h [new file with mode: 0755]
java/CyrusSasl/ClientFactory.java [new file with mode: 0644]
java/CyrusSasl/GenericClient.java [new file with mode: 0644]
java/CyrusSasl/GenericCommon.java [new file with mode: 0644]
java/CyrusSasl/GenericServer.java [new file with mode: 0644]
java/CyrusSasl/Makefile.am [new file with mode: 0644]
java/CyrusSasl/Makefile.in [new file with mode: 0644]
java/CyrusSasl/Sasl.java [new file with mode: 0644]
java/CyrusSasl/SaslClient.java [new file with mode: 0644]
java/CyrusSasl/SaslClientFactory.java [new file with mode: 0644]
java/CyrusSasl/SaslException.java [new file with mode: 0644]
java/CyrusSasl/SaslInputStream.java [new file with mode: 0644]
java/CyrusSasl/SaslOutputStream.java [new file with mode: 0644]
java/CyrusSasl/SaslServer.java [new file with mode: 0644]
java/CyrusSasl/SaslServerFactory.java [new file with mode: 0644]
java/CyrusSasl/SaslUtils.java [new file with mode: 0644]
java/CyrusSasl/ServerFactory.java [new file with mode: 0644]
java/CyrusSasl/javasasl.c [new file with mode: 0644]
java/CyrusSasl/javasasl.h [new file with mode: 0644]
java/Makefile.am [new file with mode: 0644]
java/Makefile.in [new file with mode: 0644]
java/README [new file with mode: 0644]
java/Test/Handler.java [new file with mode: 0644]
java/Test/Makefile.am [new file with mode: 0644]
java/Test/Makefile.in [new file with mode: 0644]
java/Test/ServerHandler.java [new file with mode: 0644]
java/Test/jimtest-compile.sh [new file with mode: 0755]
java/Test/jimtest.java [new file with mode: 0644]
java/Test/jimtest.sh [new file with mode: 0755]
java/Test/testserver.java [new file with mode: 0644]
java/doc/.cvsignore [new file with mode: 0644]
java/doc/draft-weltman-java-sasl-02.txt [new file with mode: 0644]
java/javax/Makefile.am [new file with mode: 0644]
java/javax/Makefile.in [new file with mode: 0644]
java/javax/security/Makefile.am [new file with mode: 0644]
java/javax/security/Makefile.in [new file with mode: 0644]
java/javax/security/auth/Makefile.am [new file with mode: 0644]
java/javax/security/auth/Makefile.in [new file with mode: 0644]
java/javax/security/auth/callback/Callback.java [new file with mode: 0644]
java/javax/security/auth/callback/CallbackHandler.java [new file with mode: 0644]
java/javax/security/auth/callback/Makefile.am [new file with mode: 0644]
java/javax/security/auth/callback/Makefile.in [new file with mode: 0644]
java/javax/security/auth/callback/NameCallback.java [new file with mode: 0644]
java/javax/security/auth/callback/PasswordCallback.java [new file with mode: 0644]
java/javax/security/auth/callback/RealmCallback.java [new file with mode: 0644]
java/javax/security/auth/callback/UnsupportedCallbackException.java [new file with mode: 0644]
lib/Makefile.am [new file with mode: 0644]
lib/Makefile.in [new file with mode: 0644]
lib/NTMakefile [new file with mode: 0755]
lib/auxprop.c [new file with mode: 0644]
lib/canonusr.c [new file with mode: 0644]
lib/checkpw.c [new file with mode: 0644]
lib/client.c [new file with mode: 0644]
lib/common.c [new file with mode: 0644]
lib/config.c [new file with mode: 0644]
lib/dlopen.c [new file with mode: 0644]
lib/external.c [new file with mode: 0644]
lib/getaddrinfo.c [new file with mode: 0644]
lib/getnameinfo.c [new file with mode: 0644]
lib/getsubopt.c [new file with mode: 0644]
lib/md5.c [new file with mode: 0644]
lib/saslint.h [new file with mode: 0644]
lib/saslutil.c [new file with mode: 0644]
lib/server.c [new file with mode: 0644]
lib/seterror.c [new file with mode: 0644]
lib/snprintf.c [new file with mode: 0644]
lib/staticopen.h [new file with mode: 0644]
lib/windlopen.c [new file with mode: 0644]
mac/CommonKClient/KClientPublic.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/KClient.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient/KClient.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/KrbDriver.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/kcglue_des.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient/kcglue_des.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/kcglue_krb.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient/kcglue_krb.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/macKClientPublic.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient/mac_krb_lib1.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache2.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/GSS/GSS.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi_krb5.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KClient/KClient.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KClient/KClientTypes.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KClientCompat/KClientCompat.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KClientDeprecated/KClientDeprecated.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos/Kerberos.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos4/Kerberos4.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos4/krb.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos5/Kerberos5.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos5/krb5.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/Kerberos5/win-mac.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/KerberosComErr.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/com_err.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosDES/KerberosDES.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosDES/des.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLLoginLogoutNotification.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLPrincipalTranslation.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KerberosLogin.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosManager/KerberosManagerLib.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosPreferences/KerberosPreferences.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/KerberosProfile.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/profile.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorLib.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorList.r [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Idle.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosConditionalMacros.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosSupport.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ShlibDriver.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/SocketErrors.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Sockets.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Utilities.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/hesiod.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/netdb.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/pwd.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeper.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeperMenuStateProtocol.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/kcglue_des.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/kcglue_des.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/kcglue_krb.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/kcglue_krb.h [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/mac_krb_lib1.c [new file with mode: 0755]
mac/CommonKClient/mac_kclient3/saslk4.h [new file with mode: 0755]
mac/README.filetypes [new file with mode: 0644]
mac/build_plugins/build_plugins [new file with mode: 0755]
mac/build_plugins/build_plugins.Carbon [new file with mode: 0755]
mac/include/config.h [new file with mode: 0755]
mac/include/extra_krb.h [new file with mode: 0755]
mac/include/md5global.h [new file with mode: 0755]
mac/include/netinet/in.h [new file with mode: 0755]
mac/include/parse_cmd_line.h [new file with mode: 0755]
mac/include/sasl_anonymous_plugin_decl.h [new file with mode: 0755]
mac/include/sasl_crammd5_plugin_decl.h [new file with mode: 0755]
mac/include/sasl_digestmd5_plugin_decl.h [new file with mode: 0755]
mac/include/sasl_kerberos4_plugin_decl.h [new file with mode: 0755]
mac/include/sasl_mac_krb_locl.h [new file with mode: 0755]
mac/include/sasl_plain_plugin_decl.h [new file with mode: 0755]
mac/include/sasl_plugin_decl.h [new file with mode: 0755]
mac/kerberos_includes/conf-svsparc.h [new file with mode: 0755]
mac/kerberos_includes/conf.h [new file with mode: 0755]
mac/kerberos_includes/error_table.h [new file with mode: 0755]
mac/kerberos_includes/kerberos/des.h [new file with mode: 0755]
mac/kerberos_includes/kerberos/des.h.unix [new file with mode: 0755]
mac/kerberos_includes/kerberos/mit-copyright.h [new file with mode: 0755]
mac/kerberos_includes/klog.h [new file with mode: 0755]
mac/kerberos_includes/kparse.h [new file with mode: 0755]
mac/kerberos_includes/krb-protos.h [new file with mode: 0755]
mac/kerberos_includes/krb.h [new file with mode: 0755]
mac/kerberos_includes/krb_conf.h [new file with mode: 0755]
mac/kerberos_includes/ktypes.h [new file with mode: 0755]
mac/kerberos_includes/lsb_addr_comp.h [new file with mode: 0755]
mac/kerberos_includes/mit-sipb-copyright.h [new file with mode: 0755]
mac/kerberos_includes/old_krb.h [new file with mode: 0755]
mac/kerberos_includes/osconf.h [new file with mode: 0755]
mac/kerberos_includes/prot.h [new file with mode: 0755]
mac/krb4_sources/krb-archaeology.h [new file with mode: 0755]
mac/krb4_sources/krb-protos.h [new file with mode: 0755]
mac/krb4_sources/krb.h [new file with mode: 0755]
mac/krb4_sources/lsb_addr_comp.c [new file with mode: 0755]
mac/krb4_sources/mk_auth.c [new file with mode: 0755]
mac/krb4_sources/mk_priv.c [new file with mode: 0755]
mac/krb4_sources/mk_req.c [new file with mode: 0755]
mac/krb4_sources/mk_safe.c [new file with mode: 0755]
mac/krb4_sources/rd_priv.c [new file with mode: 0755]
mac/krb4_sources/rd_safe.c [new file with mode: 0755]
mac/krb4_sources/rw.c [new file with mode: 0755]
mac/libdes/libdes_68K/libdes_68K [new file with mode: 0755]
mac/libdes/libdes_68K/libdes_68K.exp [new file with mode: 0755]
mac/libdes/libdes_fat/libdes_fat [new file with mode: 0755]
mac/libdes/libdes_ppc/libdes_ppc [new file with mode: 0755]
mac/libdes/libdes_ppc/libdes_ppc.Carbon [new file with mode: 0755]
mac/libdes/libdes_ppc/libdes_ppc.Carbon.exp [new file with mode: 0755]
mac/libdes/libdes_ppc/libdes_ppc.exp [new file with mode: 0755]
mac/libdes/public/cfm68k_import_off.h [new file with mode: 0755]
mac/libdes/public/des.h [new file with mode: 0755]
mac/libdes/public/destest.c [new file with mode: 0755]
mac/libdes/src/COPYRIGHT [new file with mode: 0755]
mac/libdes/src/ChangeLog [new file with mode: 0755]
mac/libdes/src/DES.pm [new file with mode: 0755]
mac/libdes/src/DES.pod [new file with mode: 0755]
mac/libdes/src/DES.xs [new file with mode: 0755]
mac/libdes/src/FILES [new file with mode: 0755]
mac/libdes/src/INSTALL [new file with mode: 0755]
mac/libdes/src/Imakefile [new file with mode: 0755]
mac/libdes/src/KERBEROS [new file with mode: 0755]
mac/libdes/src/MODES.DES [new file with mode: 0755]
mac/libdes/src/Makefile.PL [new file with mode: 0755]
mac/libdes/src/Makefile.am [new file with mode: 0755]
mac/libdes/src/Makefile.in [new file with mode: 0755]
mac/libdes/src/Makefile.ssl [new file with mode: 0755]
mac/libdes/src/Makefile.uni [new file with mode: 0755]
mac/libdes/src/PC1 [new file with mode: 0755]
mac/libdes/src/PC2 [new file with mode: 0755]
mac/libdes/src/README [new file with mode: 0755]
mac/libdes/src/VERSION [new file with mode: 0755]
mac/libdes/src/cbc3_enc.c [new file with mode: 0755]
mac/libdes/src/cbc_cksm.c [new file with mode: 0755]
mac/libdes/src/cbc_enc.c [new file with mode: 0755]
mac/libdes/src/cfb64ede.c [new file with mode: 0755]
mac/libdes/src/cfb64enc.c [new file with mode: 0755]
mac/libdes/src/cfb_enc.c [new file with mode: 0755]
mac/libdes/src/des.c [new file with mode: 0755]
mac/libdes/src/des.def [new file with mode: 0755]
mac/libdes/src/des.doc [new file with mode: 0755]
mac/libdes/src/des.dsp [new file with mode: 0755]
mac/libdes/src/des.mak [new file with mode: 0755]
mac/libdes/src/des.man [new file with mode: 0755]
mac/libdes/src/des.org [new file with mode: 0755]
mac/libdes/src/des.pl [new file with mode: 0755]
mac/libdes/src/des_crypt.man [new file with mode: 0755]
mac/libdes/src/des_enc.c [new file with mode: 0755]
mac/libdes/src/des_locl.h [new file with mode: 0755]
mac/libdes/src/des_locl.org [new file with mode: 0755]
mac/libdes/src/des_opts.c [new file with mode: 0755]
mac/libdes/src/des_ver.h [new file with mode: 0755]
mac/libdes/src/dllmain.c [new file with mode: 0755]
mac/libdes/src/doIP [new file with mode: 0755]
mac/libdes/src/doPC1 [new file with mode: 0755]
mac/libdes/src/doPC2 [new file with mode: 0755]
mac/libdes/src/ecb3_enc.c [new file with mode: 0755]
mac/libdes/src/ecb_enc.c [new file with mode: 0755]
mac/libdes/src/ede_enc.c [new file with mode: 0755]
mac/libdes/src/enc_read.c [new file with mode: 0755]
mac/libdes/src/enc_writ.c [new file with mode: 0755]
mac/libdes/src/fcrypt.c [new file with mode: 0755]
mac/libdes/src/key_par.c [new file with mode: 0755]
mac/libdes/src/makefile.bc [new file with mode: 0755]
mac/libdes/src/md4.c [new file with mode: 0755]
mac/libdes/src/md4.h [new file with mode: 0755]
mac/libdes/src/md5.c [new file with mode: 0755]
mac/libdes/src/md5.h [new file with mode: 0755]
mac/libdes/src/mdtest.c [new file with mode: 0755]
mac/libdes/src/ncbc_enc.c [new file with mode: 0755]
mac/libdes/src/ofb64ede.c [new file with mode: 0755]
mac/libdes/src/ofb64enc.c [new file with mode: 0755]
mac/libdes/src/ofb_enc.c [new file with mode: 0755]
mac/libdes/src/passwd_dialog.aps [new file with mode: 0755]
mac/libdes/src/passwd_dialog.clw [new file with mode: 0755]
mac/libdes/src/passwd_dialog.rc [new file with mode: 0755]
mac/libdes/src/passwd_dialog.res [new file with mode: 0755]
mac/libdes/src/passwd_dlg.c [new file with mode: 0755]
mac/libdes/src/passwd_dlg.h [new file with mode: 0755]
mac/libdes/src/pcbc_enc.c [new file with mode: 0755]
mac/libdes/src/podd.h [new file with mode: 0755]
mac/libdes/src/qud_cksm.c [new file with mode: 0755]
mac/libdes/src/rand_key.c [new file with mode: 0755]
mac/libdes/src/read_pwd.c [new file with mode: 0755]
mac/libdes/src/resource.h [new file with mode: 0755]
mac/libdes/src/rnd_keys.c [new file with mode: 0755]
mac/libdes/src/rpc_des.h [new file with mode: 0755]
mac/libdes/src/rpc_enc.c [new file with mode: 0755]
mac/libdes/src/rpw.c [new file with mode: 0755]
mac/libdes/src/set_key.c [new file with mode: 0755]
mac/libdes/src/sha.c [new file with mode: 0755]
mac/libdes/src/sha.h [new file with mode: 0755]
mac/libdes/src/shifts.pl [new file with mode: 0755]
mac/libdes/src/sk.h [new file with mode: 0755]
mac/libdes/src/speed.c [new file with mode: 0755]
mac/libdes/src/spr.h [new file with mode: 0755]
mac/libdes/src/str2key.c [new file with mode: 0755]
mac/libdes/src/supp.c [new file with mode: 0755]
mac/libdes/src/testdes.pl [new file with mode: 0755]
mac/libdes/src/times [new file with mode: 0755]
mac/libdes/src/typemap [new file with mode: 0755]
mac/libdes/src/version.h [new file with mode: 0755]
mac/libdes/src/vms.com [new file with mode: 0755]
mac/libdes/src/xcbc_enc.c [new file with mode: 0755]
mac/libsasl/libsasl [new file with mode: 0755]
mac/libsasl/libsasl.Carbon [new file with mode: 0755]
mac/libsasl/libsasl.Carbon.exp [new file with mode: 0755]
mac/libsasl/libsasl.exp [new file with mode: 0755]
mac/libsasl/libsasl_prefix.h [new file with mode: 0755]
mac/libsasl/libsasl_prefix_carbon.h [new file with mode: 0755]
mac/mac_lib/getopt.c [new file with mode: 0755]
mac/mac_lib/mac_dyn_dlopen.c [new file with mode: 0755]
mac/mac_lib/mac_monolithic_dlopen.c [new file with mode: 0755]
mac/mac_lib/parse_cmd_line.c [new file with mode: 0755]
mac/mac_lib/xxx_client_mac_lib.c [new file with mode: 0755]
mac/mac_lib/xxx_mac_lib.c [new file with mode: 0755]
mac/mac_lib/yyy_mac_lib.c [new file with mode: 0755]
mac/osx_cfm_glue/cfmglue.c [new file with mode: 0755]
mac/osx_cfm_glue/cfmglue.h [new file with mode: 0644]
mac/osx_cfm_glue/cfmglue.proj [new file with mode: 0755]
mac/osx_cfm_glue/cfmglue.proj.exp [new file with mode: 0755]
mac/readme/mac_testing_notes.c [new file with mode: 0755]
mac/sc_shlb/sc_shlb [new file with mode: 0755]
mac/sc_shlb/sc_shlb.Carbon [new file with mode: 0755]
mac/sc_shlb/sc_shlb.mono [new file with mode: 0755]
mac/sc_shlb/sc_shlb.rsrc.sit.hqx [new file with mode: 0644]
mac/sc_shlb/sc_shlb_carbon.h [new file with mode: 0755]
man/Makefile.am [new file with mode: 0644]
man/Makefile.in [new file with mode: 0644]
man/sasl.3 [new file with mode: 0644]
man/sasl_authorize_t.3 [new file with mode: 0644]
man/sasl_auxprop.3 [new file with mode: 0644]
man/sasl_auxprop_getctx.3 [new file with mode: 0644]
man/sasl_auxprop_request.3 [new file with mode: 0644]
man/sasl_callbacks.3 [new file with mode: 0644]
man/sasl_canon_user_t.3 [new file with mode: 0644]
man/sasl_chalprompt_t.3 [new file with mode: 0644]
man/sasl_checkapop.3 [new file with mode: 0644]
man/sasl_checkpass.3 [new file with mode: 0644]
man/sasl_client_init.3 [new file with mode: 0644]
man/sasl_client_new.3 [new file with mode: 0644]
man/sasl_client_start.3 [new file with mode: 0644]
man/sasl_client_step.3 [new file with mode: 0644]
man/sasl_decode.3 [new file with mode: 0644]
man/sasl_dispose.3 [new file with mode: 0644]
man/sasl_done.3 [new file with mode: 0644]
man/sasl_encode.3 [new file with mode: 0644]
man/sasl_encodev.3 [new file with mode: 0644]
man/sasl_errdetail.3 [new file with mode: 0644]
man/sasl_errors.3 [new file with mode: 0644]
man/sasl_errstring.3 [new file with mode: 0644]
man/sasl_getconfpath_t.3 [new file with mode: 0644]
man/sasl_getopt_t.3 [new file with mode: 0644]
man/sasl_getpath_t.3 [new file with mode: 0644]
man/sasl_getprop.3 [new file with mode: 0644]
man/sasl_getrealm_t.3 [new file with mode: 0644]
man/sasl_getsecret_t.3 [new file with mode: 0644]
man/sasl_getsimple_t.3 [new file with mode: 0644]
man/sasl_global_listmech.3 [new file with mode: 0644]
man/sasl_idle.3 [new file with mode: 0644]
man/sasl_listmech.3 [new file with mode: 0644]
man/sasl_log_t.3 [new file with mode: 0644]
man/sasl_server_init.3 [new file with mode: 0644]
man/sasl_server_new.3 [new file with mode: 0644]
man/sasl_server_start.3 [new file with mode: 0644]
man/sasl_server_step.3 [new file with mode: 0644]
man/sasl_server_userdb_checkpass_t.3 [new file with mode: 0644]
man/sasl_server_userdb_setpass_t.3 [new file with mode: 0644]
man/sasl_setpass.3 [new file with mode: 0644]
man/sasl_setprop.3 [new file with mode: 0644]
man/sasl_user_exists.3 [new file with mode: 0644]
man/sasl_verifyfile_t.3 [new file with mode: 0644]
plugins/Makefile.am [new file with mode: 0644]
plugins/Makefile.in [new file with mode: 0644]
plugins/NTMakefile [new file with mode: 0755]
plugins/anonymous.c [new file with mode: 0644]
plugins/anonymous_init.c [new file with mode: 0644]
plugins/cram.c [new file with mode: 0644]
plugins/crammd5_init.c [new file with mode: 0644]
plugins/digestmd5.c [new file with mode: 0644]
plugins/digestmd5_init.c [new file with mode: 0644]
plugins/gssapi.c [new file with mode: 0644]
plugins/gssapiv2_init.c [new file with mode: 0644]
plugins/kerberos4.c [new file with mode: 0644]
plugins/kerberos4_init.c [new file with mode: 0644]
plugins/ldapdb.c [new file with mode: 0644]
plugins/ldapdb_init.c [new file with mode: 0644]
plugins/login.c [new file with mode: 0644]
plugins/login_init.c [new file with mode: 0644]
plugins/makeinit.sh [new file with mode: 0644]
plugins/ntlm.c [new file with mode: 0644]
plugins/ntlm_init.c [new file with mode: 0644]
plugins/otp.c [new file with mode: 0644]
plugins/otp.h [new file with mode: 0644]
plugins/otp_init.c [new file with mode: 0644]
plugins/passdss.c [new file with mode: 0644]
plugins/passdss_init.c [new file with mode: 0644]
plugins/plain.c [new file with mode: 0644]
plugins/plain_init.c [new file with mode: 0644]
plugins/plugin_common.c [new file with mode: 0644]
plugins/plugin_common.h [new file with mode: 0644]
plugins/sasldb.c [new file with mode: 0644]
plugins/sasldb_init.c [new file with mode: 0644]
plugins/sql.c [new file with mode: 0644]
plugins/sql_init.c [new file with mode: 0644]
plugins/srp.c [new file with mode: 0644]
plugins/srp_init.c [new file with mode: 0644]
pwcheck/Makefile.am [new file with mode: 0644]
pwcheck/Makefile.in [new file with mode: 0644]
pwcheck/README [new file with mode: 0644]
pwcheck/pwcheck.c [new file with mode: 0644]
pwcheck/pwcheck_getpwnam.c [new file with mode: 0644]
pwcheck/pwcheck_getspnam.c [new file with mode: 0644]
sample/Makefile.am [new file with mode: 0644]
sample/Makefile.in [new file with mode: 0644]
sample/NTMakefile [new file with mode: 0644]
sample/client.c [new file with mode: 0644]
sample/common.c [new file with mode: 0644]
sample/common.h [new file with mode: 0644]
sample/sample-client.c [new file with mode: 0644]
sample/sample-server.c [new file with mode: 0644]
sample/server.c [new file with mode: 0644]
saslauthd/AUTHORS [new file with mode: 0644]
saslauthd/COPYING [new file with mode: 0644]
saslauthd/ChangeLog [new file with mode: 0644]
saslauthd/INSTALL [new file with mode: 0644]
saslauthd/LDAP_SASLAUTHD [new file with mode: 0644]
saslauthd/Makefile.am [new file with mode: 0644]
saslauthd/Makefile.in [new file with mode: 0644]
saslauthd/NEWS [new file with mode: 0644]
saslauthd/README [new file with mode: 0644]
saslauthd/aclocal.m4 [new file with mode: 0644]
saslauthd/auth_dce.c [new file with mode: 0644]
saslauthd/auth_dce.h [new file with mode: 0644]
saslauthd/auth_getpwent.c [new file with mode: 0644]
saslauthd/auth_getpwent.h [new file with mode: 0644]
saslauthd/auth_httpform.c [new file with mode: 0644]
saslauthd/auth_httpform.h [new file with mode: 0644]
saslauthd/auth_krb4.c [new file with mode: 0644]
saslauthd/auth_krb4.h [new file with mode: 0644]
saslauthd/auth_krb5.c [new file with mode: 0644]
saslauthd/auth_krb5.h [new file with mode: 0644]
saslauthd/auth_ldap.c [new file with mode: 0644]
saslauthd/auth_ldap.h [new file with mode: 0644]
saslauthd/auth_pam.c [new file with mode: 0644]
saslauthd/auth_pam.h [new file with mode: 0644]
saslauthd/auth_rimap.c [new file with mode: 0644]
saslauthd/auth_rimap.h [new file with mode: 0644]
saslauthd/auth_sasldb.c [new file with mode: 0644]
saslauthd/auth_sasldb.h [new file with mode: 0644]
saslauthd/auth_shadow.c [new file with mode: 0644]
saslauthd/auth_shadow.h [new file with mode: 0644]
saslauthd/auth_sia.c [new file with mode: 0644]
saslauthd/auth_sia.h [new file with mode: 0644]
saslauthd/cache.c [new file with mode: 0644]
saslauthd/cache.h [new file with mode: 0644]
saslauthd/cfile.c [new file with mode: 0644]
saslauthd/cfile.h [new file with mode: 0644]
saslauthd/config/config.guess [new file with mode: 0755]
saslauthd/config/config.sub [new file with mode: 0755]
saslauthd/config/depcomp [new file with mode: 0755]
saslauthd/config/install-sh [new file with mode: 0755]
saslauthd/config/ltconfig [new file with mode: 0755]
saslauthd/config/ltmain.sh [new file with mode: 0644]
saslauthd/config/missing [new file with mode: 0755]
saslauthd/config/mkinstalldirs [new file with mode: 0755]
saslauthd/configure [new file with mode: 0755]
saslauthd/configure.in [new file with mode: 0644]
saslauthd/getaddrinfo.c [new file with mode: 0644]
saslauthd/getnameinfo.c [new file with mode: 0644]
saslauthd/globals.h [new file with mode: 0644]
saslauthd/include/gai.h [new file with mode: 0644]
saslauthd/ipc_doors.c [new file with mode: 0644]
saslauthd/ipc_unix.c [new file with mode: 0644]
saslauthd/krbtf.c [new file with mode: 0644]
saslauthd/krbtf.h [new file with mode: 0644]
saslauthd/lak.c [new file with mode: 0644]
saslauthd/lak.h [new file with mode: 0644]
saslauthd/md5.c [new file with mode: 0644]
saslauthd/md5global.h [new file with mode: 0644]
saslauthd/mechanisms.c [new file with mode: 0644]
saslauthd/mechanisms.h [new file with mode: 0644]
saslauthd/saslauthd-main.c [new file with mode: 0644]
saslauthd/saslauthd-main.h [new file with mode: 0644]
saslauthd/saslauthd.8 [new file with mode: 0644]
saslauthd/saslauthd.h.in [new file with mode: 0644]
saslauthd/saslauthd.mdoc [new file with mode: 0644]
saslauthd/saslauthd_md5.h [new file with mode: 0644]
saslauthd/saslcache.c [new file with mode: 0644]
saslauthd/testsaslauthd.c [new file with mode: 0644]
saslauthd/utils.c [new file with mode: 0644]
saslauthd/utils.h [new file with mode: 0644]
sasldb/Makefile.am [new file with mode: 0644]
sasldb/Makefile.in [new file with mode: 0644]
sasldb/NTMakefile [new file with mode: 0644]
sasldb/allockey.c [new file with mode: 0644]
sasldb/db_berkeley.c [new file with mode: 0644]
sasldb/db_gdbm.c [new file with mode: 0644]
sasldb/db_ndbm.c [new file with mode: 0644]
sasldb/db_none.c [new file with mode: 0644]
sasldb/sasldb.h [new file with mode: 0644]
utils/Makefile.am [new file with mode: 0644]
utils/Makefile.in [new file with mode: 0644]
utils/NTMakefile [new file with mode: 0644]
utils/dbconverter-2.c [new file with mode: 0644]
utils/pluginviewer.8 [new file with mode: 0644]
utils/pluginviewer.c [new file with mode: 0644]
utils/sasldblistusers.c [new file with mode: 0644]
utils/sasldblistusers2.8 [new file with mode: 0644]
utils/saslpasswd.c [new file with mode: 0644]
utils/saslpasswd2.8 [new file with mode: 0644]
utils/sfsasl.c [new file with mode: 0644]
utils/sfsasl.h [new file with mode: 0644]
utils/smtptest.c [new file with mode: 0644]
utils/testsuite.c [new file with mode: 0644]
win32/.cvsignore [new file with mode: 0644]
win32/.cvswrappers [new file with mode: 0644]
win32/common.mak [new file with mode: 0644]
win32/include/.cvsignore [new file with mode: 0644]
win32/include/NTMakefile [new file with mode: 0644]
win32/include/config.h [new file with mode: 0644]
win32/include/md5global.h [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..cd07fd7
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,47 @@
+Rob Siemborski <rjs3+@andrew.cmu.edu> wrote and tested the conversion
+to the SASLv2 API.
+
+Ken Murchison <ken@oceana.com> worked on the OTP, NTLM, SRP and SQL
+plugins, as well as helping to track down bugs as they appear.
+
+Rob Earhart <earhart@cmu.edu> wrote the build/installation procedure,
+wrote and tested some of the code, and provided general guidance and
+coding advice.
+
+Leif Johansson <leifj@matematik.su.se> wrote the GSSAPI plugin, with
+contributions from Sam Hartman <hartmans@fundsxpress.com>.
+
+Leandro Santi <lesanti@sinectis.com.ar> added Courier authdaemon support.
+
+Alexey Melnikov <mel@isode.com> wrote the first pass of the
+DIGEST-MD5 plugin and continues to work on it.  He also wrote
+a good deal of the current Windows support.
+
+Rainer Schoepf <schoepf@uni-mainz.de> contributed the LOGIN plugin,
+based on Tim Martin's PLAIN plugin.
+
+Simon Loader <simon@surf.org.uk> wrote the MySQL auxprop module.
+
+Rolf Braun <rbraun@andrew.cmu.edu> wrote the MacOS ports.
+
+Howard Chu <hyc@highlandsun.com> put a good deal of work into OS/390
+portability, correct building of static libraries, and a slew
+of misc. bugfixes.
+
+Tim Martin <tmartin@andrew.cmu.edu> wrote, debugged, and tested
+most of the SASLv1 code.
+
+Larry Greenfield <leg+sasl@andrew.cmu.edu> complained. a lot.
+
+Chris Newman <chris.newman@sun.com> wrote the initial version of the
+SASL API, as well as the version 2 SASL API (documented in sasl.h,
+saslutil.h, saslplug.h, and prop.h).
+
+Ryan Troll <ryan@andrew.cmu.edu> started the Windows port,
+and both Larry Greenfield and Alexey Melnikov have done more work on it.
+
+getaddrinfo.c was written by Hajimu UMEMOTO <ume@mahoroba.org>
+which is based on the IPv6 code written by KIKUCHI Takahiro
+<kick@kyoto.wide.ad.jp>
+
+$Id: AUTHORS,v 1.17 2004/01/08 15:30:25 ken3 Exp $
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..3f56f30
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,44 @@
+/* CMU libsasl
+ * Tim Martin
+ * Rob Earhart
+ * Rob Siemborski
+ */
+/* 
+ * 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.
+ */
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..6fca1bc
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,2753 @@
+2009-04-27  Ken Murchison <murch@andrew.cmu.edu>
+       * Ready for 2.1.23
+
+2009-04-27  Ken Murchison <murch@andrew.cmu.edu>
+       * lib/saslutil.c: Fixed CERT VU#238019 (make sure sasl_encode64()
+         always NUL terminates output or returns SASL_BUFOVER).
+
+2006-05-19  Ken Murchison <murch@andrew.cmu.edu>
+       * Makefile.am: include INSTALL.TXT in distro
+       *** Ready for 2.1.22
+
+2006-05-18  Ken Murchison <murch@andrew.cmu.edu>
+       * cmulocal/sasl2.m4: patch to compile with MIT krb5 1.4.3
+         (Philip Guenther <guenther@sendmail.com>)
+
+2006-05-18  Alexey Melnikov <alexey.melnikov@isode.com>
+       * configure.in: Fixed default value in help for the
+         --with-authdaemond command line option (Philip Guenther).
+
+2006-05-17  Alexey Melnikov <alexey.melnikov@isode.com>
+       * NEWS: Ready for 2.1.22
+
+2006-05-17  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/Makefile.am: enable pluginviewer in the default build.
+
+2006-04-26  Ken Murchison <murch@andrew.cmu.edu>
+       * lib/server.c: call do_authorization() after successful APOP
+
+2006-04-26  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/digestmd5.c: If neither DES nor RC4 cipher is selected,
+         advertise maxssf of 1 (integrity protection).
+
+2006-04-26  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/pluginviewer.c: Must set fully qualified domain name
+         in sasl_client_new, or some plugins will not be shown.
+
+2006-04-26  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/client.c: Replaced wrong "break" statement with
+         "continue" in the client side list function.
+
+2006-04-25  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/NTMakefile: Enable RC4 cipher in Windows build.
+
+2006-04-25  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/digestmd5.c: Make sure that SASL packets
+         shorter than 16 bytes don't cause buffer overrun.
+         Also prevent an error report from BoundsChecker
+         regarding pointer being out of range.
+
+2006-04-25  Alexey Melnikov <alexey.melnikov@isode.com>
+       * win32/common.mak: Fixed bug of not setting CODEGEN
+         (code generation option) if STATIC is set.
+
+2006-04-24  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/passdss.c, plugins/srp.c: Added include files required
+         by OpenSSL 0.9.8 (original patch by Dan Nicholson).
+
+2006-04-24  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/NTMakefile: testsuite.exe doesn't depend on saslSASLDB.dll.
+
+2006-04-24  Alexey Melnikov <alexey.melnikov@isode.com>
+       * doc/windows.html: Updated Windows build instructions.
+
+2006-04-20  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/testsuite.c: Removed sasl_encode test which is no longer
+         valid due to changed in sasl_encodev.
+         Also properly terminated all property request lists with NULL.
+
+2006-04-19  Ken Murchison <murch@andrew.cmu.edu>
+       * saslauthd/auth_shadow.c, saslauthd/configure.in: Check for 4/5
+       argument versions of getXXname_r().
+
+2006-04-19  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/common.c: Andrey V. Malyshev pointed out that the SASL
+         context is always NULL when the default logging callback
+         _sasl_syslog is called. In particular this means that
+         the log_level configuration option is always ignored.
+
+2006-04-19  Alexey Melnikov <alexey.melnikov@isode.com>
+       * configure.in: Search for application configuration
+         files in /usr/lib/sasl2 by default and fall back to
+         /etc/sasl2 if not found.
+
+2006-04-19  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/digestmd5.c: Handle missing realm option from
+         the client as the empty string. This match the behavior
+         prescribed in RFC 2831.
+
+2006-04-19  Alexey Melnikov <alexey.melnikov@isode.com>
+       * saslauthd/Makefile.am: Enable testsaslauthd build
+         by default.
+
+2006-04-18  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/saslint.h, lib/common.c: Added support for spliting
+         big data blocks (bigger than maxbuf) into multiple SASL
+         packets in sasl_encodev.
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/Makefile.am: Added the pluginviewer man page.
+         Reordered link dependencies for saslpasswds/sasldblistusers2.
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/pluginviewer.8: Added man page for pluginviewer.
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/pluginviewer.c: Deleted unused command line parameters
+         and cleaned up usage output.
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/gai.h: Use HAVE_GETADDRINFO (instead of HAVE_GETNAMEINFO)
+         to protect definition of getaddrinfo().
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/sasl.h: Allocated some GSSAPI specific properties
+         for Nico Williams (Sun)
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/common.c: Free default_plugin_path and
+         default_conf_path variables in sasl_done.
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * sasldb/allockey.c: Cleaned up some warnings
+
+2006-04-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * win32/include/config.h: Deleted a misleading comment
+
+2006-04-06 Jeffrey Teaton <jeaton@cmu.edu>
+       * saslauthd/auth_rimap.c: patch from Dale Sedivec to prevent
+         segfault when saslauth free()s returned string
+       * plugins/sql.c: patch from Matthew Hardin to do better
+         error checking for mysql_real_query
+
+2006-04-03  Alexey Melnikov <alexey.melnikov@isode.com>
+       * configure.in, plugins/NTMakefile, plugins/sasldb.c,
+         sasldb/db_berkeley.c, sasldb/sasldb.h:
+         Patch to keep BerkleyDB handle open between operations
+         (for performance reason). New behavior can be enabled
+         with --enable-keep-db-open. Original patch by Curtis King.
+
+2006-03-14  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/server.c: Fixed bug # 2796: load_config now
+         looks in all directories for the config file,
+         not just in the first one.
+
+2006-03-14  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/saslplug.h, lib/auxprop.c, lib/client.c
+         lib/server.c, utils/Makefile.am, utils/NTMakefile,
+         utils/pluginviewer.c [new]:
+         Added support for reporting information about
+         loaded auxprop plugins. Changed the first parameter
+         to sasl_server_plugin_info/sasl_client_plugin_info
+         to be "const char *". Added new utility for
+         reporting information about client and server side
+         authentication plugins and auxprop plugins (e.g.
+         supported features, methods, etc.).
+
+2006-03-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * saslauthd/Makefile.am, saslauthd/auth_httpform.c,
+         saslauthd/auth_httpform.h, saslauthd/configure.in,
+         saslauthd/mechanisms.c, saslauthd/mechanisms.h:
+         Added support for HTTP POST password validation
+         in saslauthd (patch by Joe Ammann <joe@pyx.ch>)
+
+2006-03-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * cmulocal/openldap.m4: Allow for compilation
+         with OpenLDAP 2.3+.
+
+2006-03-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/saslutil.c, utils/testsuite.c: Various
+         fixes to sasl_decode64: don't ignore partial
+         base64 data, don't allow any data after the '='
+         sign, etc.).
+
+2006-03-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/saslint.h: Increase canonicalization buffer
+         size to 1024 bytes, as Luke Howard has reported
+         that 256 is too small for some certificates.
+
+2006-03-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/NTMakefile: Include Cyrus version of
+         getnameinfo() when compiling with Visual Studio 6,
+         as Windows SDK emulation is not available.
+
+2006-02-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/sasl.h, lib/common.c: Added sasl_set_path
+         function (for a more convenient way of setting
+         plugin and config paths. Changed the default
+         sasl_getpath_t/sasl_getconfpath_t callbacks to
+         calculate the value only once and cache it
+         for later use.
+
+2006-02-13  Alexey Melnikov <alexey.melnikov@isode.com>
+       * configure.in, include/sasl.h, lib/common.c,
+         lib/saslinit.h, lib/server.c, man/Makefile.am,
+         man/sasl_callbacks.3, man/sasl_getconfpath_t.3,
+         win32/include/config.h: Added a new sasl_getconf_t
+         callback for specifying where SASL configuration files
+         can be found. Based on patch from Artur Frysiak
+         <wiget@pld.org.pl> for SASL v1, updated by Gentoo
+         folks for SASL v2 and further modified by
+         Andreas Hasenack <andreas@conectiva.com.br>.
+
+2006-01-31  Alexey Melnikov <alexey.melnikov@isode.com>
+       * INSTALL, INSTALL.TXT: Renamed INSTALL to INSTALL.TXT
+         as the former conflicts with Windows "install" target
+         (and Windows file names are case-insensitive).
+
+2005-08-11  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/sasldb.c: Return SASL_NOUSER only if all calls to
+         _sasldb_putdata() return SASL_NOUSER. This prevents spurious
+         SASL_NOUSER errors.
+
+2005-07-07  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/ntlm.c: Added <openssl/md5.h> include in order to fix
+         building with OpenSSL 0.9.8.
+
+2005-05-19  Derrick Brashear <shadow@andrew.cmu.edu>    
+       * config/libtool.m4: do proper quoting, from Andreas Winkelmann
+       * configure.in: clean up enable switches, from Patrick Welche
+       * config/sasldb.m4: fix macro names, from Andreas Winkelmann
+       * lib/client.c: deal with gcc4 strictness, from Steven Simon
+       
+2005-05-16  Derrick Brashear <shadow@andrew.cmu.edu>   
+       * configure.in, include/sasl.h, lib/Makefile.am,
+         plugins/Makefile.am, saslauthd/configure.in, sasldb/Makefile.am,
+         win32/common.mak, win32/include/config.h: 2.1.21
+       * Makefile.am: fix dist-hook to run makeinit.sh in plugins/
+
+2005-05-15  Derrick Brashear <shadow@andrew.cmu.edu>  
+       * saslauthd/lak.c: leak fix from Igor Brezac
+       
+2005-05-15  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/NTMakefile: ldapdb on Windows might depend on OpenSSL.
+
+2005-05-06  Derrick Brashear <shadow@andrew.cmu.edu> 
+       * configure.in, saslauthd/auth_pam.c: detect pam header location also
+         where MacOS provides it, and use it there
+       * utils/Makefile.am: change link order for MacOS
+       * configure.in: provide option to disable installing MacOS SASL2 
+         framework
+       * configure.in, config/kerberos_v4.m4, config/plain.m4,
+         config/sasldb.m4, lib/Makefile.am, sasldb/Makefile.am,
+         (cmulocal/sasl2.m4): fix case where we are building 
+         --enable-static --with-dblib=none causing automake's dependancy
+         stuff to screw us when we try to build files with .. in their path
+       
+2005-04-11  Derrick Brashear <shadow@andrew.cmu.edu>
+       * configure.in, plugins/digestmd5.c: detect and include des.h if it 
+         exists, otherwise assume we don't need it (Solaris 9)
+
+2005-04-11  Derrick Brashear <shadow@andrew.cmu.edu>
+       * sasldb/Makefile.am, config/sasldb.m4: work around HP-UX make's
+         inability to have pipes in $(shell ...) by setting 
+         LOCAL_SASL_DB_BACKEND_STATIC at the same time as
+         SASL_DB_BACKEND_STATIC.
+       
+2005-03-15  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/dlopen.c: log the reason for opendir() failure
+         when loading plugin.
+
+2005-03-08  Alexey Melnikov <alexey.melnikov@isode.com>
+       * man/sasl_auxprop.3, man/sasl_auxprop_getctx.3,
+         man/sasl_auxprop_request.3, man/sasl_canon_user_t.3,
+         man/sasl_client_init.3, man/sasl_client_new.3,
+         man/sasl_client_start.3, man/sasl_client_step.3,
+         man/sasl_decode.3, man/sasl_errdetail.3, man/sasl_errstring.3,
+         man/sasl_getpath_t.3, man/sasl_getrealm_t.3,
+         man/sasl_getsecret_t.3, man/sasl_server_init.3,
+         man/sasl_server_new.3, man/sasl_server_start.3,
+         man/sasl_server_step.3, man/sasl_setpass.3,
+         man/sasl_user_exists.3, man/sasl_verifyfile_t.3: multiple
+         spelling corrections from Steven Simon <steven_si@sbcglobal.net>.
+
+2005-03-07  Alexey Melnikov <alexey.melnikov@isode.com>
+       * utils/saslpasswd2.8, utils/sasldblistusers2.8: updated manpages.
+
+2005-03-01  Derrick Brashear <shadow@andrew.cmu.edu>  
+       * lib/common.c: honor log level setting
+       
+2005-02-28  Derrick Brashear <shadow@andrew.cmu.edu>   
+       * README.ldapdb: ldapdb license info
+       
+2005-02-25  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/sasl.h, lib/common.c: Added SASL_VERSION_FULL
+         define
+
+2005-02-22  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/NTMakefile, win32/common.mak: Windows build of the ldapdb
+         auxprop plugin
+
+2005-02-16  Derrick Brashear <shadow@andrew.cmu.edu> 
+       * configure.in, doc/install.html, doc/options.html, doc/readme.html,
+         doc/sysadmin.html, lib/staticopen.h, plugins/Makefile.am,
+         plugins/ldapdb.c, plugins/makeinit.sh: pull in ldapdb auxprop
+         plugin, from Igor Brezac (Howard Chu's plugin)
+
+2005-02-14  Derrick Brashear <shadow@andrew.cmu.edu>
+       * saslauthd/krbtf.c: updated from CMUCS
+       * saslauthd/auth_krb5.c: log the krb5 error return if get_creds fails 
+       
+2005-02-01  Alexey Melnikov <alexey.melnikov@isode.com>
+       * win32/include/config.h: Updated to match gai.h changes.
+       * win32/include/config.h: added define for the OTP plugin.
+
+2005-01-27  Derrick Brashear <shadow@andrew.cmu.edu>
+       * configure.in, include/gai.h: move AI_NUMERICHOSTS definitions
+         to config.h because gai.h is not always included.
+
+2005-01-10  Derrick Brashear <shadow@andrew.cmu.edu>
+       * saslauthd/auth_krb5.c, saslauthd/auth_krb4.c,
+         saslauthd/krbtf.h (added), saslauthd/krbtf.c (added),
+         saslauthd/cfile.h (added), saslauthd/cfile.c (added),
+         saslauthd/Makefile.am: Kerberos V4/V5 alternate keytab
+         in saslauthd, plus common code merging (from David Eckhardt
+         via Dale Moore)
+
+2004-12-08  Alexey Melnikov <alexey.melnikov@isode.com>
+       * doc/windows.html: Updated as per recent build changes.
+       * plugins/ntlm.c: Fixed NTLM build on Windows,
+         as compiler was complaining about array size not being
+         a const.
+       * lib/NTMakefile, plugins/NTMakefile, win32/common.mak,
+         win32/include/config.h: Use native IPv6 support on Windows,
+         falling back to Microsoft emulation. Cleaner support
+         for Visual Studio 6.
+
+2004-11-24  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: squashed unused parameter warnings
+
+2004-11-24  Ken Murchison <ken@oceana.com>
+       * plugins/passdss.c: added; PASSDSS-3DES-1 implementation
+       * configure.in, plugins/Makefile.am, plugins/makeinit.sh:
+         added support for PASSDSS
+       * doc/draft-newman-sasl-passdss-xx.txt: added
+       * doc/index.html, doc/Makefile.am: added PASSDSS draft
+
+2004-11-19  Derrick Brashear <shadow@andrew.cmu.edu>
+       * saslauthd/auth_krb5.c: verify against the service we
+         were passed. needs to be made configurable.
+
+2004-11-10  Alexey Melnikov <alexey.melnikov@isode.com>
+       * doc/draft-burdis-cat-srp-sasl-08.txt: deleted
+       * doc/draft-ietf-sasl-anon-02.txt: deleted
+       * doc/draft-ietf-sasl-crammd5-01.txt: deleted
+       * doc/draft-ietf-sasl-gssapi-00.txt: deleted
+       * doc/draft-ietf-sasl-plain-03.txt: deleted
+       * doc/draft-ietf-sasl-rfc2222bis-03.txt: deleted
+       * doc/draft-ietf-sasl-rfc2831bis-02.txt: deleted
+       * doc/draft-ietf-sasl-saslprep-04.txt: deleted
+       * doc/draft-newman-sasl-c-api-01.txt: deleted
+       * doc/draft-burdis-cat-srp-sasl-xx.txt: added
+       * doc/draft-ietf-sasl-anon-xx.txt: added
+       * doc/draft-ietf-sasl-crammd5-xx.txt: added
+       * doc/draft-ietf-sasl-gssapi-xx.txt: added
+       * doc/draft-ietf-sasl-plain-xx.txt: added
+       * doc/draft-ietf-sasl-rfc2222bis-xx.txt: added
+       * doc/draft-ietf-sasl-rfc2831bis-xx.txt: added
+       * doc/draft-ietf-sasl-saslprep-xx.txt: added
+       * doc/draft-newman-sasl-c-api-xx.txt: added
+       * doc/index.html, doc/Makefile.am: Renamed the files
+
+2004-11-02  Alexey Melnikov <alexey.melnikov@isode.com>
+       * include/saslplug.h, lib/common.c, lib/saslint.h,
+         lib/client.c: Added sasl_client_plugin_info().
+
+2004-10-26  Alexey Melnikov <alexey.melnikov@isode.com>
+       * sample/sample-client.c, sample/sample-server.c: Fixed several
+         64 bit portability warnings.
+       * utils/testsuite.c: Fixed several 64 bit portability warnings.
+       * utils/saslpasswd.c: Fixed typo in an auxprop name.
+       * include/saslplug.h, lib/common.c, lib/saslint.h,
+         lib/server.c: Added sasl_server_plugin_info().
+
+2004-10-24  Derrick Brashear <shadow@andrew.cmu.edu> 
+       * lib/common.c: initialize path in case caller didn't.
+
+2004-10-24  Derrick Brashear <shadow@andrew.cmu.edu> 
+       * Prep for 2.1.20
+
+2004-10-19  Derrick Brashear <shadow@dementia.org>
+       * Makefile.am, saslauthd/Makefile.am: require automake 1.7;
+         prior versions require AM_CONFIG_HEADER and dislike AM_LDFLAGS
+
+2004-10-14  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: portability fixes from Alexey, and squashed a
+         signed/unsigned warning
+
+2004-10-14  Alexey Melnikov <alexey.melnikov@isode.com>
+       * lib/NTMakefile: Don't install intermediate file libsasl.res
+
+2004-09-22  Derrick Brashear <shadow@andrew.cmu.edu>
+       * lib/common.c: don't honor SASL_PATH in setuid environment. 
+         from Gentoo
+       
+2004-09-08  Alexey Melnikov <alexey.melnikov@isode.com>
+       * plugins/cram.c, plugins/anonymous.c, plugins/login.c,
+         plugins/plain.c, plugins/sasldb.c: Fixed several 64 bit
+         portability warnings
+
+2004-09-02  Derrick Brashear <shadow@andrew.cmu.edu>
+       * plugins/kerberosv4.c: simple explanation in the code of one 
+         possible error you might see in strange circumstances; 
+         i should probably make openssl's des unable to be used if
+         mit krb5 is being used.
+
+2004-08-06  Derrick Brashear <shadow@andrew.cmu.edu>
+       * plugins/cram.c: initialize authid to null so stack garbage 
+         is not pushed into _sasl_canon_user
+       
+2004-07-29  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Fix handling of client realm callback
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-07-21  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: Memory management cleanup
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-07-15  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in, plugins/gssapi.c: Wrap all GSS calls
+         in mutexes when required by the implementation.
+         (based on a patch by Simon Wilkinson <simon@sxw.org.uk>)
+
+2004-07-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Fix potential buffer overflow, call
+         add_to_challenge in 2 more places (Alexey Melnikov
+         <Alexey.Melnikov@isode.com>)
+       * lib/server.c, lib/saslint.h, lib/common.c: don't directly
+         store buffers in the params structure
+       * plugins/gssapi.c: Fix server side maxoutbuf calculation
+         (Sam Hartman <hartmans@mit.edu>)
+       * plugins/gssapi.c: Use gss_wrap_size_limit on client side too
+       * Ready for 2.1.19
+
+2004-07-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Prep for 2.1.19
+
+2004-06-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_rimap.c: Fix Tru64 compilation problem
+       * plugins/sql.c: Don't leak settings variable if init fails
+       * utils/testsuite.c: Update for current library
+       * plugins/digestmd5.c: Quoting fixes for client side
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-06-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: Minor bugfixes, support %R token
+         (Igor Brezac <igor@ypass.net>)
+       * plugins/otp.c: Use plugin supplied authid for mech calculations
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * lib/auxprop.c: Use getopt callback from connection context when
+         storing auxprops (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/otp.c, plugins/srp.c, plugins/plugin_common.c: Use correct
+         form of userid (user@realm) when running setpass methods
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * saslauthd/configure.in: Handle LTLIBOBJS
+
+2004-06-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/NTMakefile: Remove only recognized (generated) .rc files,
+         not just *.rc. This will allow for plugins with own resource files.
+         Also corrected spelling mistake in OPENSSL (Alexey Melnikov
+         <Alexey.Melnikov@isode.com>)
+       * lib/server.c, include/sasl.h: Support for SASL_SET_CURMECH_ONLY
+         flag to sasl_setpass() (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-06-16  Ken Murchison <ken@oceana.com>
+       * lib/server.c: use more accurate errors codes for mech_permitted()
+
+2004-06-16  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: don't used the parsed authid for calculations
+         (Alexey Melnikov <alexey.melnikov@isode.com>)
+
+2004-06-16  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Support for forwarding of GSSAPI credentials
+         (Morten Olsen <mso@medical-insight.com & 
+          Alexey Melnikov <alexey.melnikov@isode.com>)
+
+2004-06-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * win32/config.mak: Remove unneeded libraries
+         (Alexey Melnikov <alexey.melnikov@isode.com>)
+
+2004-06-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Spelling Fixes (selsky@columbia.edu)
+
+2004-05-27  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * SQLite support (Norikatsu Shigemura <nork@ninth-nine.com>)
+       * SQLite support on windows (Alexey Melnikov
+         <Alexey.Melnikov@isode.com>)
+
+2004-05-25  Ken Murchison <ken@oceana.com>
+       * plugins/digest-md5.c: use separate global contexts for client/server
+
+2004-05-21  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in, lib/Makefile.am: Better handling of -ldoor library
+         addition (only add it to base library, don't add -lpthread)
+       * saslauthd/auth_krb5.c: zero out the krb5_data structure
+         before use
+
+2004-05-20  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * include/sasl.h, lib/common.c, lib/saslint.h, lib/server.c:
+         Add SASL_APPNAME to sasl_getprop/sasl_setprop for further
+         compatibilty with SASL C API draft
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-05-18  Ken Murchison <ken@oceana.com>
+       * plugins/digest-md5.c: made the global context a struct
+         containing the reauth_cache so we can NULL it after we free it
+
+2004-05-07  Ken Murchison <ken@oceana.com>
+       * contrib/stripplus_canonuser.patch: added
+
+2004-04-27  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_shadow.c: Make thread-safe
+         (Steve Barber <steveb@cme.nist.gov>)
+
+2004-04-26  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_krb5.c: Alternate realm support for Kerberos 5
+
+2004-04-16  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: Mac OS X fix
+         (Chris Ridd <chris.ridd@isode.com>)
+
+2004-04-14  Ken Murchison <ken@oceana.com>
+       * plugins/plain.c: don't include authzid in response unless
+         specified by client
+
+2004-03-29  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * sample/server.c: Ensure that len has a value
+
+2004-03-25  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/saslauthd-main.c: add -r option to saslauthd for combining
+         user and realm into user@realm (for the userid).  Based on a patch
+         by Jeremy Rumpf <jrumpf@heavyload.net>.
+
+2004-03-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/checkpw.c: Include errno.h when HAVE_AUTHDAEMON is defined
+       * doc/windows.html: Updates (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-03-16  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in: Properly use CMU_ADD_LIBPATH_TO for pgsql and mysql
+
+2004-03-10  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/dlopen.c: HPUX 11 Fix (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * Add sasl_version_info() (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * Add a bunch of NTMakefile files to EXTRA_DIST in Makefile.am's
+       * Ready for 2.1.18
+
+2004-03-08  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * NI_WITHSCOPEID fixes (Hajimu UMEMOTO <ume@mahoroba.org>) - correct
+         Solaris 9 IPLOCALPORT/IPREMOTEPORT issue
+
+2004-02-24  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * acinclude.m4: move to config/libtool.m4
+       * saslauthd/lak.[ch]: Added filter based group membership check
+         (Paul Bender <pbender@qualcomm.com>, Igor Brezac <igor@ipass.net>)
+
+2004-02-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/NTMakefile: Enable DO_SRP_SETPASS on windows
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * doc/windows.html: Updates
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * win32/: Add version resource info to plugins
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/digestmd5.c: Comments and other cleanup
+
+2004-02-20  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/server.c, include/saslplug.h: Allow "temporary failure"
+         return values from mech_avail
+       * lib/canonusr.c, lib/server.c: Comment Nits
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/NTMakefile, plugins/plugin_common.h, 
+         plugins/plugin_common.c, plugins/otp.c: build OTP on Windows
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-02-19  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c, sample/server.c, sample/client.c:
+         error checking of getnameinfo() (Paul Kranenburg <pk@cs.few.eur.nl>)
+       * plugins/ntlm.c: alignment and endian fixes in load_session_setup()
+         (Paul Kranenburg <pk@cs.few.eur.nl>)
+
+2004-02-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/NTMakefile, NTMakefile: nmake install support
+         for doc/ (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/digestmd5.c: Check that digest-uri is only sent once
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * utils/Makefile.am: add LIB_PGSQL to static link line
+
+2004-02-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * win32/include/config.h: caddr_t might be already defined
+         elsewhere (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+        * lib/NTMakefile, include/saslutil.h:  getopt might be already
+         defined elsewhere. The change will produce libsasl.dll which exports
+         getopt, buat a define can be used to prevent import of getopt from
+         libsasl.dll. (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-02-16  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in: Remove deprecated AC_PROG_RANLIB, CMU_PROG_LIBTOOL
+         (Patrick Welche <prlw1@newn.cam.ac.uk>)
+       * lib/dlopen.c: OpenBSD ELF patch (J.C. Roberts)
+
+2004-02-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/NTMakefile, utils/NTMakefile: fix "clean" target
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * General winsock.h -> winsock2.h conversion
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/plugin_common.h: add extern "C" wrapper
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-01-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Remove "experimental" designation from saslauthd/ldap
+       * Correct handling of sasl_setpass errors when no
+         mechanisms implement the setpass interface
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2004-01-20  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in: minor sql nit (Edward Rudd <eddie@omegaware.com>)
+       * lib/staticopen.h: MYSQL should be SQL
+         (Edward Rudd <eddie@omegaware.com>)
+
+2004-01-12  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * win32/include/config.h: fix VC++ 6.0 compiles
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * configure.in: Correct use of AC_LIBOBJ, quote macro names
+         defined by AC_DEFUN, Use enable_shared to determine whether
+         to enable the shared plugin.
+         (Maciej W. Rozycki <macro@ds2.pg.gda.pl>)
+       * plugins/srp.c: Fix typos
+         (Maciej W. Rozycki <macro@ds2.pg.gda.pl>)
+       * saslauthd/configure.in: Correct use of AC_LIBOBJ
+         (Maciej W. Rozycki <macro@ds2.pg.gda.pl>)
+
+2004-01-08  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: better error logging
+
+2004-01-07  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/checkpw.c & others: Support for Courier-IMAP authdaemond
+         use during password verification (Leandro Santi
+         <lesanti@uolsinectis.com.ar>)
+
+2003-12-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: Fix NULL pointer dereference
+         (Simon Brady <simon.brady@otago.ac.nz>)
+       * saslauthd/lak.c, lak.h, LDAP_SASLAUTHD: Improved retry handler,
+         Improved logging/debug messages, Fixed String checks, config
+         option changes (Igor Brezac <igor@ipass.net>)
+
+2003-12-22  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Fix memory leak
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-12-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/plugin_common.c: Fix handling of blob unwrapping
+         in _plug_decode
+       * lib/checkpw.c: Fix some file descriptor leaks during failures
+         in the saslauthd code.
+
+2003-12-15  Rob Siemborksi <rjs3@andrew.cmu.edu>
+       * utils/saslauthd.c: Fix Typo
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/plugin_common.c: Fix potential memory leak
+       * lib/external.c: Limit size of authzids in EXTERNAL
+       * plugins/gssapi.c: Pre-init some variables
+       * lib/cram.c: Detect possible buffer overrun
+       * lib/checkpw.c: Post-fence bug
+         (Leandro Santi <lesanti@uolsinectis.com.ar>)
+
+2003-12-12  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: assign null to free
+         variables (Juan Felipe Garcia <fgc@usal.es>)
+       * saslauthd/lak.c: Improve retry when ldap connection is reset
+         (1st pass) (Igor Brezac <igor@ipass.net>)
+
+2003-12-11  Rolf Braun <rbraun@andrew.cmu.edu>
+       * Several MacOS X Fixes
+
+2003-12-06  Ken Murchison <ken@oceana.com>
+       * lib/checkpw.c, lib/server.c,
+         plugins/cram.c, plugins/digestmd5.c, plugins/ntlm.c,
+         plugins/otp.c, plugins/srp.c: erase the plaintext password
+         property from the context when we're done with it
+
+2003-12-01  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-crammd5-01.txt: added
+       * doc/draft-ietf-sasl-gssapi-00.txt: added
+       * doc/draft-ietf-sasl-plain-03.txt: added
+       * doc/draft-ietf-sasl-rfc2222bis-03.txt: added
+       * doc/draft-ietf-sasl-saslprep-04.txt: added
+       * doc/draft-ietf-sasl-crammd5-00.txt: deleted
+       * doc/draft-ietf-cat-sasl-gssapi-05.txt: deleted
+       * doc/draft-ietf-sasl-plain-02.txt: deleted
+       * doc/draft-ietf-sasl-rfc2222bis-02.txt: deleted
+       * doc/draft-ietf-sasl-saslprep-03.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest version of
+         SASL drafts
+
+2003-12-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Fix build nit in IRIX.
+       * Actual 2.1.17 release.
+
+2003-11-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.17
+
+2003-11-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/kerberos_v4.m4: Disable KERBEROS_V4 support by default
+
+2003-11-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/server.c: do authorization callback in sasl_checkpass()
+         (Chris Newman <chris.newman@sun.com>)
+
+2003-11-11  Ken Murchison <ken@oceana.com>
+       * lib/client.c: allow serverFDQN to be NULL in sasl_client_new()
+       * plugins/digestmd5.c, gssapi.c: require that we have serverFQDN
+         for the client side of the plugin
+
+2003-11-07  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * --with-gss_impl configure option
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-11-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * nmake install support for Win32
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-11-03  Ken Murchison <ken@oceana.com>
+       * include/saslplug.h, lib/server.c, plugins/cram.c,
+         plugins/digestmd5.c, plugins/ntlm.c, plugins/otp.c,
+         plugins/srp.c: return SASL_TRANS to the application where
+         appropriate (auto_transition enabled with writable auxprop)
+
+2003-10-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: OpenLDAP 2.0 Compatability Fix
+         (Igor Brezac <igor@ypass.net>)
+       * saslauthd/ipc_unix.c: Fix buglet of not using saved errno
+         value (Jeremy Rumpf <jrumpf@heavyload.net>)
+
+2003-10-20  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Win64 warning squashing (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * GSSAPI cleanups and fixes (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-10-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.16-BETA
+
+2003-10-08  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Support for autoconf 2.57, automake 1.7
+       * Minor m4 quoting fixes (Patrick Welche <prlw1@cam.ac.uk>)
+
+2003-10-07  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: removed sql_delete - don't DELETE rows from the
+         table, just set the properties to NULL;
+         fix a stupid logic error in my PgSQL changes
+       * doc/options.html: removed sql_delete option; clarifications
+       * doc/install.html: note that we require PostgreSQL v7.2+
+
+2003-10-06  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: use the correct propctx in sql_auxprop_store()
+
+2003-10-06  Maya Nigrosh <mnigrosh@andrew.cmu.edu>
+       * plugins/sql.c: tiny bugfix to begin pgsql transactions
+       
+2003-10-04  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: only do a txn when we have a property to fetch;
+         _pgsql_open() cleanup/fixes; more intelligient sql_usessl parsing;
+         require sql_select option
+       * doc/options.html: reorganized SQL option descriptions
+
+2003-10-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * sasldb/allockey.c, sasldb/sasldb.h, utils/sasldblistusers.c:
+         Add enumeration capability to the sasldb API
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-10-02  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: changed abstraction layer for transactions
+
+2003-10-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/: Documentation Update
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/NTMakefile, plugins/srp.c: Win32 SRP Support
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Clean up some warnings
+       * lib/canonusr.c, win32/include/config.h, win32/common.mak,
+         include/saslplug.h: Minor Cleanup
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * utils/NTMakefile, utils/sasldblistusers.c, utils/saslpasswd.c:
+         Add version options to command line utilities
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-29  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c, doc/options.html: added sql_update and sql_delete
+         for a complete auxprop_store() implementation; logic cleanup
+
+2003-09-25  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * utils/saslpasswd.c: Win32 perror() related patch
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-25  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: renamed sql_statement to sql_select,
+         cleanup and bugfixes
+
+2003-09-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/gssapi.html: Misc updates
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * lib/Makefile.am, plugins/Makefile.am, saslauthd/Makefile.am,
+         sasldb/Makefile.am: Cleanup INCLUDES for different build
+         directories. (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-23  Maya Nigrosh <mnigrosh@andrew.cmu.edu>
+       * plugins/sql.c: put transaction handling around the entirety of 
+         the queries, and not just per-property; return the result status
+         of bad postgres tuples
+
+2003-09-22  Maya Nigrosh <mnigrosh@andrew.cmu.edu>
+       * plugins/sql.c: added semicolon at the end of each sql statement
+       
+2003-09-19  Maya Nigrosh <mnigrosh@andrew.cmu.edu>
+       * plugins/sql.c: moved transaction handling to a more useful place,
+         minor bugfixes
+
+2003-09-18  Ken Murchison <ken@oceana.com>
+       * lib/server.c: log a message when no password change is attempted
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-17  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c: misc fixes from Patrick Welche <prlw1@newn.cam.ac.uk>
+       
+2003-09-16  Ken Murchison <ken@oceana.com>
+       * doc/mechanisms.html: updated to latest versions of LOGIN and
+         SRP drafts
+
+2003-09-15  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-rfc2222bis-02.txt: added
+       * doc/draft-ietf-sasl-rfc2222bis-01.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest version of
+         SASL draft
+
+2003-09-14  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c, plugins/plugin_common.[ch]: Win32 support
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-12  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/sql.c: Log errors on connect failures
+         (based on patch from Bruce M Simpson <bms@spc.org>)
+       * plugins/NTMakefile: Add support for GSSAPI=CyberSafe
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-10  Maya Nigrosh <mnigrosh@andrew.cmu.edu>
+       * plugins/sql.c: created generic sql store function, added 
+         transaction handling to sql statements
+       * doc/options.html: put pretty new options in the documentation
+       
+2003-09-10  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c, win32/config.mak, sample/: Win32 Fixes
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/NTMakefile: Minor nit
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-09  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: use retry_read() instead of just read()
+       * lib/checkpw.c, plugins/ntlm.c, saslauthd/utils.c:
+         squash signed/unsigned warning
+
+2003-09-08  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: fix byte-alignment and password handling problems
+
+2003-09-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/checkpw.c: Check return value of door_call
+         (Gary Mills <mills@cc.umanitoba.ca>)
+       * saslauthd/ipc_doors.c: Implement thread limiting,
+         minor cleanup and error checking
+         (Gary Mills <mills@cc.umanitoba.ca>)
+       * plugins/digestmd5.c: Fix minor interop issues, limit maxbuf
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-09-02  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c, doc/options.html: added support for NTLMv2 responses;
+         fixed potential buffer overflow
+
+2003-09-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/common.c, lib/server.c, lib/NTMakefile, include/md5.h:
+         more windows compatibility
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * plugins/NTMakefile: Add ability to build NTLM plugin under
+         Win32 (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * utils/NTMakefile: Add ability to build testsuite
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * saslauthd/lak.c: Minor error message fix
+         (Igor Brezac <igor@ypass.net>)
+
+2003-08-29  Ken Murchison <ken@oceana.com>
+       * doc/draft-murchison-sasl-login-00.txt: added
+       * doc/draft-sasl-login.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to "official" LOGIN draft
+
+2003-08-29  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: properly compute GSSAPI MAXOUTBUF
+         (Paul Turgyan <pturgyan@umich.edu>)
+       * Further Win32 cleanup + HIER_DELIMITER usage
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+
+2003-08-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * include/md5.h, lib/md5.c: Misc cleanup
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * utils/sasldblistusers.c: UI Cleanup, Win32 support
+         (Alexey Melnikov <Alexey.Melnikov@isode.com>)
+       * acconfig.h: add HIER_DELIMITER
+
+2003-08-27  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: handle OpenSSL 0.9.7+ w/o old DES support
+
+2003-08-26  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: only send one NT/LM response to server
+         (NT preferred); don't use canonified authid when proxying
+
+2003-08-24  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c, doc/options.html: allow NTLM authentication to
+         be optionally proxied to an NT server (ntlm_server option)
+
+2003-08-24  Ken Murchison <ken@oceana.com>
+       * lib/common.c: added support for unsigned int types in _sasl_log()
+
+2003-08-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Improvements in Win32 build system from Alexey Melnikov
+         <Alexey.Melnikov@isode.com>
+
+2003-08-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/*: Massive documentation updates.
+
+2003-08-13  Ken Murchison <ken@oceana.com>
+       * doc/index.html: added reference to a CIFS (SMB/NTLM) document
+
+2003-08-12  Ken Murchison <ken@oceana.com>
+       * doc/index.html: added reference to a good NTLM document
+
+2003-07-29  Ken Murchison <ken@oceana.com>
+       * plugins/cram.c: don't truncate long secrets to 64 bytes on the
+         client-side of CRAM-MD5 (jiang_xiong@yahoo.com)
+
+2003-07-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: another missed pointer init
+         (Will Fiveash <william.fiveash@sun.com>)
+
+2003-07-26  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/server.c: Missed pointer initialization fix
+         ("Dave Cridland [Home]" <dave@cridland.net>)
+
+2003-07-26  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: merged privacy and integrity security layer
+         code and removed use of tmp buffers for security layer
+
+2003-07-25  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: removed use of tmp buffer for security layer;
+         don't make a big buffer out of iovecs when encoding
+       * lib/server.c, plugins/login.c, plugins/plain.c: better handling
+         of auto_transition -- doesn't try to transition from auxprop to
+         auxprop
+
+2003-07-25  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in: Fix up some mysql/pgsql detection
+       * plugins/gssapi.c: improved error reporting
+         (William Fiveash <William.Fiveash@sun.com>)
+       * cmulocal/sasl2.m4, saslauthd/mechanisms.h: Improved
+         GSSAPI detection (don't default to MIT, require HAVE_KRB5_H
+         for the kerberos5 saslauthd module)
+         (Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>)
+
+2003-07-24  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: updated security layer code to be closer to draft -08
+
+2003-07-23  Rob Siemborksi <rjs3@andrew.cmu.edu>
+       * saslauthd/utils.[ch], saslauthd/configure.in: Detect/replace
+         strlcpy and strlcat (based on ideas from
+         Igor Brezac <igor@ipass.net>)
+
+2003-07-22  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c,
+         plugins/plugin_common.[ch]: moved encoded packet buffering into
+         _plug_decode()
+
+2003-07-21  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: updated auth code to draft -08 (layers still need
+         to be updated)
+       * configure.in, plugins/srp.c: use auxprop_store() instead of
+         direct sasldb access
+
+2003-07-21  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * configure.in: add runpath information for MySQL and Postgres;
+         better behavior for the interaction of --enable-sql and
+         --with-mysql / --with-pgsql
+       * saslauthd/lak.[ch]: %d to be derived from %u if it can be,
+         otherwise use %r (to account for the recent change in the
+         core library).  Add ldap_default_realm parameter
+         (Igor Brezac <igor@ipass.net>)
+
+2003-07-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Client side of digest md5 doesn't
+         have quotes around its cypher= directive (Bug 2113).
+       * saslauthd/lak.[ch]: support for ldap sasl binds,
+         support for tls (Igor Brezac <igor@ipass.net>)
+
+2003-07-17  Ken Murchison <ken@oceana.com>
+       * include/sasl.h, include/saslplug.h,
+       * lib/auxprop.c, lib/common.c, lib/server.c, plugins/sasldb.c:
+         implemented writable auxprops
+       * configure.in, plugins/otp.c, utils/saslpasswd: use
+         auxprop_store() instead of direct sasldb access
+       * doc/options.html, lib/server.c: implemented 'noplain' option for
+         auto_transition
+
+2003-07-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/config.c: Remove sasl_config_getint and sasl_config_getswitch
+         because they are unused and confusing
+       * lib/checkpw.c: Correctly split realm from username in
+         saslauthd_verify_password
+
+2003-07-15  Ken Murchison <ken@oceana.com>
+       * plugins/sql.c, doc/options.html: added sql_usessl option
+
+2003-07-15  Ken Murchison <ken@oceana.com>
+       * plugins/mysql.c: deleted
+       * plugins/sql.c: added
+       * acconfig.h, configure.in,
+         doc/components.html, doc/options.html, doc/sysadmin.html,
+         plugins/Makefile.am, plugins/makeinit.sh: deprecated MySQL plugin
+         in favor of a new generic SQL plugin (currently supports MySQL and
+         PostgreSQL)
+
+2003-07-15  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.15
+
+2003-07-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/components.html: added in the hopes that this gives a better
+         description of how all the components interact
+
+2003-07-02  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-anon-02.txt: added
+       * doc/draft-ietf-sasl-plain-02.txt: added
+       * doc/draft-ietf-sasl-saslprep-03.txt: added
+       * doc/draft-ietf-sasl-anon-01.txt: deleted
+       * doc/draft-ietf-sasl-plain-01.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest versions of
+         PLAIN, ANONYMOUS, SASLprep drafts
+
+2003-07-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * acconfig.h, cmulocal/sasl2.m4, plugins/gssapi.c:
+         Properly detect HAVE_GSS_C_NT_USER_NAME
+         (Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>)
+
+2003-07-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/kerberos4.c: Fix some maxoutbuf handling issues
+
+2003-07-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/mysql.c: Check return value of mysql_init
+         (Ivan Kelly <ivan@ivankelly.net>)
+
+2003-07-01  Ken Murchison <ken@oceana.com>
+       * doc/draft-burdis-cat-srp-sasl-08.txt: added
+       * doc/draft-ietf-sasl-rfc2222bis-01.txt: added
+       * doc/draft-ietf-sasl-rfc2831bis-02.txt: added
+       * doc/draft-burdis-cat-srp-sasl-06.txt: deleted
+       * doc/draft-ietf-sasl-rfc2222bis-00.txt: deleted
+       * doc/draft-ietf-sasl-rfc2831bis-01.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest versions of
+         SASL, SRP, DIGEST-MD5 drafts
+
+2003-06-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/mysql.c: Call mysql_init() too
+         (Hajimu UMEMOTO <ume@mahoroba.org>)
+
+2003-06-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/sysadmin.html: Add more text about how to use realms.
+
+2003-06-27  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.14
+
+2003-06-11  Rolf Braun <rbraun@andrew.cmu.edu>
+       * config/kerberos_v4.m4:
+         fix fallback to -lkrb4 when --enable-krb4 is specified
+       * config/ltconfig:
+       * config/ltmain.sh:
+         make the darwin libtool work on OS X v10.2
+         (bash/zsh shell syntax, and don't link bundles with extra args)
+       * dlcompat-20010505/dlopen.c: back out bogus delimiter change
+       * doc/macosx.html: update for 10.2 and add known problems section
+       * mac/osx_cfm_glue/cfmglue.c: fix sasl_done followed by client_init
+
+2003-06-11  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * man/sasl_client_new.3, man/sasl_server_new.3:
+         Security flags don't belong here, connection flags do.
+
+2003-06-10  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-crammd5-00.txt: added
+       * doc/draft-nerenberg-sasl-crammd5-03.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to WG version of
+         CRAM-MD5 draft
+
+2003-05-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: If we get an empty output token back
+         from gss_accept_sec_context, return
+         an empty string to transmit to the client.
+
+2003-05-30  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-rfc2831bis-01.txt: added
+       * doc/draft-ietf-sasl-rfc2831bis-00.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest version of
+         DIGEST-MD5 draft
+
+2003-05-28  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-anon-01.txt: added
+       * doc/draft-ietf-sasl-plain-01.txt: added
+       * doc/draft-ietf-sasl-rfc2222bis-00.txt: added
+       * doc/draft-ietf-sasl-anon-00.txt: deleted
+       * doc/draft-ietf-sasl-plain-00.txt: deleted
+       * doc/draft-myers-saslrev-02.txt: deleted
+       * doc/index.html, doc/Makefile.am: updated to latest versions of
+         SASL, PLAIN, ANONYMOUS drafts
+
+2003-05-21  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/ipc_unix.c: Accept File Descriptor Locking
+         Fixes (found by Leena Heino <Leena.Heino@uta.fi>)
+       * saslauthd/cache.c: Similar fixes
+         (Jeremy Rumpf <jrumpf@heavyload.net>)
+
+2003-05-15  Rob Siemborski <rjs3@andrew.cmu.edu>       
+       * configure.in: Actually listen to --disable-java
+         (Maciej W. Rozycki <macro@ds2.pg.gda.pl>)
+       * saslauthd/saslauthd-main.h: Increase listen backlog to
+         match Cyrus master process (Igor Brezac <igor@ipass.net>)
+
+2003-05-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/kerberos_v4.m4: Minor nit
+         (Carlos Velasco <carlosev@newipnet.com>)
+       * plugins/gssapi.c: Use GSS_C_NT_USER_NAME
+         to work around Solaris 8/9 libgss bug.
+         (gssapi_client_mech_step): Pass GSS_C_NO_BUFFER to first
+         invocation of gss_init_sec_context to work around Solaris 8/9
+         mech_krb5 bug. (Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>)
+       * cmulocal/sasl2.m4: Check for Sun SEAM GSS-API implementation
+         (Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>)
+       * saslauthd/configure.in: Check for krb5.h.  Don't define if GSSAPI
+         is present. (Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>)
+       * saslauthd/mechanisms.h: Test for HAVE_KRB5_H instead of HAVE_GSSAPI_H
+         to activate AUTH_KRB5. (Rainer Orth  <ro@TechFak.Uni-Bielefeld.DE>)
+       * plugins/mysql.c: Use mysql_real_connect() instead of mysql_connect()
+         (Petri Riihikallio <Petri.Riihikallio@Metis.fi>)
+       * saslauthd/: Misc ANSI C cleanups (Jeremy Rumpf <jrumpf@heavyload.net>)
+
+2003-05-13  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/sasldb.m4, utils/Makefile.am: fix installation of man
+         pages that are homed in the utils/ directory
+       * include/*.h: Add extern "C" blocks for C++ compiles
+
+2003-05-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/saslauthd-main.c: misc spelling and UI cleanups
+
+2003-04-16  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/saslauthd-main.c: Don't set the auth mech until
+         all options have been processed. (Peter Stamfest <peter@stamfest.at>)
+       * lib/client.c, lib/common.c, lib/saslint.h, lib/server.c: Do
+         reference counting of the number of times sasl has been inited/doned.
+
+2003-04-15  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/ltmain.sh: fix some portability problems in the use of expr
+         (Oliver Eikemeier <eikemeier@fillmore-labs.com>)
+
+2003-04-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.13
+
+2003-04-08  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/external.c, lib/server.c: use mech_avail to disable
+       EXTERNAL instead of special casing it (Chris Newman
+       <Chris.Newman@Sun.COM>)
+
+2003-03-31  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/ipc_unix.c, saslauthd/saslauthd-main.c,
+         saslauthd/saslauthd-main.h: use the pidfile locking from
+         the Cyrus IMAPd master process (implemented for saslauthd by
+         Igor Brezac <igor@ipass.net>)
+       * configure.in, acconfig.h: Add configure option to set what
+         we use for /dev/random
+
+2003-03-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/: Unify the source files so that the IPC methods
+         are broken out into a separate API.  Cacheing of authentication
+         credentials is also available as a command-line option.
+         Other changes include: Remove Time of Day Flag, omit
+         SO_REUSEADDR on AF_UNIX sockets, make using the accept-socket
+         locking runtime configurable, and misc other cleanup.
+         (Jeremy Rumpf <jrumpf@heavyload.net>)
+
+2003-03-26  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/plain.c: Defend against memory leak on canon_user
+         failure (Chris Newman <chris.newman@sun.com>)
+
+2003-03-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/auxprop.c, lib/checkpw.c, lib/common.c, lib/saslutil.c,
+         lib/server.c: Assorted minor fixes from Sun Microsystems
+         (provided by Chris Newman <chris.newman@sun.com>)
+
+2003-03-13  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: Fix a memset length.  (Igor Brezac <igor@ipass.net>)
+
+2003-03-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: fix parity of digest-uri test
+       * lib/client.c, common.c, saslint.h, server.c: Pass global
+         callbacks to global utils structure
+         (Howard Chu <hyc@highlandsun.com>)
+       * saslauthd/auth_krb5.c: Fix memory/file descriptor leak
+         in krb5 authentication (Jonathen Chen <jon@spock.org>)
+       * saslauthd/lak.c, lak.h, LDAP_SASLAUTHD: Remove ldap_cache
+         code, and rename MAX() to LAK_MAX()
+
+2003-02-20  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-rfc2831bis-00.txt: added
+       * doc/draft-melnikov-rfc2831bis-02.txt: deleted
+       * doc/draft-newman-sasl-c-api-01.txt: added
+       * doc/draft-newman-sasl-c-api-00.txt: deleted
+       * doc/index.html: updated to WG version of DIGEST-MD5 draft,
+         updated to latest C API draft
+       * doc/Makefile.am: updated to WG version of DIGEST-MD5 draft,
+         updated to latest C API draft
+
+2003-02-12  Lawrence Greenfield  <leg+@andrew.cmu.edu>
+       * plugins/digestmd5.c: verify the service component of digest-uri
+
+2003-02-11  Ken Murchison <ken@oceana.com>
+       * doc/draft-ietf-sasl-anon-00.txt: added
+       * doc/draft-ietf-sasl-plain-00.txt: added
+       * doc/draft-zeilenga-sasl-anon-01.txt: deleted
+       * doc/draft-zeilenga-sasl-plain-01.txt: deleted
+       * doc/index.html: updated to WG versions of ANONYMOUS, PLAIN drafts
+
+2003-02-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * cmulocal/sasl2.m4: Don't use -ldes to check for Heimdal
+       * saslauthd/auth_krb4.c, saslauthd/auth_shadow.c,
+         saslauthd/auth_getpwent.c, lib/kerberos4.c:
+         Smarter checking of #includs for des.h
+         (Mark Keasling <mark@air.co.jp>)
+       * saslauthd/testsaslauthd.c, saslauthd/saslauthd-doors.c:
+         retry_read() should use a char * buffer not a void *
+         buffer (Mark Keasling <mark@air.co.jp>)       
+       * cmulocal/berkdb.m4: Set CPPFLAGS around tests
+         (based on patch from Leena Heino <Leena.Heino@uta.fi>)
+       * config/sasldb.m4: Actually use results of Berkeley DB tests
+         (Leena Heino <Leena.Heino@uta.fi>)
+       * Ready for 2.1.12
+
+2003-01-31  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.11
+       * utils/Makefile.am: Ensure that dbconverter-2 can see the sasldb
+         include directory.
+
+2003-01-29  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: Fix a situation where the realm wasn't
+         being set for the client context, causing a segfault
+       * config/kerberos_v4.m4: first check des_* then check DES_*
+         during OpenSSL tests (based on ideas from
+         Leena Heino <Leena.Heino@uta.fi>)
+
+2003-01-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/sasldb.m4: Don't build sasldb plugin if compiling
+         --with-dblib=none, since it will only fail to load anyway.
+
+2003-01-27  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/configure.in: use CMU_ADD_LIBPATH for LDAP support
+         (Simon Brady <simon.brady@otago.ac.nz>)
+
+2003-01-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/acconfig.h: protect file from being included more than
+         once (reported by Jeremy Rumpf <jrumpf@heavyload.net>)
+       * saslauthd/configure.in, configure.in: Move OpenSSL detection into
+         cmulocal, detect openssl for use with lak.c
+
+2003-01-21  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: only _require_ one response (LM and/or NT), not both
+
+2003-01-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c, saslauthd/lak.h: Add the fastbind auth method
+         (Simon Brady <simon.brady@otago.ac.nz>)
+
+2003-01-01  Ken Murchison <ken@oceana.com>
+       * saslauthd/configure.in, saslauthd/Makefile.am: don't make
+         -lcrypt dependent upon --enable-plain
+
+2002-12-11  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: set SASL_FEAT_ALLOWS_PROXY on client side
+
+2002-12-10  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: explicitly #include <openssl/md5.h> to resolve
+         OpenBSD/OpenSSL cruftiness
+
+2002-12-10  Rob Siemborksi <rjs3@andrew.cmu.edu>
+       * saslauthd/saslauthd-doors.c: Fix a potential memory leak when
+         we call door_return()
+
+2002-12-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/auxprop.c: Correct leak in prop_clear, also update list_end
+         in prop_request.
+       * doc/options.html: Update use of saslauthd_path to be correct
+
+2002-12-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.10
+
+2002-12-05  Larry Greenfield <leg@andrew.cmu.edu>
+       * plugins/digestmd5.c: DES key fixes. stupid DES libraries want
+          the key in the stupid DES parity format.
+        * plugins/digestmd5.c:  refactored some of the cipher code so that
+          there isn't RC4 state around when we're using DES and vice versa
+
+2002-12-05  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: Allocate a large enough buffer to account for
+         a completely escaped username. (lak_escape and lak_filter)
+       * lib/common.c: Ensure there is enough space for the trailing \0
+         in _sasl_log
+
+2002-12-04  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/canonusr.c: Check for potential buffer overflow
+
+2002-12-03  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: major fast reauth rewrite, mech_step cleanup
+       * doc/options.html: server-side reauth is disabled by default
+
+2002-11-24  Ken Murchison <ken@oceana.com>
+       * plugins/login.c: allow authid to be passed in initial response
+       * doc/draft-sasl-login.txt, doc/mechanisms.html:
+         documentation updates re: initial response
+
+2002-11-07  Ken Murchison <ken@oceana.com>
+       * doc/draft-nerenberg-sasl-crammd5-03.txt: added
+       * doc/draft-nerenberg-sasl-crammd5-02.txt: deleted
+       * doc/draft-zeilenga-sasl-anon-01.txt: added
+       * doc/draft-zeilenga-sasl-anon-00.txt: deleted
+       * doc/draft-zeilenga-sasl-plain-01.txt: added
+       * doc/draft-zeilenga-sasl-plain-00.txt: deleted
+       * doc/index.html: updated to latest CRAM-MD5, ANONYMOUS, PLAIN drafts
+
+2002-11-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/kerberos4.c: Make at most 1 canon_user call, not two.
+         (Howard Chu <hyc@highlandsun.com>)
+
+2002-10-25  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: minor cleanups
+
+2002-10-24  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: fix problem where saslauthd stops LDAP
+         authentications when ldap_auth_method is bind.
+         (Igor Brezac <igor@ypass.net>)
+       * doc/sysadmin.html, doc/options.html, saslauthd/saslauthd.mdoc:
+         documentation updates re: saslauthd mux path
+
+2002-10-23  Ken Murchison <ken@oceana.com>
+       * lib/external.c: added SASL_SEC_NOANONYMOUS to client side
+         (Howard Chu, <hyc@highlandsun.com>)
+
+2002-10-21  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: NTLM probably doesn't offer perfect forward secrecy
+       * doc/mechanisms: added table of properties/features
+
+2002-10-20  Ken Murchison <ken@oceana.com>
+       * saslauthd/lak.ch: consolidated hashed password checking code
+
+2002-10-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.[ch], saslauthd/auth_ldap.c:
+         Code cleanup, now support {SHA}, {SSHA}, {MD5}, and {SMD5} hashes,
+         misc other cleanup. (Igor Brezac <igor@ypass.net> and
+         Thomas Lussnig <thomas.lussnig@bewegungsmelder.de>)
+
+2002-10-17  Ken Murchison <ken@oceana.com>
+       * doc/draft-melnikov-rfc2831bis-02.txt: added
+       * doc/draft-melnikov-rfc2831bis-01.txt: deleted
+       * doc/index.html: updated to latest RFC 2831bis draft
+
+2002-10-11  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/Makefile.am: add missing staticopen.h to EXTRA_DIST,
+         fix some dependencies
+       * Ready for 2.1.9
+
+2002-10-10  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.8
+
+2002-10-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/client.c: Allow plaintext mechanisms under an external security
+         layer.
+
+2002-10-07  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * sample/server.c: Fix some IPV6 defines
+         (Marshall Rose <mrose@dbc.mtview.ca.us>)
+
+2002-10-02  Ken Murchison <ken@oceana.com>
+       * lib/checkpw.c: return SASL_NOUSER when we can't find APOP secret
+       * lib/server.c: plug APOP memory leak and consolidate canonification
+       * configure.in: force the use of a cache file
+         (Carlos Velasco <carlosev@newipnet.com>)
+
+2002-10-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/checkpw.c: Fix some misuses of sasl_seterror
+         (Martin Exler <m.exler@gmx.at>)
+
+2002-09-24  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/sasl2.m4, saslauthd/Makefile.am: GSSAPI doesn't need
+         to link ndbm.  Also cleanup some sasldb linking in saslauthd.
+
+2002-09-23  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * config/kerberos_v4.m4: Don't compile with kerberos unless we
+         have both the libs and the headers (Carlos Velasco
+         <carlosv@newipnet.com>)
+
+2002-09-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: endinaness corrections
+       * sasldb/db_berkeley.c, utils/dbconverter-2.c: Berkley DB 4.1
+         support (Mika Iisakkila <mika.iisakkila@pingrid.fi>)
+
+2002-09-19  Ken Murchison <ken@oceana.com>
+       * plugins/plugin_common.[ch]: make SASL_CB_USER and result optional
+       * plugins/anonymous.c: use SASL_CB_USER for fetching trace info,
+         don't require SASL_CB_AUTHNAME
+       * plugins/gssapi.c, plugins/kerberos.c: don't require SASL_CB_USER
+       * lib/external.c: define SASL_FEAT_ALLOWS_PROXY for this mechanism,
+         don't require SASL_CB_USER
+
+2002-09-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/srp.c, plugins/kerberos4.c: correct maxoutbuf handling
+       * plugins/digestmd5.c: correct maxoutbuf handling, actually
+         send maxbuf to the remote.
+       * lib/common.c: sanity check security properties
+       
+2002-09-17  Ken Murchison <ken@oceana.com>
+       * plugins/ntlm.c: home-grown client/server NTLM implementation
+       * configure.in: NTLM depends on OpenSSL libcrypto
+       * doc/sysadmin.html: added NTLM blurb
+
+2002-09-16  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/canonusr.c: don't index begin_u with -1
+         (Randy Kunkee <randy@randallkunkee.com>)
+       * doc/sysadmin.html: cleanup
+       * utils/saslpasswd.c: don't exit with -SASL_FAIL
+       * saslauthd/saslauthd-unix.c: use a char* instead of a void* in
+         retry_read
+
+2002-09-12  Ken Murchison <ken@oceana.com>
+       * lib/common.c: NULL outbuf if we get no output from sasl_decode()
+
+2002-09-11  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/mysql.c: Actually loop through the potential servers
+         properly (Seow Kok Heng <kokheng@jhs.com.sg>)
+       * acinclude.m4: Added copy of the correct libtool macros as
+         acinclude.m4
+       * configure.in: fix for gcc 3.x
+         (Carlos Velasco <carlosev@newipnet.com>)
+
+2002-09-10  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/server.c: Better handling of add_plugin failures
+
+2002-09-10  Ken Murchison <ken@oceana.com>
+       * acconfig.h, configure.in: enable/disable NTLM
+       * lib/staticopen.h, plugins/Makefile.am, makeinit.sh, ntlm.c:
+         added NTLM support (client-side only)
+
+2002-09-07  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/configure.in, saslauthd/Makefile.am: don't
+         do configure substitutions for the saslauthd_SOURCES variable
+         (Carlos Velasco <carlosev@newipnet.com>)
+
+2002-09-05  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/os390.html: added
+       * doc/index.html: referenced os390.html and macosx.html
+       * lib/Makefile.am: better handling of plugin_common
+
+2002-09-04  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * (throughout) Extensive cleanup of how we build static and
+         shared versions of libsasl.  Also some more portability
+         fixes (Howard Chu <hyc@highlandsun.com>)
+
+2002-09-04  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * acconfig.h, configure.in: Actually check for sysexits.h,
+         varargs.h, and stdarg.h
+       * lib/checkpw.c: compatibility patch for retry_read
+         (Howard Chu <hyc@highlandsun.com>)
+
+2002-09-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * (throughout) fix handling of sys/param.h
+       * (throughout) fix handling of time.h and sys/time.h
+       * include/exits.h: include a replacement for sysexits.h
+       * acconfig.h: define MAXHOSTNAMELEN if it isn't
+       * lib/getaddrinfo.c, config/ipv6.m4: minor fixes for partial
+         getaddrinfo/getnameinfo implementations
+       * (Above changes are all from or based on ideas from
+          Howard Chu <hyc@highlandsun.com>)
+
+2002-08-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/client.c, lib/saslint.h: Properly handle client-side
+         serverFQDN and clientFQDN
+
+2002-08-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/dlopen.c: use correct paths when a .la file is not present
+         (Justin Gibbs <gibbs@scsiguy.com>)
+
+2002-08-13  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/sysadmin.html: fix some /usr/lib/sasl references to
+         /usr/lib/sasl2 (Andrew Jones <arjones@simultan.dyndns.org>)
+
+2002-08-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/Makefile.am: fix small parts of the saslauthd.8 build
+         process.
+       * Ready for 2.1.7
+
+2002-08-06  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: disable/remove server-side fast reauth
+
+2002-08-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * include/sasl.h, lib/common.c: Add SASL_AUTHUSER as a parameter
+         to sasl_getprop
+
+2002-08-01  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: allow use of more than one %u or %r in the filter
+         (Laurent Larquère <llarquere@aacom.fr>)
+
+2002-07-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/client.c, lib/server.c: Add checks for SASL_NEED_PROXY and
+         SASL_FEAT_ALLOWS_PROXY
+       * include/sasl.h, include/saslplug.h: Add SASL_NEED_PROXY and
+         SASL_FEAT_ALLOWS_PROXY
+       * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c,
+         plugins/otp.c, plugins/plain.c, plugins/srp.c: define
+         SASL_FEAT_ALLOWS_PROXY for these mechanisms
+
+2002-07-27  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_sasldb.c: Include mechanisms.h in a reasonable place.
+
+2002-07-24  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/Makefile.am: Fix DEFS to still supply -I. and -I..
+       * configure.in: Make --with-ldap show up in top level configure script,
+         make saslauthd compile by default
+       * lib/saslutil.c: use read() and not fread() on /dev/random to preserve
+         entropy
+       * doc/sysadmin.html: Add note about using /dev/urandom
+
+2002-07-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * doc/sysadmin.html, doc/readme.html, doc/upgrading.html:
+         Misc. documentation cleanup (Joe Rhett <jrhett@isite.net>)
+
+2002-07-17  Ken Murchison <ken@oceana.com>
+       * lib/canonusr.c: update length of user string to length of output
+         from callback 
+
+2002-07-16  Rob Siemborski <rjs3+@andrew.cmu.edu>
+        * plugins/cram.c: Fix a security problem in the verification of
+          the digest string. (Andrew Jones <arjones@simultan.dyndns.org>)
+       * Ready for 2.1.6
+
+2002-07-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/mysql.c: Further memory management cleanup. (never
+         strdup the options, and therefore don't free staticly allocated
+         strings)
+       * man/sasl_getopt_t.3: Clarify semantics of memory management
+
+2002-07-05  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/lak.c: Better handling of downed ldap servers
+         (Igor Brezac <igor@ipass.net>)
+       * sasldb/db_berkeley.c, utils/dbconverter-2.c: Use db_strerror()
+          rather than strerror() for Berkeley DB error values.
+         (J.H.M. Dassen (Ray) <jdassen@debian.org>)
+       * saslauthd/Makefile.am, saslauthd/auth_ldap.c: don't
+         hardwire the saslauthd conf file
+         (J.H.M. Dassen (Ray) <jdassen@debian.org>)
+
+2002-07-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * man/sasl_user_exists.3: fix sasl_idle reference
+
+2002-07-02  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/auxprop.c: Can now select multiple auxprop plugins
+       * doc/options.html: updated for above
+       * lib/client.c: improve mechanism selection to include
+         number of security flags
+
+2002-06-27  Ken Murchison <ken@oceana.com>
+       * doc/draft-zeilenga-sasl-plain-00.txt: added
+       * doc/index.html: added PLAIN draft
+
+2002-06-26  Ken Murchison <ken@oceana.com>
+       * doc/draft-zeilenga-sasl-anon-00.txt: added
+       * doc/index.html: added ANONYMOUS draft
+
+2002-06-20  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/auxprop.c: Make "cound not find auxprop plugin" warning
+         log at LOG_DEBUG
+
+2002-06-19  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: create layer keys for integrity as
+         well as privacy
+       * saslauthd/auth_ldap.[ch], saslauthd/lak.[ch]:
+         Large rewrite (Igor Brezac <igor@ipass.net>)
+       * lib/client.c, lib/server.c, lib/common.c:
+         Actually set most of the sparams and cparams structures
+
+2002-06-19  Ken Murchison <ken@oceana.com>
+       * doc/draft-melnikov-rfc2831bis-01.txt: added
+       * doc/draft-melnikov-rfc2831bis-00.txt: deleted
+       * doc/index.html: updated to latest RFC 2831bis draft
+
+2002-06-18  Ken Murchison <ken@oceana.com>
+       * doc/draft-nerenberg-sasl-crammd5-02.txt: added
+       * doc/draft-nerenberg-sasl-crammd5-01.txt: deleted
+       * doc/index.html: updated to latest CRAM-MD5 draft
+
+2002-06-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/login.c, plugins/plain.c: Canonicalize username before
+         doing checkpass
+
+2002-06-14  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/client.c, lib/server.c, lib/saslint.h, lib/common.c.
+         lib/seterror.c: continued size_t vs unsigned cleanups
+
+2002-06-13  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/ : remove LDAP support
+       * Ready for 2.1.5
+
+2002-06-12  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/digestmd5.c: rename get_realm to get_server_realm, and
+         pay attention to its return value
+       * lib/external.c, lib/seterror.c: cleanup size_t/unsigned confusion
+
+2002-06-10  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * sasldb/Makefile.am: fix handling of allockey (only include it once)
+       * plugins/kerberos4.c: fix a reference count leak
+       * Ready for 2.1.4
+
+2002-05-28  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/LDAP_SASLAUTHD, saslauthd/saslauthd.mdoc:
+         Update documentation for LDAP and Saslauthd as per
+         Igor Brezac <igor@ipass.net>
+
+2002-05-22  Lawrence Greenfield  <leg+@andrew.cmu.edu>
+       * lib/checkpw.c: close door file descriptor in
+         saslauthd_verify_password
+
+2002-05-21  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_krb5.c: fix a leak due to not
+         calling krb5_cc_destroy on failure
+
+2002-05-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/saslauthd-*.c: support a generic mechanism option -O
+         instead of -H
+       * saslauthd/auth_ldap.c, lak.c, et. al: auth_ldap overhaul
+         (Igor Brezac <igor@ipass.net>)
+       * lib/common.c, include/sasl.h: add sasl_version
+
+2002-05-13  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * lib/checkpw.c: use "*cmusaslsecretPLAIN" in auxprop_verify_password
+         (Howard Chu, <hyc@highlandsun.com>), also only make a single
+         canon_user call.
+
+2002-05-13  Ken Murchison <ken@oceana.com>
+       * plugins/plugin_common.c: set the return code to SASL_FAIL, and
+         NULL the results of the _plug_get_*() functions before we get
+         started
+       * plugins/digestmd5.c, otp.c, plain.c, srp.c: check for NULL or
+         empty authzid from callback
+
+2002-05-09  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/configure.in: --with-ldap now takes a path
+
+2002-05-08  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/acconfig.h, auth_ldap.c, configure.in, lak.c, lak.h:
+         Misc compile/portability fixes (mostly header-related)
+       * utils/testsuite.c: minor getopt() parameter fix
+         (Claus Assmann <ca+sasl@sendmail.org>)
+       * lib/checkpw.c: fix some warnings
+
+2002-05-07  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * Ready for 2.1.3-BETA
+
+2002-05-06  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * include/saslplug.h: add name member for canon_user plugins
+       * lib/canonusr.c: use name member
+
+2002-05-06  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: added client-side reauth
+
+2002-05-05  Ken Murchison <ken@oceana.com>
+       * lib/client.c: pass global_context to mech_new()
+       * lib/server.c: don't free global_context (the plugin should free it)
+       * utils/testsuite: swapped serverlast tests so that the
+         descriptions are correct
+
+2002-05-03  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c: added server-side reauth
+       * doc/index.html: added Marshall Rose's SASL papers
+       * doc/options.html: added 'reauth_timeout'
+
+2002-05-03  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/kerberos4.c: fix compile errors
+       * config/kerberos_v4.m4, plugins/digestmd5.c: fix des_cbc_encrypt
+         interoperability problem (OpenSSL)
+       * saslauthd/Makefile.am, acconfig.h, auth_ldap.c, auth_ldap.h,
+         configure.in, lak.c, lak.h, mechanisms.c, mechanisms.h,
+         saslauthd.conf: added experimental LDAP saslauthd module 
+         (by Igor Brezac <igor@ipass.net>)
+       * include/saslplug.h: give auxprop plugins a name
+       * plugins/sasldb.c: give sasldb plugin a name
+       * lib/auxprop.c: allow auxprop selection
+       * doc/options.html: document auxprop_plugin option
+
+2002-05-01  Ken Murchison <ken@oceana.com>
+       * plugins/digestmd5.c, gssapi.c, kerberos4.c, srp.c:
+         general plugin cleanup - standardizing structure
+
+2002-04-30  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: Minor cleanup of struct hack in context structure
+
+2002-04-30  Ken Murchison <ken@oceana.com>
+       * plugins/plugin_common.[ch], anonymous.c, cram.c, login.c, otp.c,
+         plain.c, sasldb.c, srp.c,
+         lib/client.c, external.c, saslint.h, server.c: general plugin
+         cleanup - reusing more common code, standardizing structure
+
+2002-04-28  Ken Murchison <ken@oceana.com>
+       * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c,
+         gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c,
+         lib/external.c:finalize movement of callback/interaction stuff
+         into plugin_common
+
+2002-04-27  Ken Murchison <ken@oceana.com>
+       * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c,
+         gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c,
+         lib/external.c: move make_prompts stuff into plugin_common
+       * utils/testsuite.c: allow for testing of EXTERNAL
+
+2002-04-26  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * sasldb/allockey.c: be sure to set userPassword and not *userPassword
+
+2002-04-26  Ken Murchison <ken@oceana.com>
+       * lib/client.c, server.c: check 'doneflag' just before mech_step()
+       * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c,
+         gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c,
+         lib/external.c, Makefile.am: move callback/interaction stuff
+         into plugin_common
+       * plugins/plugin_common.[ch], digestmd5.c, gssapi.c,
+         kerberosv4.c, srp.c: move decode/concatenation of multiple
+         packets into plugin_common
+       * utils/testsuite.c: set SASL_AUTH_EXTERNAL so we can test EXTERNAL
+
+2002-04-25  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: don't free the secret when we get data from a
+         callback (and don't copy it)
+       * plugins/gssapi.c, plain.c: make sure to set 'doneflag' when done
+       * lib/client.c, server.c: don't call mech_step() if 'doneflag' is set
+
+2002-04-24  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/cram.c, digestmd5.c, login.c, plain.c, srp.c: don't
+         free the secret when we get data from a callback (and don't copy it)
+       
+2002-04-22  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * include/gai.h: Fix for compatibility with older glibc versions
+         (Howard Chu, <hyc@highlandsun.com>)
+       * plugins/gssapi.c: Don't always send authzid on client side
+         (Howard Chu, <hyc@highlandsun.com>)
+
+2002-04-18  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * saslauthd/auth_sasldb.c: Use "use_realm" instead of "realm"
+         for lookup of secret. (Jonas Oberg <jonas@gnu.org>)
+       * plugins/gssapi.c: Correct handling of client-side authid and
+         authzid (Howard Chu, <hyc@highlandsun.com>)
+       * lib/external.c: Better handling of user canonicalization
+         (Howard Chu, <hyc@highlandsun.com>)
+       * plugins/cram.c, digestmd5.c, gssapi.c, kerberos4.c,
+         login.c, otp.c, plain.c, srp.c:  zero out prompt_need structures
+         before use
+
+2002-04-17  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/cram.c, digestmd5.c, srp.c: Adjust cmusaslsecretFOO to
+         *cmusaslsecretFOO
+       * plugins/sasldb.c: correctly handle *(property)
+       * lib/canonusr.c, server.c: Lookup authzid and authid auxprops
+         correctly (and in the same place).
+       * include/sasl.h, saslplug.h: Fix auxprop lookups
+         (e.g. SASL_AUXPROP_AUTHZID)
+
+2002-04-15  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: Handle null authzid's correctly
+       * lib/server.c: fix a strcmp() that should be a memcmp()
+
+2002-04-15  Rob Siemborski <rjs3@andrew.cmu.edu>
+       * plugins/gssapi.c: fix how name_token and name_without_realm are
+         freed.
+
+2002-04-12  Ken Murchison <ken@oceana.com>
+       * doc/draft-melnikov-rfc2831bis-00.txt: added
+       * doc/draft-myers-saslrev-02.txt: moved TOC
+       * doc/draft-myers-saslrev-02.txt: added
+       * doc/draft-myers-saslrev-01.txt: deleted
+       * doc/index.html: changed link to updated saslrev draft,
+         added KERBEROS_V4 notation,
+         added link to rfc2831bis draft
+
+2002-04-08  Ken Murchison <ken@oceana.com>
+       * lib/server.c, doc/options.html: allow multiple pwcheck_methods
+
+2002-04-03  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/configure.in: properly define AUTH_KRB5
+       * saslauthd/auth_krb5.c: changes for MIT KRB5
+
+2002-03-27  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Removed check for db3/db.h (people can just use --with-bdb-incdir)
+
+2002-03-26  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Ready for 2.1.2
+
+2002-03-11  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/kerberos4.c: Fix a race condition during mutex allocation
+
+2002-03-04  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/checkpw.c: Stop logging "authentication failed" message
+       * plugins/gssapi.c: Reduce log level of "gss_accept_context" message
+
+2002-02-27  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/saslauthd.mdoc: Clarify that sasldb with saslauthd
+         is not what you want to be doing.
+       * doc/sysadmin.html: Update "sasldb" verifier to "auxprop"
+
+2002-02-22  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/checkpw.c: made retry_read static
+
+2002-02-21  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/checkpw.c (auxprop_verify_password) report SASL_NOUSER instead
+         of SASL_FAIL.
+       * lib/client.c, lib/server.c: More Complete returning of SASL_NOTINIT
+       * utils/testsuite.c: Better checking for SASL_NOTINIT
+
+2002-02-11  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: removed OpenSSL 0.9.6 dependencies, small bugfix
+       * configure.in: cleaned up OpenSSL (libcrypto) check
+
+2002-02-05  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * contrib/tclsasl: Add Marshall Rose's <mrose@dbc.mtview.ca.us>
+         tclsasl patch.
+       * plugins/anonymous.c: No longer append extra NUL to client response
+
+2002-02-04  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/saslpasswd.c: Added -n option (Ken Murchison)
+       * lib/dlopen.c: Removed confusing entry point message.
+       * Ready for 2.1.1
+
+2002-02-01  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: fixed srp_setpass()
+
+2002-01-31  Ken Murchison <ken@oceana.com>
+       * include/sasl.h, lib/server.c,
+         plugins/digestmd5.c, gssapi.c, kerberos4.c, srp.c:
+         added SASL_SEC_MUTUAL_AUTH
+       * plugins/srp.c: cleanup error messages and return codes
+       
+2002-01-30  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c, plugins/otp.h: added non-OPIE client/server
+         implementation (requires OpenSSL)
+       * configure.in: OTP now requires OpenSSL, OPIE is optional
+       * doc/options.html, doc/readme.html, doc/sysadmin.html, doc/TODO:
+         updated for new OTP implementation
+
+2002-01-25  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/Makefile.am: Correct multiple EXTRA_DIST bug
+       * saslauthd/Makefile.am: small typo fixed (Leena Heino <liinu@uta.fi>)
+
+2002-01-23  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/dbconverter-2.c (main): More intelligent default paths
+       * acconfig.h: #ifndef's for _GNU_SOURCE (Assar <assar@permabit.com>)
+
+2002-01-22  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/common.c: Complete definition of sasl_global_listmech
+         (from Love <lha@stacken.kth.se>)
+       * lib/client.c: added checks for _sasl_client_active to
+         sasl_client_new and sasl_client_start
+
+2002-01-21  Ken Murchison <ken@oceana.com>
+       * doc/draft-myers-saslrev-01.txt: moved TOC
+       * doc/draft-ietf-cat-sasl-gssapi-05.txt: moved TOC
+       * doc/draft-nerenberg-sasl-crammd5-01.txt: added
+       * doc/draft-nerenberg-sasl-crammd5-00.txt: deleted
+       * doc/index.html: changed link to updated draft
+       * plugins/login.c (login_client_mech_step): fix client-first
+         handling
+
+2002-01-21  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/server.c (sasl_server_start): null out *serverout and
+         *serveroutlen, just in case.
+       * lib/external.c: Added correct required_prompts
+       * saslauthd/testsaslauthd.c: Added simple saslauthd client
+       * saslauthd/Makefile.am: rules for testsaslauthd
+       * doc/sysadmin.html: updated to reference testsaslauthd
+       * saslauthd/saslauthd.c: allow -n 0 (for fork-per-connection)
+       * saslauthd/saslauthd.mdoc: documentation of -n 0
+       * plugins/cram.c (crammd5_client_mech_step): fix client-first
+         handling
+       * sasldb/db_gdbm.c: improved error reporting
+         (Courtesy Marshall T. Rose <mrose@dbc.mtview.ca.us>
+       * config/sasldb.m4: improved gdbm configure handling
+         (Courtesy Marshall T. Rose <mrose@dbc.mtview.ca.us>
+       * config/kerberos_v4.m4: Detect OpenSSL libdes first.
+         (Courtesy Marshall T. Rose <mrose@dbc.mtview.ca.us>
+       * plugins/cram.c, digestmd5.c, kervberos4.c, login.c,
+         lib/client.c, server.c, include/saslplug.h:
+         Cleaner client-first ABI.
+
+2002-01-19  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: set serverout to NULL where we have nothing to
+         send instead of the empty string
+       * plugins/srp.c: let glue code handle client-last/server-last
+         situation by setting serverout appropriately
+
+2002-01-19  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/plain.c, plugins/login.c, plugins/digestmd5.c:
+          set serverout to NULL where we have nothing to send instead of
+         the empty string
+       * include/saslplug.h, lib/client.c, lib/server.c: eliminated
+         SASL_FEAT_WANT_SERVER_LAST in favor of clever setting of serverout
+       * plugins/digestmd5.c: removed SASL_FEAT_WANT_SERVER_LAST
+
+2002-01-18  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: updated to draft-burdis-cat-srp-sasl-06
+       * plugins/srp.c: server uses external SSF
+       * plugins/srp.c: server sends mandatory options based on min SSF
+       * doc/draft-burdis-cat-srp-sasl-06.txt: added
+       * doc/draft-burdis-cat-srp-sasl-05.txt: deleted
+       * doc/index.html: changed link to updated draft
+
+2002-01-17  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/kerberos4.c: Actually allocate a mutex on the client side
+
+2002-01-16  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/server.c (mech_permitted): fixed incorrect return value of
+         SASL_NOMECH that should have been 0.
+       * lib/common.c (sasl_errdetail): fixed core if passed in conn is NULL
+       * plugins/digestmd5.c (encode_tmp_buf): removed unneeded buffer
+
+2002-01-16  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: fixed layer decoding to handle multiple packets
+       * plugins/srp.c: plugged memory leaks (now passes testsuite)
+       * plugins/srp.c: more logging
+       * plugins/srp.c: lots of other nits, bug fixes
+       * utils/testsuite.c: added SSF=0/56 test
+
+2002-01-14  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/auth_krb4.c (auth_krb4): fix tf_name memory leak,
+         and other efficency fixes
+
+2002-01-11  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * include/saslplug.h: Add flags member to params structures
+       * lib/client.c, lib/server.c: flags parameter to sasl_*_new
+         now gets to the plugins
+
+2002-01-10  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * include/sasl.h: Update for sasl_global_listmech API
+       * lib/common.c, lib/client.c, lib/server.c: sasl_global_listmech()
+       * lib/dlopen.c (_parse_la): fix parseing of dlname= line
+       * Ready for 2.1.0
+
+2002-01-09  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: fixed security_flags
+       * plugins/srp.c: corrected integrity layer encoding
+       * plugins/srp.c: finished maxbuffersize handling
+       * plugins/srp.c: fixed security_flags
+       * doc/index.html: added reference to SRP paper
+
+2002-01-09  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/common.c (sasl_decode): Removed maxoutbuf check
+       * man/sasl_setprop.3: Minor clarifications
+       * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c:
+         Assorted security layer fixes (maxoutbuf setting, mech_ssf setting)
+       * lib/common.c, lib/client.c, lib/server.c, lib/saslint.h:
+         Allowed client-side sasl_listmech calls.
+       * include/sasl.h: Minor cosmetic fix to comments
+       * doc/programming.html: Interaction memory management clarifications
+       * lib/common.c: Fix several crash problems in getprop
+         (Courtesy Marshall T. Rose <mrose@dbc.mtview.ca.us>)
+
+2002-01-05  Lawrence Greenfield  <leg+@andrew.cmu.edu>
+       * saslauthd/saslauthd.c: F_SETLK doesn't block; F_SETLKW does
+       * saslauthd/saslauthd.c: detect errors somewhat better
+
+2002-01-04  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/common.c: Allow sasl_setprop for SASL_DEFUSERREALM
+
+2002-01-04  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: don't send M2 if using a confidentiality layer
+       * plugins/srp.c: more constraint checks
+       * plugins/otp.c: improve standard hex/word response detection
+       * doc/install.html, doc/sysadmin.html, contrib/opie-2.4-fixes:
+         add patch for OPIE 2.4 to enable extended responses
+
+2002-01-03  Ken Murchison <ken@oceana.com>
+       * configure.in: removed check fpr gmp
+       * plugins/srp.c: migrated to OpenSSL's BN (removed GNU MP dependency)
+
+2001-12-20  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * sasldb/db_ndbm.c: Fixed small memory leak
+         (Courtesy  Howard Chu <hyc@highlandsun.com>)
+
+2001-12-18  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: more constraint checks
+
+2001-12-17  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/saslauthd.c: Prefork a number of processes to handle
+         connections.
+       * saslauthd/auth_krb4.c: Handle concurrent accesses better.
+
+2001-12-15  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: added confidentiality layers
+
+2001-12-14  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: improved client/server layer option handling
+       * plugins/srp.c: added client-side support for mandatory options
+       * plugins/srp.c: added framework for confidentiality layers
+       * plugins/srp.c: added some data sanity checking (thanks to
+         Tom Holroyd <tomh@po.crl.go.jp> for feedback)
+
+2001-12-13  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/server.c, lib/common.c: Fix handling of
+         global callbacks so that plugin_list works again
+
+2001-12-12  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * pwcheck/Makefile.am: Added include of ../lib
+         (from Hajimu UMEMOTO <ume@mahoroba.org>)
+
+2001-12-11  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * sasldb/db_ndbm.c: fix call to dbm_nextkey, from
+         Scot W. Hetzel <scot@genroco.com>
+
+2001-12-10  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * doc/plugprog.html: Update for new user canonicalization usage.
+       * man/sasl_canon_user.3: Update for new user canonicalization usage.
+       * configure.in: Actually set STATIC_GSSAPIV2 when necessary
+
+2001-12-08  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: make sure we have the HMAC before trying to use it
+       * plugins/srp.c: don't advertise server integrity w/o HMAC-SHA-1
+       * plugins/srp.c: move EVP_cleanup() to mech_free so mech can be reused
+
+2001-12-07  Ken Murchison <ken@oceana.com>
+       * configure.in: SRP now requires OpenSSL
+       * plugins/srp.c: migrated to OpenSSL's MDA/cipher abstraction API 
+       * plugins/srp.c: added RIPEMD-160 support
+       * plugins/srp.c: using "standard ACSII names" for MDA-names as
+         documented by [SCAN] (until determined otherwise)
+       * plugins/srp.c: using updated canon_user API to allow separate
+         canonicalization of authid and authzid.
+
+2001-12-06  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/canonusr.c: Better logging when desired plugin is not found.
+       * lib/checkpw.c: spelling error fixed.
+       * lib/canonusr.c, lib/checkpw.c, lib/client.c, lib/external.c,
+         lib/saslint.h, lib/server.c, include/sasl.h, include/saslplug.h,
+         plugins/*.c: Updated canon_user API to allow separate
+         canonicalization of authid and authzid.
+
+2001-12-05  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/Makefile.am, saslauthd/acconfig.h, saslauthd/configure.in:
+         Solaris 7 and FreeBSD (FreeBSD is courtesy of Claus Assmann
+         <ca+sasl@sendmail.org>)
+       * sasldb/Makefile.am: link order fix (Courtesy Claus Assmann
+         <ca+sasl@sendmail.org>)
+
+2001-12-05  Ken Murchison <ken@oceana.com>
+       * configure.in:
+       * plugins/Makefile.am: only build SRP with sasldb libs when
+         srp_setpass() is enabled
+       * plugins/srp.c: added HMAC-SHA-160 integrity layer
+       * plugins/srp.c: don't offer integrity layers unless HMAC-SHA-160
+         is available (mandatory)
+       * plugins/srp.c: fixed multiple integrity/confidentiality layer
+         client-side bug
+       * plugins/srp.c: fixed delete SRP secret bug
+       * plugins/srp.c: removed VL() stuff
+
+2001-12-04  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/Makefile.am, config/sasldb.m4: Build sasldblistusers2
+         and saslpasswd2.  Default database now /etc/sasldb2
+       * INSTALL, README, doc/index.html, doc/upgrading.html: Update
+         with upgrading instructions in preparation for release.
+       * doc/, /: Documentation reorganization, convert README and INSTALL to
+         HTML format.
+       * Bumped appropriate version numbers, Ready for 2.0.5-BETA
+
+2001-12-04  Ken Murchison <ken@oceana.com>
+       * acconfig.h, configure.in: dependency checking for SRP
+       * acconfig.h, configure.in:
+       * plugins/srp.c: made srp_setpass() a compile-time option (default=off)
+       * plugins/srp.c: use auxprop to fetch cmusaslsecretSRP/userPassword
+       * plugins/srp.c: code cleanup
+       * acconfig.h, configure.in:
+       * doc/sysadmin.html:
+       * plugins/otp.c: made otp_setpass() a compile-time option (default=off)
+
+2001-12-02  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: fixed SHA1 support
+       * plugins/srp.c: changed calculation of 'x' to coincide with draft -05
+       * plugins/srp.c: code cleanup
+
+2001-12-01  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: abstracted MDA interface
+       * plugins/srp.c: added SHA1 support (not working)
+
+2001-11-30  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: renumbered steps to start at 1
+       * plugins/srp.c: check plugin API version instead of SRP_VERSION
+       * plugins/srp.c: changed data exchanges to conform to draft -05
+
+2001-11-29  Ken Murchison <ken@oceana.com>
+       * plugins/srp.c: code now compiles and runs
+       * plugins/Makefile.am: added sasldb libs to SRP build
+
+2001-11-24  Ken Murchison <ken@oceana.com>
+       * lib/external.c: made EXTERNAL a client-send-first mechanism
+       * doc/index.html: added CRAM-MD5 draft
+
+2001-11-22  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: fixed otp_setpass() bug
+       * doc/sysadmin.html: OTP additions/changes
+
+2001-11-19  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/saslpasswd.c: Corrected disable handling
+
+2001-11-17  Ken Murchison <ken@oceana.com>
+       * doc/index.html, rfc2945.txt, rfc3174.txt: specification additions
+       * doc/Makefile.am: Updated included RFCs and IDs
+       
+2001-11-14  Ken Murchison <ken@oceana.com>
+       * lib/server.c, doc/options.html: added 'mech_list' option
+
+2001-11-14  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * sasldb/allockey.c: removed an assert() call
+       * sasldb/db_ndmb.c, sasldb/db_gdbm.c: Fixed cntxt's to be conn's 
+
+2001-11-13  Ken Murchison <ken@oceana.com>
+       * acconfig.h, configure.in:
+       * plugins/otp.c: support client-side OTP without OPIE
+
+2001-11-08  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: allow entry of one-time password via
+         SASL_CB_ECHOPROMPT callback
+       * plugins/otp.c: code cleanup
+       * doc/index.html, draft*.txt: specification updates/additions
+
+2001-11-08  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/cram.c, digestmd5.c, sasldb.c: Removed all assert()
+         calls from supported plugins.
+
+2001-11-07  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/testsuite.c: added proxy policy checks
+       * lib/checkpw.c (_sasl_auxprop_verify_apop): correct handling
+         of seterror calls
+
+2001-11-06  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/canonusr.c (_canonuser_internal): added necessary seterror calls
+       * doc/Makefile.am: Updated included RFCs and IDs
+       * lib/canonusr.c, lib/server.c: Corrected authzid/authid handling
+       * plugins/digestmd5.c: Unconfused authzid/authid in server call to
+         canon_user
+
+2001-11-01  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/gssapi.c, plugins/kerberos4.c: Get rid of unnecessary
+         buffer copy in security layer encodes.
+
+2001-10-24  Ken Murchison <ken@oceana.com>
+       * plugins/otp.c: added otp_setpass() so that saslpasswd can
+         be used instead of opiepasswd on closed systems
+       * doc/sysadmin.html: OTP additions/changes
+
+2001-10-22  Ken Murchison <ken@oceana.com>
+       * acconfig.h, configure.in: detect OPIE, enable/disable OTP
+       * plugins/Makefile.am, makeinit.sh, otp.c: added OTP support
+         (still need work on RFC2444 compliance - depends on OPIE changes)
+       * doc/index.html, options.html, sysadmin.html, rfc*.txt:
+         OTP additions/changes
+
+2001-10-18  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/testsuite.c: Test DES harder for DIGEST-MD5
+       * plugins/digestmd5.c (enc_des): Get rid of one buffer copy.
+       * plugins/digestmd5.c (dec_des, dec_3des): correct handling of
+         padding length check.
+
+2001-10-17  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * config/sasldb.m4: detect berkeley db 4
+       * plugins/gssapi.c, cram.c, kerberos4.c, digestmd5.c: have dispose
+         calls deal with the possibility of a null context
+
+2001-10-16  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/Makefile.am: Link LIB_PAM  as well, if needed
+       * plugins/digestmd5.c: Don't send a trailing nul on challenge and
+         responses.
+       * lib/server.c (sasl_server_start, sasl_server_step): Deal with
+         authentication failures better. (Reported by Larry Rosenbaum
+         <lmr@ornl.gov>)
+
+2001-10-02  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/Makefile.am, saslauthd/auth_sasldb.c,
+         saslauthd/configure.in: Changes to allow extraction of saslauthd
+         as needed.
+
+2001-09-19  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/getaddrinfo.c (getaddrinfo): Correct fix for
+         AI_PASSIVE bug from Hajimu UMEMOTO <ume@mahoroba.org>
+       * plugins/plugin_common.c, lib/common.c (_*_ipfromstring):
+         revert to previous versions.
+
+       * plugins/Makefile.am: Include necessry compatibility objects
+         as needed.
+       * lib/Makefile.am: compatibility code for static libsasl
+       * configure.in: small changes to make compatibility objects easy
+         to use.
+
+2001-09-18  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/plugin_common.c, lib/common.c (_*_ipfromstring):
+         no longer use AI_PASSIVE hint for getaddrinfo
+
+2001-09-13  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/auth_sasldb.c, saslauthd/auth_sasldb.h:
+         Added experimental sasldb saslauthd module
+       * saslauthd/configure.in: sasldb related config changes,
+         do not config if disabled
+
+2001-09-12  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/*, lib/checkpw.c (saslauthd_verify_password):
+         merged new saslauthd protocol from Ken Murchison <ken@oceana.com>
+
+2001-08-30  Rob Siemborski <rjs3+@andrew.cmu.edu>
+
+       * configure.in, saslauthd/configure.in: check for inet_aton
+         in libresolv.so, so as to link it if necessary
+
+       * config/sasldb.m4 (BERKELEY_DB_CHK_LIB): set runpath of library
+         if necessary
+
+2001-08-29  Rob Siemborski <rjs3+@andrew.cmu.edu>
+
+       * utils/testsuite.c: Minor testsuite fix (include paths)
+
+       * Ready for 2.0.4-BETA
+
+2001-08-24  Rolf Braun <rbraun+@andrew.cmu.edu>
+
+       * Mac OS 9 and X support, including Carbon
+         Mac OS 9 Classic support based on the SASL v1 code
+         by Aaron Wohl <n3liw+@andrew.cmu.edu>
+
+       * updated ltconfig and ltmain.sh
+       * acconfig.h:
+       * configure.in:
+       * lib/saslutil.c: use random() when jrand48() isn't available
+
+       * dlcompat-20010505:
+         dlcompat included for OS X support, compiles separately
+       * lib/dlopen.c: prefix symbols with underscore on OS X, as on OpenBSD
+         note that this is also detected automatically by configure,
+         this only helps when cross-compiling (for OS X?)
+
+       * acconfig.h:
+       * configure.in:
+       * config/kerberos_v4.m4
+         look for libdes524 when libdes doesn't exist.
+         look for libkrb4 when libkrb doesn't exist.
+
+       * lib/saslint.h:
+       * lib/common.c:
+       * lib/seterror.c:
+       * lib/Makefile.am:
+         split sasl_seterror() into a new file.
+         add_string -> _sasl_add_string and made this non-static
+         so seterror can use it.
+         added _sasl_get_errorbuf to go into the conn_t struct
+         so we don't have to know the format of that struct when
+         seterror.c is linked from glue code (i.e., the Mac OS X CFM glue)
+
+       * acconfig.h:
+         fix the order of the fake iovec struct for systems that
+         don't have it (like Mac OS 9) so it's the same order as
+         most Unixes that do (like Mac OS X) -- the CFM glue needs this
+
+       * acconfig.h:
+         include <sys/types.h> before we include <sys/uio.h>
+
+       * plugins/kerberos4.c:
+       * lib/checkpw.c:
+       * acconfig.h:
+       * configure.in:
+         check for krb_get_err_txt in the kerberos 4 library,
+         and use it instead of the krb_err_txt[] array if available
+
+       * plugins/kerberos4.c:
+         define KEYFILE to "/etc/srvtab" if not already defined
+         by the kerberos 4 headers (needed for MIT KfM 4.0)
+
+       * doc/macosx.html: added this
+       * README: point Mac OS X users to doc/macosx.html
+       * doc/Makefile.am: add doc/macosx.html to distfiles
+
+       * Makefile.am:
+       * lib/Makefile.am:
+       * include/Makefile.am:
+       * config/Info.plist:
+       * configure.in:
+         when building on Mac OS X, install a framework
+         in /Library/Frameworks
+
+       * mac/*:
+         projects and support files for Mac OS 9, classic and Carbon
+       * mac/osx_cfm_glue:
+         the glue to allow CFM Carbon applications under Mac OS X
+         call the Unix-layer SASL library
+
+       * lib/common.c:
+       * lib/canonusr.c:
+         don't do the auxprop stuff on Mac OS 9
+
+       * lib/getaddrinfo.c:
+         don't look up hostnames on Mac OS 9 (we only officially
+         support passing IP address strings anyway)
+
+       * lib/getaddrinfo.c:
+       * plugins/plugin_common.c:
+       * plugins/plugin_common.h:
+         don't include headers on Mac OS 9 that we don't have.
+
+       * sample/sample-client.c:
+         add a cast for Mac OS 9 (different type handling of char)
+
+       * plugins/makeinit.sh:
+         include the stub header to export the right symbols on Mac OS 9
+
+2001-08-20  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/gssapi.c (gssapi_server_mech_step): fixed accidental
+         back link into glue code
+
+       * config/kerberos4.m4: Actually link in -lkrb
+
+2001-08-15  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/common.c (_sasl_iptostring): #if 0'd out.
+
+       * lib/server.c (sasl_user_exists): only check the verifier we
+         are using
+
+       * config/kerberos_v4.m4 (SASL_DES_CHK): added
+       * config/kerberos_v4.m4 (SASL_KERBEROS_V4_CHK): included
+         entire check from configure.in
+       * configure.in: moved kerberos 4 code completely out.
+       * saslauthd/acconfig.h (WITH_DES, WITH_SSL_DES): Added
+         DES-related symbols   
+
+2001-08-14  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * configure.in: Check for sys/uio.h
+       * saslauthd/configure.in: Check for sys/uio.h
+       * config.h: Do the Right Thing for struct iovec (and
+         no longer include sys/uio.h elsewhere)
+       * saslauthd/config.h: Do the Right Thing for struct iovec (and
+         no longer include sys/uio.h elsewhere)
+
+2001-08-13  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/digestmd5.c (init_des, init_3des, enc_des, dec_des,
+         enc_3des, dec_3des): fixed interoperability problems,
+         3des was not decrypting with correct key and des was not
+         setting up the initial vector.
+
+       * lib/checkpw.c (always_true): log users who log in via this verifier
+
+2001-08-13  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/testsuite.c (giveokpath): fix memory leak
+
+       * lib/common.c (sasl_ipfromstring): add call to freeaddrinfo()
+       * plugins/plugin_common.c (_plug_ipfromstring): add call to
+         freeaddrinfo()
+
+       * lib/saslutil.c (sasl_randseed): actually initialize the randpool
+
+       * saslauthd/auth_getpwent.c (auth_getpwent): clear a warning
+       * saslauthd/auth_shadow.c (auth_shadow): clear a similar warning
+
+       * utils/Makefile.am (EXTRA_DIST): Actually include the needed files
+
+       * saslauthd/configure.in: Handle shadow passwords correctly
+       * saslauthd/acconfig.h: Handle shadow passwords correctly
+
+       * lib/checkpw.c (always_true): added
+       * configure.in: added check for alwaystrue verifier
+       * acconfig.h: added HAVE_ALWAYSTRUE
+       * doc/options.html: alwaystrue verifier documented
+
+2001-08-11  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/: Now configures separately from SASL, so as
+         to localize tests for that package within that package
+
+       * utils/dbconverter-2.c (listusers_cb): fix handling of APOP 
+
+2001-08-10  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/Makefile.am (install-data-local):
+         correct handling of $(DESTDIR) (and create the directory if it
+         isn't there) [Amos Gouaux <amos@utdallas.edu>]
+
+       * lib/server.c (sasl_server_init): Added plugname to add_plugin
+         call for EXTERNAL
+
+       * doc/index.html: updated
+       * doc/appconvert.html: cleaned up
+
+2001-08-09  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/digestmd5.c (digestmd5_client_mech_step): handle
+         missing authorization name
+       * plugins/plain.c (plain_client_mech_step): handle
+         missing authorization name
+
+       * include/sasl.h: better documentation of SASL_CB_CANON_USER
+
+2001-08-08  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * saslauthd/saslauthd.mdoc: updated re: pam
+       * saslauthd/saslauthd.8: regenerated
+       * saslauthd/Makefile.am: Link against PLAIN_LIBS also
+         (from Ken Murchison <ken@oceana.com>)
+
+2001-08-07  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/client.c (sasl_server_step): corrected maxoutbuf handleing
+       * lib/server.c (sasl_server_step): corrected maxoutbuf handleing
+       * lib/saslint.h (DEFAULT_MAXOUTBUF): removed
+
+       * lib/common.c (sasl_encodev, sasl_decode): maxbufsize checking
+
+       * utils/testsuite.c (testseclayer,doauth): more security layer
+         checking.  Added parameter to doauth to disable fatal() calls,
+         updated all callers.
+
+       * utils/smtptest.c (main): added ability to support LMTP
+
+       * plugins/gssapi.c: conform with draft-ietf-cat-sasl-gssapi-05.txt
+
+       * doc/draft-ietf-cat-sasl-gssapi-05.txt: added
+       * doc/Makefile.am (EXTRA_DIST): added above to EXTRA_DIST
+
+2001-08-06  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/dbconverter-2.c (listusers_cb): handle PLAIN-APOP
+
+       * lib/client.c (sasl_client_add_plugin, client_done):
+         save plugin name
+       * lib/server.c (sasl_server_add_plugin, server_done):
+         save plugin name
+       * lib/dlopen.c (_sasl_plugin_load): correctly pass pluginname
+       * lib/common.c (sasl_getprop): implement SASL_AUTHSOURCE properly
+       * lib/saslint.h (cmechanism_t, mechanism_t): added plugname field
+       * lib/canonusr.c (internal_canonuser_init): no longer limit
+         based on plugname
+       * plugins/sasldb.c (sasldb_auxprop_plug_init): no longer limit
+         based on plugname
+
+2001-08-01  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * utils/smtptest.c (iptostring): better behaved w.r.t endianness
+
+       * plugins/cram.c (crammd5_server_mech_step): support for old-style
+         secrets
+       * plugins/digestmd5.c (digestmd5_server_mech_step): support for
+         old-style secrets
+       * lib/checkpw.c (auxprop_verify_password,_sasl_make_plain_secret):
+         support for old-style secrets
+       * utils/dbconverter-2.c: added
+       * utils/sasldblistusers.c (listusers): Print out property names
+         as well as username@realm format.
+       * utils/saslpasswd.c (_sasl_sasldb_set_pass): Correctly handle updates
+         that concern old-style secrets
+
+       * sasldb/allockey.c: Added a missing null to propName in key parser
+       
+2001-07-31  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/kerberos4.c (mech_avail): made static
+
+       * plugins/kerberos4.c (mech_avail): fixed ipv4 check
+         (patch from Hajimu UMEMOTO <ume@mahoroba.org>)
+
+       * doc/appconvert.html: vague guide documenting our experience
+         porting Cyrus IMAPd to use SASLv2
+       * doc/Makefile.am: added appconvert.html
+
+       * lib/client.c (sasl_client_new): fixed ip address setting to hit
+               relevant params structures as well
+       * lib/server.c (sasl_server_new): fixed ip address setting to hit
+               relevant params structures as well
+       * lib/common.c (sasl_setprop): fixed ip address setting to hit
+               relevant params structures as well
+
+       * lib/common.c (sasl_seterror): fixed spelling error
+
+2001-07-30  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * sasldb/db_berkeley.c: utils->seterror() calls
+       * sasldb/db_gdbm.c: utils->seterror() calls
+       * sasldb/db_ndbm.c: utils->seterror() calls
+       * sasldb/allockey.c: utils->seterror() calls
+
+       * lib/common.c (sasl_seterror): still call logging callback with a
+         null sasl_conn_t
+
+       * plugins/sasldb.c (sasldb_auxprop_lookup): support for multiple
+         properties
+
+       * plugins/Makefile.am: added -module to LDFLAGS
+
+       * config/sasldb.m4: Allow specification of exact berkeley db
+         lib and include paths
+       * sasldb/Makefile.am: Add proper include directory
+
+       * sasldb/sasldb.m4 (SASL_DB_BACKEND_STATIC): include allockey.o
+       
+       * Ready for 2.0.3-BETA  
+
+       * plugins/kerberos4.c (kerberos4_server_plug_init): reset
+         srvtab when we do not load correctly.
+
+       * lib/staticopen.c (_sasl_load_plugins): do not fail
+         if a single plugin load fails
+
+       * include/sasl.h (SASL_CLIENT_FALLBACK): removed
+
+2001-07-27  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * configure.in: extracted SASLDB-related checking
+       * config/sasldb.m4: added
+
+       * configure.in: now cache the JNI include directory path
+
+       * utils/testsuite.c: switch some sasl_errstrings to sasl_errdetail
+       * plugins/gssapi.c: Fix error reporting
+
+       * plugins/gssapi.c: Required SASL_CB_USER instead of SASL_CB_AUTHNAME
+
+       * plugins/anonymous.c: Function name standardization
+       * plugins/cram.c: Function name standardization
+       * plugins/digestmd5.c: Function name standardization
+       * plugins/gssapi.c: Function name standardization
+       * plugins/kerberos.c: Function name standardization
+       * plugins/login.c: Function name standardization
+       * plugins/plain.c: Function name standardization        
+
+       * sasldb/allockey.c: Generalized SASLdb API
+       * sasldb/db_berkeley.c: Generalized SASLdb API
+       * sasldb/db_gdbm.c: Generalized SASLdb API
+       * sasldb/db_ndbm.c: Generalized SASLdb API
+       * sasldb/db_none.c: Generalized SASLdb API
+       * sasldb/db_testw32.c: Added #error to block compile so the API will
+               be fixed when we do the Win 32 port
+       * plugins/sasldb.c: Use new SASLdb API
+       * utils/saslpasswd.c: Use new SASLdb API
+       
+2001-07-26  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/common.c (_sasl_getcallback): fixed reference to
+               possibly NULL conn
+
+       * configure.in: only build saslpasswd and sasldblistusers
+               if we have a meaningfull libsasldb (e.g. not db_none),
+       * utils/Makefile.am: only build saslpasswd and sasldblistusers
+               if we have a meaningfull libsasldb (e.g. not db_none),
+
+       * configure.in: conditionally build smtptest
+       * utils/Makefile.am: conditionally build smtptest
+       
+       * sasldb/allockey.c (_sasldb_parse_key): added
+
+       * sasldb/sasldb.h: New key list access API, added  parameter to
+               sasl_check_db (all callers updated, all callees updated)
+       * sasldb/db_berkeley.c: Implement key list access API
+       * sasldb/db_gdbm.c: Implement key list access API
+       * sasldb/db_ndbm.c: Implement key list access API
+       * sasldb/db_none.c: Implement key list access API
+
+       * utils/sasldblistuser.c: Use libsasldb instead of internal
+               functions.
+       
+       * utils/saslpasswd.c: No longer have separate global_utils,
+               call sasl_dispose and sasl_done
+
+       * acconfig.h: check for inttypes.h
+       * configure.in: check for inttypes.h
+       * plugins/plugin_common.c: include, if necessary, inttypes.h,
+               reference uint32_t instead of u_int32_t
+
+2001-07-25  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * lib/saslint.h: changed "sasldb" verifier to "auxprop"
+       * lib/server.c: changed "sasldb" verifier to "auxprop"
+       * lib/checkpw.c: changed "sasldb" verifier to "auxprop"
+       * utils/testsuite.c: changed "sasldb" verifier to "auxprop"
+       * doc/options.html: changed "sasldb" verifier to "auxprop"
+
+       * README: updated upgrade information
+
+       * utils/Makefile.am (CLEANFILES): added
+
+       * sasldb/allockey.c (alloc_key): single place for alloc_key()
+         Removed alloc_key from other source files.
+       * sasldb/sasldb.h: added declaration of alloc_key()     
+
+       * configure.in: added checks for db-3.3 and db3.3
+
+       * plugins/digestmd5.c (get_realm): now error on empty user_realm
+
+       * plugins/cram.c (client_required_prompts): removed redundant
+         required_prompts
+
+       * plugins/plain.c (client_continue_step): server-send-last error
+
+       * utils/testsuite.c (main): detailed client-send-first,
+               server-send-last checking
+       
+2001-07-24  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * plugins/sasldb.c: Cleaned up calls into the glue code
+
+       * java/Test/*: Cleaned up java test utilities
+       
+       * configure.in: Minor GSSAPI configure changes
+
+       * utils/saslpasswd.c: Clarfied -d option for saslpasswd
+       * utils/saslpasswd.8: Clarfied -d option for saslpasswd
+       
+       * doc/plugprog.html: Added plugin programmer's guide
+       * doc/index.html: linked to plugin programmer's guide
+       
+        * configure.in: corrected configure checking of Berkeley DB
+          (from Scot W. Hetzel <scot@genroco.com>)
+
+       * configure.in: corrected checking for libcom_err
+         (from Scot W. Hetzel <scot@genroco.com>)
+
+2001-07-23  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * configure.in: Added check for db3/db.h
+
+       * plugins/kerberos4.c Added mech_avail (checks for IP info)
+       
+       * lib/common.c: Fixed setting of serverFQDN in _sasl_conn_init
+       
+       * lib/server.c: Fully Implemented mech_avail calls in glue code
+       
+       * lib/server.c: Fixed allocation/destruction of sasl_conn_t's
+       * lib/client.c: Fixed allocation/destruction of sasl_conn_t's
+       * lib/common.c: Rely on earlier initialization in server.c and client.c
+
+       * doc/options.html: added
+
+       * ChangeLog: back to standard format
+       
+2001-07-20  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Can now deal with variable client-first mechs such as
+         DIGEST-MD5, though this interface is subject to change
+       * Modified parseuser to deal better with default realms
+       * Simplified realm handling in DIGEST-MD5 (getrealm callback
+         is no longer required).
+       * Cleaned up some memory management issues in DIGEST-MD5
+
+2001-07-19  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Fixed prototype of sasl_getpath_t to be in conformance with
+         memory allocation rules
+       * Fixed up samples directory
+       * Try to dlopen using information in .la file if available
+         (based on patch from
+          Stoned Elipot <Stoned.Elipot@script.jussieu.fr>)
+       * Resolution of most of the server-send-first and client-send-last
+         issues (using mechanism feature flags)
+
+2001-07-18  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Updated config.guess and config.sub
+       * Better underscore checking for dlsym
+       * Resolved possible global_utils namespace collision
+       * Updated sasldb library to be expandable to multiple properties
+         if the need arises in the future.
+       * IPv6 support from Hajimu UMEMOTO <ume@mahoroba.org>
+
+2001-07-17  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Extricated sasldb support to an auxprop plugin only.
+         sasldb modifications can now only be done through the saslpasswd
+         interface.
+
+2001-07-13  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Fixed buffer overrun problem in sasldb auxprop plugin
+       * Removed severe memory leak from testsuite
+       * Version 2.0.2-ALPHA Released
+
+2001-07-11  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * error reporting in KERBEROS_V4 plugin
+       * vague handling of SASL_AUTHSOURCE for getprop
+       * random misc error reporting bugs
+       * basic error messages for GSSAPI plugin
+
+2001-07-10  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * added client-send-first logic in glue code
+       * removed some client-send-first logic in mechanisms
+       * removed IPv4 specifics from sasl_conn_t
+       * Much gluecode error revamping (store the error code
+         in sasl_conn_t)
+
+2001-07-09  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Removed dependency on "name" in canonuser plugin structure
+       * Update configure.in from a new configure.scan
+       * Update copyright info in man pages, finished all API man pages
+       * Added auxprop tests to testsuite
+       * Added userdb callback support
+
+2001-07-09  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * First attempt at making the java code work again
+       * Minor memory and byte order bugfixes
+       * Added testing support for dmalloc (--with-dmalloc)
+
+2001-07-06  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Loading of auxprop and canonuser plugins from DSOs
+         (This still sucks performance wise, and will be fixed soon)
+       * Fixed some lack of indirection in the plugins
+       * Reverted to the v1 entry points for the plugins
+       * Cleaned up a good deal of the library loading code so it
+         now only gets called from the sasl_*_init functions, and
+         all the cleanup happens in the common sasl_done function
+       * Added SASL_IPREMOTEPORT and SASL_IPLOCALPORT to setprop,
+         and now _sasl_conn_init calls it to do the same work.
+
+2001-07-05  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Working libsfsasl and smtptest program (--with-sfio)
+       * Fixed sasldblistusers (atleast for Berkeley DB)
+       * seterror() calls in ANONYMOUS, CRAM, PLAIN and LOGIN
+       * Some new manpages
+
+2001-07-03  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Static library compilation now optional (--with-staticsasl)
+         Note that this is different from --enable-static, which causes
+         libtool to build static versions of everything is is almost
+         certainly NOT what you want.
+       * Removed all references to the ancient NANA code.
+       * Updated some documentation.
+
+2001-07-02  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Improved allocation efficiency of KERBEROS_V4, DIGEST-MD5,
+         and GSSAPI security layers.
+       * Fixed a decode bug in DIGEST-MD5 (and testsuite improvements to
+         help find similar ones)
+       * Fixed a number of solaris compiler warnings
+       * Static Library Build Support
+
+2001-06-30  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Cleanup of some man pages (added sasl_errors.3)
+
+2001-06-29  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Cleanup of APOP Code + new man page (Ken Murchison <ken@oceana.com>)
+       * Cleanup of comments in some files (Ken Murchison <ken@oceana.com>)
+       * Fixed some compiler errors on Solaris using /opt/SUNWspro/bin/cc
+         (Reported by Mei-Hui Su <mei@ISI.EDU>
+
+2001-06-28  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Improved memory allocation in default sasl_decode handler
+       * Added ability to disable sasl_checkapop (--disable-checkapop)
+       * Re-initialized kerberos mutex to NULL after it was freed
+
+2001-06-28  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Fixed a severe bug in DIGEST-MD5 Plugin
+       * KERBEROS_V4 plugin now thread safe
+       * Version 2.0.1-ALPHA Released (due to DIGEST-MD5 problem)
+
+2001-06-27  Rob Siemborski <rjs3+@andrew.cmu.edu>
+       * Version 2.0.0-ALPHA Released
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..54caf7c
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,229 @@
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/INSTALL.TXT b/INSTALL.TXT
new file mode 100644 (file)
index 0000000..bc759c1
--- /dev/null
@@ -0,0 +1 @@
+For installation instructions, see doc/install.html.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..d6005fb
--- /dev/null
@@ -0,0 +1,106 @@
+AUTOMAKE_OPTIONS = 1.7
+# Top-level Makefile.am for SASL
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+if SASLAUTHD
+SAD = saslauthd
+else
+SAD =
+endif
+if PWCHECK
+PWC = pwcheck
+else
+PWC = 
+endif
+if SAMPLE
+SAM = sample
+else
+SAM =
+endif
+if JAVA
+JAV = java
+else
+JAV =
+endif
+if MACOSX
+INSTALLOSX = install-exec-local-osx
+else 
+INSTALLOSX = 
+endif
+
+SUBDIRS=include sasldb plugins lib utils doc man $(PWC) $(SAM) $(JAV) $(SAD)
+EXTRA_DIST=config cmulocal win32 mac dlcompat-20010505 NTMakefile INSTALL.TXT
+
+dist-hook:
+       @find $(distdir) -exec chmod o+w {} ';'
+       @find $(distdir) -name CVS -print | xargs -t rm -rf
+       (cd $(distdir)/plugins && sh makeinit.sh)
+
+framedir = /Library/Frameworks/SASL2.framework
+install-exec-local: $(INSTALLOSX)
+       @if test "$(plugindir)" != "$(prefix)/lib/sasl2"; then \
+         echo "********************************************************"; \
+         echo "* WARNING:"; \
+         echo "* Plugins are being installed into $(prefix)/lib/sasl2,"; \
+         echo "* but the library will look for them in $(plugindir)."; \
+         echo "* You need to make sure that the plugins will eventually"; \
+         echo "* be in $(plugindir) -- the easiest way is to make a"; \
+         echo "* symbolic link from $(plugindir) to $(prefix)/lib/sasl2,"; \
+         echo "* but this may not be appropriate for your site, so this"; \
+         echo "* installation procedure won't do it for you."; \
+         echo "*"; \
+          echo "* If you don't want to do this for some reason, you can"; \
+          echo "* set the location where the library will look for plugins"; \
+         echo "* by setting the environment variable SASL_PATH to the path"; \
+         echo "* the library should use."; \
+         echo "********************************************************"; \
+       fi
+install-exec-local-osx:
+       $(mkinstalldirs) $(framedir)/Versions/A/Headers
+       $(mkinstalldirs) $(framedir)/Versions/A/Resources
+       cd $(framedir)/Versions ; ln -fs A Current
+       cd $(framedir) ; ln -fs Versions/A/Headers .
+       cd $(framedir) ; ln -fs Versions/A/Resources .
+       $(INSTALL_DATA) $(srcdir)/config/Info.plist $(framedir)/Versions/A/Resources
+
diff --git a/Makefile.in b/Makefile.in
new file mode 100644 (file)
index 0000000..fb75d8c
--- /dev/null
@@ -0,0 +1,701 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+AUTOMAKE_OPTIONS = 1.7
+@SASLAUTHD_FALSE@SAD = 
+
+# Top-level Makefile.am for SASL
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+@SASLAUTHD_TRUE@SAD = saslauthd
+@PWCHECK_TRUE@PWC = pwcheck
+@PWCHECK_FALSE@PWC = 
+@SAMPLE_FALSE@SAM = 
+@SAMPLE_TRUE@SAM = sample
+@JAVA_FALSE@JAV = 
+@JAVA_TRUE@JAV = java
+@MACOSX_FALSE@INSTALLOSX = 
+@MACOSX_TRUE@INSTALLOSX = install-exec-local-osx
+
+SUBDIRS = include sasldb plugins lib utils doc man $(PWC) $(SAM) $(JAV) $(SAD)
+EXTRA_DIST = config cmulocal win32 mac dlcompat-20010505 NTMakefile INSTALL.TXT
+
+framedir = /Library/Frameworks/SASL2.framework
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+       ps-recursive install-info-recursive uninstall-info-recursive \
+       all-recursive install-data-recursive install-exec-recursive \
+       installdirs-recursive install-recursive uninstall-recursive \
+       check-recursive installcheck-recursive
+DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \
+       COPYING ChangeLog INSTALL Makefile.am NEWS aclocal.m4 \
+       config.h.in config/config.guess config/config.sub \
+       config/depcomp config/install-sh config/ltconfig \
+       config/ltmain.sh config/missing config/mkinstalldirs configure \
+       configure.in
+DIST_SUBDIRS = include sasldb plugins lib utils doc man pwcheck sample \
+       java saslauthd
+all: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
+
+$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure:  $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+$(ACLOCAL_M4):  configure.in 
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+       @if test ! -f $@; then \
+         rm -f stamp-h1; \
+         $(MAKE) stamp-h1; \
+       else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+       @rm -f stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status config.h
+
+$(srcdir)/config.h.in:  $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       touch $(srcdir)/config.h.in
+
+distclean-hdr:
+       -rm -f config.h stamp-h1
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if (etags --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+       else \
+         include_option=--include; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = .
+distdir = $(PACKAGE)-$(VERSION)
+
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+
+distdir: $(DISTFILES)
+       $(am__remove_distdir)
+       mkdir $(distdir)
+       $(mkinstalldirs) $(distdir)/config
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-hook
+       -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+         ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+       || chmod -R a+r $(distdir)
+dist-gzip: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+dist dist-all: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       $(am__remove_distdir)
+       GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
+       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       mkdir $(distdir)/_build
+       mkdir $(distdir)/_inst
+       chmod a-w $(distdir)
+       dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+         && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+         && cd $(distdir)/_build \
+         && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+           $(DISTCHECK_CONFIGURE_FLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+         && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+               distuninstallcheck \
+         && chmod -R a-w "$$dc_install_base" \
+         && ({ \
+              (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+                   distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+             } || { rm -rf "$$dc_destdir"; exit 1; }) \
+         && rm -rf "$$dc_destdir" \
+         && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
+         && rm -f $(distdir).tar.gz \
+         && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+       $(am__remove_distdir)
+       @echo "$(distdir).tar.gz is ready for distribution" | \
+         sed 'h;s/./=/g;p;x;p;x'
+distuninstallcheck:
+       @cd $(distuninstallcheck_dir) \
+       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+          || { echo "ERROR: files left after uninstall:" ; \
+               if test -n "$(DESTDIR)"; then \
+                 echo "  (check DESTDIR support)"; \
+               fi ; \
+               $(distuninstallcheck_listfiles) ; \
+               exit 1; } >&2
+distcleancheck: distclean
+       @if test '$(srcdir)' = . ; then \
+         echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+         exit 1 ; \
+       fi
+       @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+         || { echo "ERROR: files left in build directory after distclean:" ; \
+              $(distcleancheck_listfiles) ; \
+              exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-exec-local
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+       clean-generic clean-libtool clean-recursive ctags \
+       ctags-recursive dist dist-all dist-gzip distcheck distclean \
+       distclean-generic distclean-hdr distclean-libtool \
+       distclean-recursive distclean-tags distcleancheck distdir \
+       distuninstallcheck dvi dvi-am dvi-recursive info info-am \
+       info-recursive install install-am install-data install-data-am \
+       install-data-recursive install-exec install-exec-am \
+       install-exec-local install-exec-recursive install-info \
+       install-info-am install-info-recursive install-man \
+       install-recursive install-strip installcheck installcheck-am \
+       installdirs installdirs-am installdirs-recursive \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
+       pdf-recursive ps ps-am ps-recursive tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am \
+       uninstall-info-recursive uninstall-recursive
+
+
+dist-hook:
+       @find $(distdir) -exec chmod o+w {} ';'
+       @find $(distdir) -name CVS -print | xargs -t rm -rf
+       (cd $(distdir)/plugins && sh makeinit.sh)
+install-exec-local: $(INSTALLOSX)
+       @if test "$(plugindir)" != "$(prefix)/lib/sasl2"; then \
+         echo "********************************************************"; \
+         echo "* WARNING:"; \
+         echo "* Plugins are being installed into $(prefix)/lib/sasl2,"; \
+         echo "* but the library will look for them in $(plugindir)."; \
+         echo "* You need to make sure that the plugins will eventually"; \
+         echo "* be in $(plugindir) -- the easiest way is to make a"; \
+         echo "* symbolic link from $(plugindir) to $(prefix)/lib/sasl2,"; \
+         echo "* but this may not be appropriate for your site, so this"; \
+         echo "* installation procedure won't do it for you."; \
+         echo "*"; \
+          echo "* If you don't want to do this for some reason, you can"; \
+          echo "* set the location where the library will look for plugins"; \
+         echo "* by setting the environment variable SASL_PATH to the path"; \
+         echo "* the library should use."; \
+         echo "********************************************************"; \
+       fi
+install-exec-local-osx:
+       $(mkinstalldirs) $(framedir)/Versions/A/Headers
+       $(mkinstalldirs) $(framedir)/Versions/A/Resources
+       cd $(framedir)/Versions ; ln -fs A Current
+       cd $(framedir) ; ln -fs Versions/A/Headers .
+       cd $(framedir) ; ln -fs Versions/A/Resources .
+       $(INSTALL_DATA) $(srcdir)/config/Info.plist $(framedir)/Versions/A/Resources
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..0391ae1
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,329 @@
+New in 2.1.23
+-------------
+* Fixed CERT VU#238019 (make sure sasl_encode64() always NUL
+  terminates output or returns SASL_BUFOVER)
+
+New in 2.1.22
+-------------
+
+* Added support for spliting big data blocks (bigger than maxbuf)
+  into multiple SASL packets in sasl_encodev
+* Various sasl_decode64() fixes
+* Increase canonicalization buffer size to 1024 bytes
+* Call do_authorization() after successful APOP authentication
+* Allow for configuration file location to be configurable independently
+  of plugin location (bug # 2795)
+* Added sasl_set_path function, which provides a more convenient way
+  of setting plugin and config paths. Changed the default
+  sasl_getpath_t/sasl_getconfpath_t callbacks to calculate
+  the value only once and cache it for later use.
+* Fixed load_config to search for the config file in all directories
+  (bug # 2796). Changed the default search path to be
+  /usr/lib/sasl2:/etc/sasl2
+* Don't ignore log_level configuration option in default UNIX syslog
+  logging callback
+* (Windows) Minor IPv6 related changes in Makefiles for Visual Studio 6
+* (Windows) Fixed bug of not setting the CODEGEN (code generation option)
+  nmake option if STATIC nmake option is set.
+* Several fixed to DIGEST-MD5 plugin:
+  - Enable RC4 cipher in Windows build of DIGEST-MD5
+  - Server side: handle missing realm option as if realm="" was sent
+  - Fix DIGEST-MD5 to properly advertise maxssf when both DES and RC4
+    are disabled
+  - Check that DIGEST-MD5 SASL packet are no shorter than 16 bytes
+* Several changes/fixed to SASLDB plugin:
+  - Prevent spurious SASL_NOUSER errors
+  - Added ability to keep BerkleyDB handle open between operations
+    (for performance reason). New behavior can be enabled
+    with --enable-keep-db-open.
+* Better error checking in SQL (MySQL) auxprop plugin code
+* Added support for HTTP POST password validation in saslauthd
+* Added new application ("pluginviewer") that helps report information
+  about installed plugins
+* Allow for building with OpenSSL 0.9.8
+* Allow for building with OpenLDAP 2.3+
+* Several quoting fixes to configure script
+* A large number of other minor bugfixes and cleanups
+
+New in 2.1.21
+-------------
+* Fixes DIGEST-MD5 server side segfault caused by the client not sending
+  any realms
+* Minor Other bugfixes
+
+New in 2.1.20
+-------------
+* Fixes to cram plugin to avoid attempting to canonify uninitialized data.
+* NTLM portability fixes.
+* Avoid potential attack using SASL_PATH when sasl is used in a setuid 
+  environment.
+* A trivial number of small bugfixes.
+
+New in 2.1.19
+-------------
+* Fixes to saslauthd to allow better integration with realms (-r flag to
+  saslauthd, %R token in LDAP module)
+* Support for forwarding of GSSAPI credentials
+* SQLite support for the SQL plugin
+* A nontrivial number of small bugfixes.
+
+New in 2.1.18
+-------------
+* saslauthd/LDAP no longer tagged "experimental"
+* Add group membership check to saslauthd/LDAP
+* Fix Solaris 9 "NI_WITHSCOPEID" issue
+* Fix missing "getaddrinfo.c" and other distribution problems
+* Significant Windows enhancements
+* A large number of other minor bugfixes and cleanups
+
+New in 2.1.17
+-------------
+* Allow selection of GSSAPI implementation explicitly (--with-gss_impl)
+* Other GSSAPI detection improvements
+* Now correctly do authorizaton callback in sasl_checkpass()
+* Disable KERBEROS_V4 by default
+* Continued Win32/Win64 Improvements
+* Minor Other bugfixes
+
+New in 2.1.16-BETA
+------------------
+* Significantly improved Win32 support
+* Writable auxprop support
+* Expanded SQL support (including postgres)
+* Significantly improved documentation
+* Improved realm/username handling with saslauthd
+* Support for modern automake and autoconf
+
+New in 2.1.15
+-------------
+* Fix a number of build issues
+* Add a doc/components.html that hopefully describes how things
+  interact better.
+
+New in 2.1.14
+-------------
+* OS X 10.2 support
+* Support for the Sun SEAM GSSAPI implementation
+* Support for MySQL 4
+* A number of build fixes
+* Other minor bugfixes
+
+New in 2.1.13
+-------------
+* Add a configure option to allow specification of what /dev/random to use.
+* Addition of a saslauthd credential cache feature (-c option).
+* Unification of the saslauthd ipc method code.
+* Fix a number of autoconf issues.
+* A significant number of fixes throughout the library from Sun Microsystems.
+* Other minor bugfixes.
+
+New in 2.1.12
+-------------
+* Distribute in Solaris tar (not GNU tar format)
+* Fix a number of build/configure related issues.
+
+New in 2.1.11
+-------------
+* Add the fastbind auth method to the saslauthd LDAP module.
+* Fix a potential memory leak in the doors version of saslauthd.
+* NTLM now only requires one of LM or NT, not both.
+* Fix a variety of Berkeley DB, LDAP, OpenSSL, and other build issues.
+* Win32 support compiles, but no documentation as of yet.
+
+New in 2.1.10
+-------------
+* Further DIGEST-MD5 DES interoperability fixes.  Now works against Active
+  Directory.
+* Fix some potential buffer overflows.
+* Misc. cleanups in the saslauthd LDAP module
+* Fix security properties of NTLM and EXTERNAL
+
+New in 2.1.9
+------------
+* Include missing lib/staticopen.h file.
+
+New in 2.1.8
+------------
+* Support for the NTLM mechanism (Ken Murchison <ken@oceana.com>)
+* Support libtool --enable-shared and --enable-static
+  (Howard Chu <hyc@highlandsun.com>)
+* OS/390 Support (Howard Chu <hyc@highlandsun.com>)
+* Berkeley DB 4.1 Support (Mika Iisakkila <mika.iisakkila@pingrid.fi>)
+* Documentation fixes
+* The usual round of assorted other minor bugfixes.
+
+New in 2.1.7
+------------
+* Add SASL_AUTHUSER as a parameter to sasl_getprop
+* Allow applications to require proxy-capable mechanisms (SASL_NEED_PROXY)
+* Performance improvements in our treatment of /dev/random
+* Removal of buggy DIGEST-MD5 reauth support.
+* Documentation fixes
+* Assorted other minor bugfixes.
+
+New in 2.1.6
+------------
+* Security fix for the CRAM-MD5 plugin to check the full length of the
+  digest string.
+* Return of the Experimental LDAP saslauthd module.
+* Addition of Experimental MySQL auxprop plugin.
+* Can now select multiple auxprop plugins (and a priority ordering)
+* Mechanism selection now includes number of security flags
+* Mac OS X 10.1 Fixes
+* Misc other minor bugfixes.
+
+New in 2.1.5
+------------
+* Remove LDAP support due to copyright concerns.
+* Minor bugfixes.
+
+New in 2.1.4
+------------
+* Enhancements and cleanup to the experimental LDAP saslauthd module
+  (Igor Brezac <igor@ipass.net>)
+* Addition of a new sasl_version() API
+* Misc. Bugfixes
+
+New in 2.1.3-BETA
+-----------------
+* Significant amount of plugin cleanup / standardization.  A good deal of code
+  is now shared between them. (mostly due to Ken Murchison <ken@oceana.com>)
+* DIGEST-MD5 now supports reauthentication.  Also has a fix for DES
+  interoperability.
+* saslauthd now supports the Solaris "doors" IPC method
+  (--with-ipctype=doors)
+* Significant GSSAPI fixes (mostly due to Howard Chu <hyc@highlandsun.com>)
+* Auxprop interface now correctly deals with the * prefix indicating 
+  authid vs. authzid.  (May break some incompatible auxprop plugins).
+* We now allow multiple pwcheck_method(s).  Also you can restrict auxprop
+  plugins to the use of a single plugin.
+* Added an experimental saslauthd LDAP module (Igor Brezac <igor@ipass.net>)
+* Removed check for db3/db.h
+* Misc. documentation updates.  (Marshall Rose, and others)
+* Other misc. bugfixes.
+
+New in 2.1.2
+------------
+* Mostly a minor-bugfix release
+* Improved documentation / cleanup of old references to obsolete
+  pwcheck_methods
+* Better error reporting for auxprop password verifiers
+
+New in 2.1.1
+------------
+* Many minor bugfixes throughout.
+* Improvements to OTP and SRP mechanisms (now compliant with
+  draft-burdis-cat-srp-sasl-06.txt)
+* API additions including sasl_global_listmech, and a cleaner handling of
+  client-first and server-last semantics (no application level changes)
+* Minor documentation improvements
+
+New in 2.1.0
+------------
+* The Cyrus SASL library is now considered stable.  It is still not backwards
+  compatible with applications that require SASLv1.
+* Minor API changes occured, namely the canon_user callback interface.
+* saslauthd now preforks a number of processes to handle connections
+* Many bugfixes through the entire library.
+
+New in 2.0.5-BETA
+-----------------
+* THIS IS A BETA-QUALITY RELEASE THAT IS NOT INTENDED FOR PRODUCTION USE.
+  IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
+* Improved performance of security layers in KERBEROS_V4, GSSAPI, and DIGEST.
+* This release includes an OTP plugin that requires libopie.
+* SRP plugin now in alpha stage.
+* Includes many significant bugfixes throughout the library.
+
+New in 2.0.4-BETA
+-----------------
+* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY
+  DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
+  IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
+* This release now includes Mac OS 9 and Mac OS X support.
+* Significant new features include 
+  * DES and 3DES Encryption should now be working for DIGEST-MD5
+  * Improved configuration system
+  * Improved documentation (now includes plugin writers guide)
+  * Many other bugfixes (see ChangeLog)
+
+New in 2.0.3-BETA
+-----------------
+* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY
+  DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.
+  IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API.
+* This library should be fairly close to the core features that will be
+  released in a final version of Cyrus SASLv2.  It very likely has bugs.
+* Major new features included in this release:
+  - The glue code now correctly handles client-send-first and server-send-last
+    situations based on what the protocol and mechanism each support.
+  - The sasldb code has been extracted from the main library and now resides
+    in a separate libsasldb.la that is available at build time.
+  - SASLdb now supports multiple auxiliary properties, though as distributed
+    only userPassword is implemented and used.
+  - Much improved configure checking for various items, including
+    Berkeley DB, Kerberos, and GSSAPI.
+  - Better (more standard) handling of realms in DIGEST-MD5.
+  - A new Plugin Programmer's guide.
+  - IPv6 support.
+  - Error reporting now works in the GSSAPI plugin.
+* See the ChangeLog for a more detailed list of changes.
+
+New in 2.0.2-ALPHA
+------------------
+* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS
+  WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.  
+* This release is intended to show developers that use Cyrus SASL what
+  direction we are planning on taking the library so that they can make
+  plans to migrate their applications accordingly
+* Major new features included in this release:
+  - Ability to compile a static library including all mechanisms.  This
+    means lower memory usage and faster mechanism loading time, but
+    is not for everyone (or even many people). See doc/advanced.html,
+    as well as the '--with-staticsasl' configure flag.
+  - Man pages should now all be present and are close to being correct.
+  - Can now build libsfsasl and the smtptest program (using the --with-sfio
+    configure flag)
+  - Reverted to the v1 entry points for mechanisms, to allow v1 mechanisms
+    to fail loading cleanly.
+  - Auxprop and canon_user plugins can now load from DSOs
+  - Java code now compiles (but is not well tested, or up to date with the
+    current Java API draft)
+  - Error handling and use of sasl_errdetail has been fleshed out and
+    should now work in most cases.
+* Still Coming:
+  - Cleanup of the client-send-first and server-send-last situation
+  - Error reporting in GSSAPI plugin
+  - Move the sasldb code out of the main library and into plugins and
+    utilities only.
+
+New in 2.0.0-ALPHA
+------------------
+* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS
+  WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY.  
+* This release is intended to show developers that use Cyrus SASL what
+  direction we are planning on taking the library so that they can make
+  plans to migrate their applications accordingly
+* This release implements the SASLv2 API.
+  Some of the major improvements in the API include:
+  - Memory management is now sane (whoever allocates the memory is responsible
+    for freeing it)
+  - Auxiliary Property plugin support (ability to interface with directory
+    services as part of authentication)
+  - Username canonification plugin support
+  - Improved error reporting (not fully implemented in this release)
+  - Database support has been simplified.  We now maintain only a single
+    store of plaintext passwords that is shared by all supplied plugins
+    (using the auxiliary property interface).
+  The new API is more fully documented in the header files sasl.h, saslplug.h
+  saslutil.h, and prop.h.  The man pages, programmers guide, and system
+  administrators guide have also been rewritten to deal with the new API.
+* There is still a good amount of work to be done, and as this code is alpha
+  quality, it has bugs, known and unknown.  Please either use our bugzilla at
+  http://bugzilla.andrew.cmu.edu, or email cyrus-bugs@andrew.cmu.edu with
+  questions, comments, or bug reports.
+  - Most notably, the Java bindings have not been converted to work with
+    the new API, and thus will not compile successfully.
+  - The current development branch with this source is in our
+    cvs repository as the "sasl-v2-rjs3" branch of the "sasl" collection.
+    (see http://asg.web.cmu.edu/cyrus/download/anoncvs.html for more info)
diff --git a/NTMakefile b/NTMakefile
new file mode 100644 (file)
index 0000000..d3aac8a
--- /dev/null
@@ -0,0 +1,60 @@
+# Top-level NTMakefile for SASL
+# Alexey Melnikov
+#
+################################################################
+# Copyright (c) 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.
+#
+################################################################
+
+!INCLUDE .\win32\common.mak
+
+SUBDIRS=lib plugins utils sample
+INCSUBDIRS=include sasldb win32\include
+DOCSUBDIRS=doc
+
+all-first: all
+
+#nmake doesn't have "for" construct?
+#front ! will call the command replacing $? with a value from dependency list
+all clean: $(SUBDIRS)
+       !cd $? && $(MAKE) /f NTMakefile /$(MAKEFLAGS) VERBOSE=0 $@
+
+install: $(INCSUBDIRS) $(SUBDIRS) $(DOCSUBDIRS)
+       !cd $? && $(MAKE) /f NTMakefile /$(MAKEFLAGS) prefix=$(prefix) $@
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..3bd8eec
--- /dev/null
+++ b/README
@@ -0,0 +1,23 @@
+$Id: README,v 1.32 2002/04/06 03:44:52 rjs3 Exp $
+
+This is the Cyrus SASL API implentation. It can be used on the client
+or server side to provide authentication and authorization services.
+See RFC 2222 for more information.
+
+The latest version is available at:
+ftp://ftp.andrew.cmu.edu/pub/cyrus-mail
+
+There's a mailing list for Cyrus SASL.  Subscribe by sending a message
+to majordomo@lists.andrew.cmu.edu with the body "subscribe
+cyrus-sasl". The mailing list is available via anonymous IMAP at
+imap://cyrus.andrew.cmu.edu/archive.cyrus-sasl or via the web at
+http://asg.web.cmu.edu/archive/mailbox.php3?mailbox=archive.cyrus-sasl.
+
+If you are looking to port SASLv1 applications to SASLv2, please see
+doc/appconvert.html
+
+Bugs can be searched/reported at: http://bugzilla.andrew.cmu.edu
+
+DOCUMENTATION
+--------------
+Please see doc/index.html for the remainder of the documentation.
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644 (file)
index 0000000..f2ca0c4
--- /dev/null
@@ -0,0 +1,3469 @@
+# generated automatically by aclocal 1.7.9 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# Do all the work for Automake.                            -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 10
+
+AC_PREREQ([2.54])
+
+# Autoconf 2.50 wants to disallow AM_ names.  We explicitly allow
+# the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright 2002  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+        [AM_AUTOMAKE_VERSION([1.7.9])])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+
+# Copyright 2001, 2002  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+#  -*- Autoconf -*-
+
+
+# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+# Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_AUX_DIR_EXPAND], [
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+#                                                          -*- Autoconf -*-
+# Copyright (C) 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# serial 5                                             -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      : > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking Speeds up one-time builds
+  --enable-dependency-tracking  Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking.   -*- Autoconf -*-
+
+# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n -e '/^U = / s///p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n -e '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Check to see how 'make' treats includes.     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# AM_CONDITIONAL                                              -*- Autoconf -*-
+
+# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 5
+
+AC_PREREQ(2.52)
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+        [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+dnl init_automake.m4--cmulocal automake setup macro
+dnl Rob Earhart
+dnl $Id: init_automake.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+
+AC_DEFUN([CMU_INIT_AUTOMAKE], [
+       AC_REQUIRE([AM_INIT_AUTOMAKE])
+       ACLOCAL="$ACLOCAL -I \$(top_srcdir)/cmulocal"
+       ])
+
+dnl
+dnl $Id: c-attribute.m4,v 1.3 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN([CMU_C___ATTRIBUTE__], [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+  exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+  AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
+
+dnl
+dnl Additional macros for configure.in packaged up for easier theft.
+dnl $Id: cyrus.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+dnl tjs@andrew.cmu.edu 6-may-1998
+dnl
+
+dnl It would be good if ANDREW_ADD_LIBPATH could detect if something was
+dnl already there and not redundantly add it if it is.
+
+dnl add -L(arg), and possibly (runpath switch)(arg), to LDFLAGS
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH], [
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$1 ${LDFLAGS}"
+  else
+       LDFLAGS="-L$1 $andrew_runpath_switch$1 ${LDFLAGS}"
+  fi
+])
+
+dnl add -L(1st arg), and possibly (runpath switch)(1st arg), to (2nd arg)
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH_TO], [
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       $2="-L$1 ${$2}"
+  else
+       $2="-L$1 ${$2} $andrew_runpath_switch$1"
+  fi
+])
+
+dnl runpath initialization
+AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [
+   # CMU GUESS RUNPATH SWITCH
+  AC_CACHE_CHECK(for runpath switch, andrew_runpath_switch, [
+    # first, try -R
+    SAVE_LDFLAGS="${LDFLAGS}"
+    LDFLAGS="-R /usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-R"], [
+       LDFLAGS="-Wl,-rpath,/usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-Wl,-rpath,"],
+    [andrew_runpath_switch="none"])
+    ])
+  LDFLAGS="${SAVE_LDFLAGS}"
+  ])])
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_SHARED], [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_STATIC], [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL], [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN([AM_PROG_LIBTOOL], [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN([AM_ENABLE_SHARED], [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN([AM_ENABLE_STATIC], [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN([AM_DISABLE_SHARED], [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN([AM_DISABLE_STATIC], [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN([AM_PROG_LD], [indir([AC_PROG_LD])])dnl
+AC_DEFUN([AM_PROG_NM], [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+dnl bsd_sockets.m4--which socket libraries do we need? 
+dnl Derrick Brashear
+dnl from Zephyr
+dnl $Id: bsd_sockets.m4,v 1.10 2005/04/26 19:14:07 shadow Exp $
+
+dnl Hacked on by Rob Earhart to not just toss stuff in LIBS
+dnl It now puts everything required for sockets into LIB_SOCKET
+
+AC_DEFUN([CMU_SOCKETS], [
+       save_LIBS="$LIBS"
+       LIB_SOCKET=""
+       AC_CHECK_FUNC(connect, :,
+               AC_CHECK_LIB(nsl, gethostbyname,
+                            LIB_SOCKET="-lnsl $LIB_SOCKET")
+               AC_CHECK_LIB(socket, connect,
+                            LIB_SOCKET="-lsocket $LIB_SOCKET")
+       )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNC(res_search, :,
+               LIBS="-lresolv $LIB_SOCKET $save_LIBS"
+               AC_TRY_LINK([[
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>]],[[
+const char host[12]="openafs.org";
+u_char ans[1024];
+res_search( host, C_IN, T_MX, (u_char *)&ans, sizeof(ans));
+return 0;
+]], LIB_SOCKET="-lresolv $LIB_SOCKET")
+        )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNCS(dn_expand dns_lookup)
+       LIBS="$save_LIBS"
+       AC_SUBST(LIB_SOCKET)
+       ])
+
+dnl Functions to check what database to use for libsasldb
+
+dnl Berkeley DB specific checks first..
+
+dnl Figure out what database type we're using
+AC_DEFUN([SASL_DB_CHECK], [
+cmu_save_LIBS="$LIBS"
+AC_ARG_WITH(dblib, [  --with-dblib=DBLIB      set the DB library to use [berkeley] ],
+  dblib=$withval,
+  dblib=auto_detect)
+
+CYRUS_BERKELEY_DB_OPTS()
+
+SASL_DB_LIB=""
+
+case "$dblib" in
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named.  arg.
+  berkeley)
+       CYRUS_BERKELEY_DB_CHK()
+       CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+       SASL_DB_INC=$BDB_INCADD
+       SASL_DB_LIB="${BDB_LIBADD}"
+       ;;
+  gdbm)
+       AC_ARG_WITH(gdbm,[  --with-gdbm=PATH        use gdbm from PATH],
+                    with_gdbm="${withval}")
+
+        case "$with_gdbm" in
+           ""|yes)
+               AC_CHECK_HEADER(gdbm.h, [
+                       AC_CHECK_LIB(gdbm, gdbm_open, SASL_DB_LIB="-lgdbm",
+                                           dblib="no")],
+                       dblib="no")
+               ;;
+           *)
+               if test -d $with_gdbm; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_gdbm}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_gdbm}/lib"
+                 SASL_DB_LIB="-lgdbm" 
+               else
+                 with_gdbm="no"
+               fi
+       esac
+       ;;
+  ndbm)
+       dnl We want to attempt to use -lndbm if we can, just in case
+       dnl there's some version of it installed and overriding libc
+       AC_CHECK_HEADER(ndbm.h, [
+                       AC_CHECK_LIB(ndbm, dbm_open, SASL_DB_LIB="-lndbm", [
+                               AC_CHECK_FUNC(dbm_open,,dblib="no")])],
+                               dblib="no")
+       ;;
+  auto_detect)
+        dnl How about berkeley db?
+       CYRUS_BERKELEY_DB_CHK()
+       if test "$dblib" = no; then
+         dnl How about ndbm?
+         AC_CHECK_HEADER(ndbm.h, [
+               AC_CHECK_LIB(ndbm, dbm_open,
+                            dblib="ndbm"; SASL_DB_LIB="-lndbm",
+                            dblib="weird")],
+                  dblib="no")
+         if test "$dblib" = "weird"; then
+           dnl Is ndbm in the standard library?
+            AC_CHECK_FUNC(dbm_open, dblib="ndbm", dblib="no")
+         fi
+
+         if test "$dblib" = no; then
+            dnl Can we use gdbm?
+           AC_CHECK_HEADER(gdbm.h, [
+               AC_CHECK_LIB(gdbm, gdbm_open, dblib="gdbm";
+                                            SASL_DB_LIB="-lgdbm", dblib="no")],
+                            dblib="no")
+         fi
+       else
+         dnl we took Berkeley
+         CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+         SASL_DB_INC=$BDB_INCADD
+          SASL_DB_LIB="${BDB_LIBADD}"
+       fi
+       ;;
+  none)
+       ;;
+  no)
+       ;;
+  *)
+       AC_MSG_WARN([Bad DB library implementation specified;])
+       AC_ERROR([Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"])
+       dblib=no
+       ;;
+esac
+LIBS="$cmu_save_LIBS"
+
+AC_MSG_CHECKING(DB library to use)
+AC_MSG_RESULT($dblib)
+
+SASL_DB_BACKEND="db_${dblib}.lo"
+SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
+SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_${dblib}.c ../sasldb/allockey.c"
+SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
+
+case "$dblib" in
+  gdbm) 
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_GDBM,[],[Use GDBM for SASLdb])
+    ;;
+  ndbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_NDBM,[],[Use NDBM for SASLdb])
+    ;;
+  berkeley)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_BERKELEYDB,[],[Use BerkeleyDB for SASLdb])
+    ;;
+  *)
+    AC_MSG_WARN([Disabling SASL authentication database support])
+    dnl note that we do not add libsasldb.la to SASL_MECHS, since it
+    dnl will just fail to load anyway.
+    SASL_DB_BACKEND="db_none.lo"
+    SASL_DB_BACKEND_STATIC="db_none.o"
+    SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_none.c"
+    SASL_DB_UTILS=""
+    SASL_DB_MANS=""
+    SASL_DB_LIB=""
+    ;;
+esac
+
+if test "$enable_static" = yes; then
+    if test "$dblib" != "none"; then
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sasldb.c $SASL_DB_BACKEND_STATIC_SRCS"
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS sasldb.o $SASL_DB_BACKEND_STATIC"
+      AC_DEFINE(STATIC_SASLDB,[],[Link SASLdb Staticly])
+    else
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS $SASL_DB_BACKEND_STATIC"
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS $SASL_DB_BACKEND_STATIC_SRCS"
+    fi
+fi
+
+AC_SUBST(SASL_DB_UTILS)
+AC_SUBST(SASL_DB_MANS)
+AC_SUBST(SASL_DB_BACKEND)
+AC_SUBST(SASL_DB_BACKEND_STATIC)
+AC_SUBST(SASL_DB_INC)
+AC_SUBST(SASL_DB_LIB)
+])
+
+dnl Figure out what database path we're using
+AC_DEFUN([SASL_DB_PATH_CHECK], [
+AC_ARG_WITH(dbpath, [  --with-dbpath=PATH      set the DB path to use [/etc/sasldb2] ],
+  dbpath=$withval,
+  dbpath=/etc/sasldb2)
+AC_MSG_CHECKING(DB path to use)
+AC_MSG_RESULT($dbpath)
+AC_DEFINE_UNQUOTED(SASL_DB_PATH, "$dbpath", [Path to default SASLdb database])])
+
+dnl $Id: berkdb.m4,v 1.20 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_DB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <db.h>],
+[DB *db;
+db_create(&db, NULL, 0);
+db->open(db, "foo.db", NULL, DB_UNKNOWN, DB_RDONLY, 0644);],
+ac_cv_found_db_inc=yes,
+ac_cv_found_db_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_DB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db headers in $i)
+      CMU_DB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, db)
+      if test "$ac_cv_found_db_inc" = "yes"; then
+        ac_cv_db_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for lib files
+#
+
+AC_DEFUN([CMU_DB3_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+  LIBS="$saved_LIBS -L$1 -ldb-3"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_3_lib=yes],
+ac_cv_found_db_3_lib=no)
+LIBS=$saved_LIBS
+])
+AC_DEFUN([CMU_DB4_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -ldb-4"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_4_lib=yes],
+ac_cv_found_db_4_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_DB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db libraries in $i)
+if test "$enable_db4" = "yes"; then
+      CMU_DB4_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-4])
+      ac_cv_found_db_lib=$ac_cv_found_db_4_lib
+else
+      CMU_DB3_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-3])
+      ac_cv_found_db_lib=$ac_cv_found_db_3_lib
+fi
+      if test "$ac_cv_found_db_lib" = "yes" ; then
+        ac_cv_db_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_USE_DB], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(db,
+       [  --with-db=PREFIX      Compile with db support],
+       [if test "X$with_db" = "X"; then
+               with_db=yes
+       fi])
+AC_ARG_WITH(db-lib,
+       [  --with-db-lib=dir     use db libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-lib])
+       fi])
+AC_ARG_WITH(db-include,
+       [  --with-db-include=dir use db headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-include])
+       fi])
+AC_ARG_ENABLE(db4,
+       [  --enable-db4          use db 4.x libraries])
+       
+       if test "X$with_db" != "X"; then
+         if test "$with_db" != "yes"; then
+           ac_cv_db_where_lib=$with_db/$CMU_LIB_SUBDIR
+           ac_cv_db_where_inc=$with_db/include
+         fi
+       fi
+
+       if test "X$with_db_lib" != "X"; then
+         ac_cv_db_where_lib=$with_db_lib
+       fi
+       if test "X$ac_cv_db_where_lib" = "X"; then
+         CMU_DB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_db_include" != "X"; then
+         ac_cv_db_where_inc=$with_db_include
+       fi
+       if test "X$ac_cv_db_where_inc" = "X"; then
+         CMU_DB_INC_WHERE(/usr/athena/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include db)
+       if test "X$ac_cv_db_where_lib" = "X" -o "X$ac_cv_db_where_inc" = "X"; then
+         ac_cv_found_db=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_db=yes
+         AC_MSG_RESULT(yes)
+         DB_INC_DIR=$ac_cv_db_where_inc
+         DB_LIB_DIR=$ac_cv_db_where_lib
+         DB_INC_FLAGS="-I${DB_INC_DIR}"
+          if test "$enable_db4" = "yes"; then
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-4"
+          else
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-3"
+          fi
+          dnl Do not force configure.in to put these in CFLAGS and LIBS unconditionally
+          dnl Allow makefile substitutions....
+          AC_SUBST(DB_INC_FLAGS)
+          AC_SUBST(DB_LIB_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${DB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${DB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${DB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
+
+
+dnl ---- CUT HERE ---
+
+dnl These are the Cyrus Berkeley DB macros.  In an ideal world these would be
+dnl identical to the above.
+
+dnl They are here so that they can be shared between Cyrus IMAPd
+dnl and Cyrus SASL with relative ease.
+
+dnl The big difference between this and the ones above is that we don't assume
+dnl that we know the name of the library, and we try a lot of permutations
+dnl instead.  We also assume that DB4 is acceptable.
+
+dnl When we're done, there will be a BDB_LIBADD and a BDB_INCADD which should
+dnl be used when necessary.  We should probably be smarter about our RPATH
+dnl handling.
+
+dnl Call these with BERKELEY_DB_CHK.
+
+dnl We will also set $dblib to "berkeley" if we are successful, "no" otherwise.
+
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named and where the db-3 header file is located.  arg.
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK_LIB],
+[
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, LDFLAGS)
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, BDB_LIBADD)
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           AC_TRY_LINK([#include <db.h>],
+           [db_create(NULL, NULL, 0);],
+           BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db,
+            dblib="no")
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           AC_TRY_LINK([#include <db.h>],
+           [db_open(NULL, 0, 0, 0, NULL, NULL, NULL);],
+           BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db,
+            dblib="no")
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_OPTS],
+[
+AC_ARG_WITH(bdb-libdir,
+       [  --with-bdb-libdir=DIR   Berkeley DB lib files are in DIR],
+       with_bdb_lib=$withval,
+       [ test "${with_bdb_lib+set}" = set || with_bdb_lib=none])
+AC_ARG_WITH(bdb-incdir,
+       [  --with-bdb-incdir=DIR   Berkeley DB include files are in DIR],
+       with_bdb_inc=$withval,
+       [ test "${with_bdb_inc+set}" = set || with_bdb_inc=none ])
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
+[
+       AC_REQUIRE([CYRUS_BERKELEY_DB_OPTS])
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+       dnl Note that FreeBSD puts it in a wierd place
+        dnl (but they should use with-bdb-incdir)
+        AC_CHECK_HEADER(db.h,
+                        [CYRUS_BERKELEY_DB_CHK_LIB()],
+                        dblib="no")
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+])
+
+dnl $Id: common.m4,v 1.13 2006/02/25 18:29:46 cg2v Exp $
+
+AC_DEFUN([CMU_TEST_LIBPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_lib, <<- *>>, <<__p>>))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/lib$2.a" -a \! -r "$1/lib$2.so" -a \! -r "$1/lib$2.sl" -a \! -r "$1/lib$2.dylib"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+AC_DEFUN([CMU_TEST_INCPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_inc, [ *], [_p]))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/$2.h"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+dnl CMU_CHECK_HEADER_NOCACHE(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([CMU_CHECK_HEADER_NOCACHE],
+[dnl Do the transliteration at runtime so arg 1 can be a shell variable.
+ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
+AC_MSG_CHECKING([for $1])
+AC_TRY_CPP([#include <$1>], eval "ac_cv_header_$ac_safe=yes",
+  eval "ac_cv_header_$ac_safe=no")
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  AC_MSG_RESULT(yes)
+  ifelse([$2], , :, [$2])
+else
+  AC_MSG_RESULT(no)
+ifelse([$3], , , [$3
+])dnl
+fi
+])
+
+AC_DEFUN([CMU_FIND_LIB_SUBDIR],
+[dnl
+AC_ARG_WITH([lib-subdir], AC_HELP_STRING([--with-lib-subdir=DIR],[Find libraries in DIR instead of lib]))
+AC_CHECK_SIZEOF(long)
+AC_CACHE_CHECK([what directory libraries are found in], [ac_cv_cmu_lib_subdir],
+[test "X$with_lib_subdir" = "Xyes" && with_lib_subdir=
+test "X$with_lib_subdir" = "Xno" && with_lib_subdir=
+if test "X$with_lib_subdir" = "X" ; then
+  ac_cv_cmu_lib_subdir=lib
+  if test $ac_cv_sizeof_long -eq 4 ; then
+    test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32
+  fi
+  if test $ac_cv_sizeof_long -eq 8 ; then
+    test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64
+  fi
+else
+  ac_cv_cmu_lib_subdir=$with_lib_subdir
+fi])
+AC_SUBST(CMU_LIB_SUBDIR, $ac_cv_cmu_lib_subdir)
+])
+
+dnl afs.m4--AFS libraries, includes, and dependencies
+dnl $Id: afs.m4,v 1.29 2005/04/26 19:14:07 shadow Exp $
+dnl Chaskiel Grundman
+dnl based on kerberos_v4.m4
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+
+AC_DEFUN([CMU_AFS_INC_WHERE1], [
+cmu_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$cmu_save_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <afs/param.h>],
+[#ifndef SYS_NAME
+choke me
+#endif
+int foo;],
+ac_cv_found_afs_inc=yes,
+ac_cv_found_afs_inc=no)
+CPPFLAGS=$cmu_save_CPPFLAGS
+])
+
+AC_DEFUN([CMU_AFS_LIB_WHERE1], [
+save_LIBS="$LIBS"
+save_LDFLAGS="$LDFLAGS"
+
+LIBS="-lauth $1/afs/util.a $LIB_SOCKET $LIBS"
+LDFLAGS="-L$1 -L$1/afs $LDFLAGS"
+dnl suppress caching
+AC_TRY_LINK([],[afsconf_Open();], ac_cv_found_afs_lib=yes, ac_cv_found_afs_lib=no)
+LIBS="$save_LIBS"
+LDFLAGS="$save_LDFLAGS"
+])
+
+AC_DEFUN([CMU_AFS_WHERE], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+   for i in $1; do
+      AC_MSG_CHECKING(for AFS in $i)
+      CMU_AFS_INC_WHERE1("$i/include")
+      ac_cv_found_lwp_inc=$ac_cv_found_afs_inc
+      CMU_TEST_INCPATH($i/include, lwp) 
+      ac_cv_found_afs_inc=$ac_cv_found_lwp_inc
+      if test "$ac_cv_found_afs_inc" = "yes"; then
+        CMU_AFS_LIB_WHERE1("$i/$CMU_LIB_SUBDIR")
+        if test "$ac_cv_found_afs_lib" = "yes"; then
+          ac_cv_afs_where=$i
+          AC_MSG_RESULT(found)
+          break
+        else
+          AC_MSG_RESULT(not found)
+        fi
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_AFS], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(AFS,
+       [  --with-afs=PREFIX      Compile with AFS support],
+       [if test "X$with_AFS" = "X"; then
+               with_AFS=yes
+       fi])
+
+       if test "X$with_AFS" != "X"; then
+         ac_cv_afs_where=$with_AFS
+       fi
+       if test "X$ac_cv_afs_where" = "X"; then
+         CMU_AFS_WHERE(/usr/afsws /usr/local /usr/athena /Library/OpenAFS/Tools)
+       fi
+
+       AC_MSG_CHECKING(whether to include AFS)
+       if test "X$ac_cv_afs_where" = "Xno" -o "X$ac_cv_afs_where" = "X"; then
+         ac_cv_found_afs=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_afs=yes
+         AC_MSG_RESULT(yes)
+         AFS_INC_DIR="$ac_cv_afs_where/include"
+         AFS_LIB_DIR="$ac_cv_afs_where/$CMU_LIB_SUBDIR"
+         AFS_TOP_DIR="$ac_cv_afs_where"
+         AFS_INC_FLAGS="-I${AFS_INC_DIR}"
+          AFS_LIB_FLAGS="-L${AFS_LIB_DIR} -L${AFS_LIB_DIR}/afs"
+          cmu_save_LIBS="$LIBS"
+          cmu_save_CPPFLAGS="$CPPFLAGS"
+          CPPFLAGS="$CPPFLAGS ${AFS_INC_FLAGS}"
+         cmu_save_LDFLAGS="$LDFLAGS"
+         LDFLAGS="$cmu_save_LDFLAGS ${AFS_LIB_FLAGS}"
+                        
+          AC_CHECK_HEADERS(afs/stds.h)
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],AFS_DES_LIB="",AFS_DES_LIB="maybe")
+          if test "X$AFS_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],AFS_DES_LIB="yes")
+              if test "X$AFS_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                 AFS_LIBDES="-ldes"
+                 AFS_LIBDESA="${AFS_LIB_DIR}/libdes.a"
+             else
+                 LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                 AC_TRY_LINK([],
+                 [des_quad_cksum();],AFS_DES_LIB="libcrypto")
+                 if test "X$AFS_DES_LIB" = "Xlibcrypto"; then
+                     AC_MSG_RESULT([libcrypto])
+                     AFS_LIBDES="$LIBSSL_LIB_FLAGS"
+                     AFS_LIBDESA="$LIBSSL_LIB_FLAGS"
+                 else
+                     LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     AC_TRY_LINK([],
+                     [des_quad_cksum();],AFS_DES_LIB="libcrypto+descompat")
+                     if test "X$AFS_DES_LIB" = "Xlibcrypto+descompat"; then
+                         AC_MSG_RESULT([libcrypto+descompat])
+                         AFS_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                         AFS_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     else
+                         AC_MSG_RESULT([unknown])
+                         AC_MSG_ERROR([Could not use -ldes])
+                     fi 
+                 fi 
+             fi 
+         else
+             AC_MSG_RESULT([no])
+          fi
+
+
+         AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS_STATIC="${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+         AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+         AFS_RX_LIBS="-lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS="-lauth ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_CHECK_FUNC(des_pcbc_init)
+          if test "X$ac_cv_func_des_pcbc_init" != "Xyes"; then
+           AC_CHECK_LIB(descompat, des_pcbc_init, AFS_DESCOMPAT_LIB="-ldescompat")
+           if test "X$AFS_DESCOMPAT_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_DESCOMPAT_LIB"
+           else
+
+           AC_MSG_CHECKING([if rxkad needs des_pcbc_init])
+           AC_TRY_LINK(,[tkt_DecodeTicket();],RXKAD_PROBLEM=no,RXKAD_PROBLEM=maybe)
+            if test "$RXKAD_PROBLEM" = "maybe"; then
+              AC_TRY_LINK([int des_pcbc_init() { return 0;}],
+              [tkt_DecodeTicket();],RXKAD_PROBLEM=yes,RXKAD_PROBLEM=error)
+              if test "$RXKAD_PROBLEM" = "yes"; then
+                    AC_MSG_RESULT([yes])
+                    AC_MSG_ERROR([cannot use rxkad])
+              else
+                    AC_MSG_RESULT([unknown])        
+                    AC_MSG_ERROR([Unknown error testing rxkad])
+              fi
+            else
+              AC_MSG_RESULT([no])
+            fi
+           fi
+          fi
+
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(flock)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_flock" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs flock])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int sigvec() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_FLOCK=no,AFS_FLOCK=yes)
+             if test $AFS_FLOCK = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, flock,:, [AC_CHECK_LIB(BSD, flock)])
+             fi
+          fi
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(sigvec)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_sigvec" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs sigvec])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int flock() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_SIGVEC=no,AFS_SIGVEC=yes)
+             if test $AFS_SIGVEC = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, sigvec,:,[AC_CHECK_LIB(BSD, sigvec)])
+             fi
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_LIB_FLAGS="${AFS_LIB_FLAGS} -L/usr/ucblib -R/usr/ucblib"
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lucb"
+          elif test "$ac_cv_lib_BSD_flock" = "yes" -o "$ac_cv_lib_BSD_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lBSD"
+          fi
+          if test "X$AFS_BSD_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_RX_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_BSD_LIB"
+          fi
+
+          AC_MSG_CHECKING([if libaudit is needed])
+         AFS_LIBAUDIT=""
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+          [afsconf_SuperUser();],AFS_AUDIT_LIB="",AFS_AUDIT_LIB="maybe")
+          if test "X$AFS_AUDIT_LIB" != "X"; then
+          LIBS="$cmu_save_LIBS -lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB $LIB_SOCKET"
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+             [afsconf_SuperUser();],AFS_AUDIT_LIB="yes")
+             if test "X$AFS_AUDIT_LIB" = "Xyes"; then
+                 AC_MSG_RESULT([yes])
+                AFS_LIBAUDIT="-laudit"
+                AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libaudit.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+                 AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+                 AFS_RX_LIBS="-lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+             else
+                 AC_MSG_RESULT([unknown])
+                 AC_MSG_ERROR([Could not use -lauth while testing for -laudit])
+             fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+
+         AC_CHECK_FUNCS(VL_ProbeServer)
+          AC_MSG_CHECKING([if new-style afs_ integer types are defined])
+          AC_CACHE_VAL(ac_cv_afs_int32,
+dnl The next few lines contain a quoted argument to egrep
+dnl It is critical that there be no leading or trailing whitespace
+dnl or newlines
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<(^|[^a-zA-Z_0-9])afs_int32[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif],
+ac_cv_afs_int32=yes, ac_cv_afs_int32=no)])
+          AC_MSG_RESULT($ac_cv_afs_int32)
+          if test $ac_cv_afs_int32 = yes ; then
+            AC_DEFINE(HAVE_AFS_INT32,, [AFS provides new "unambiguous" type names])
+          else
+            AC_DEFINE(afs_int16, int16, [it's a type definition])
+            AC_DEFINE(afs_int32, int32, [it's a type definition])
+            AC_DEFINE(afs_uint16, u_int16, [it's a type definition])
+            AC_DEFINE(afs_uint32, u_int32, [it's a type definition])
+          fi
+
+          CPPFLAGS="${cmu_save_CPPFLAGS}"
+          LDFLAGS="${cmu_save_LDFLAGS}"
+          LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(AFS_ENV,, [Use AFS. (find what needs this and nuke it)])
+          AC_DEFINE(AFS,, [Use AFS. (find what needs this and nuke it)])
+          AC_SUBST(AFS_CLIENT_LIBS_STATIC)
+          AC_SUBST(AFS_KTC_LIBS_STATIC)
+          AC_SUBST(AFS_CLIENT_LIBS)
+          AC_SUBST(AFS_RX_LIBS)
+          AC_SUBST(AFS_KTC_LIBS)
+          AC_SUBST(AFS_INC_FLAGS)
+          AC_SUBST(AFS_LIB_FLAGS)
+         AC_SUBST(AFS_TOP_DIR)
+         AC_SUBST(AFS_LIBAUDIT)
+         AC_SUBST(AFS_LIBDES)
+          AC_SUBST(AFS_LIBDESA)
+               fi
+       ])
+
+AC_DEFUN([CMU_NEEDS_AFS],
+[AC_REQUIRE([CMU_AFS])
+if test "$ac_cv_found_afs" != "yes"; then
+        AC_ERROR([Cannot continue without AFS])
+fi])
+
+dnl libssl.m4--Ssl libraries and includes
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: libssl.m4,v 1.10 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+CMU_CHECK_HEADER_NOCACHE(openssl/ssl.h,
+ac_cv_found_libssl_inc=yes,
+ac_cv_found_libssl_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl headers in $i)
+      CMU_LIBSSL_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, ssl)
+      if test "$ac_cv_found_libssl_inc" = "yes"; then
+        ac_cv_libssl_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lssl -lcrypto $LIB_SOCKET"
+AC_TRY_LINK(,
+[SSL_write();],
+[ac_cv_found_ssl_lib=yes],
+ac_cv_found_ssl_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl libraries in $i)
+      CMU_LIBSSL_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, ssl)
+      if test "$ac_cv_found_ssl_lib" = "yes" ; then
+        ac_cv_libssl_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(libssl,
+       [  --with-libssl=PREFIX      Compile with Libssl support],
+       [if test "X$with_libssl" = "X"; then
+               with_libssl=yes
+       fi])
+AC_ARG_WITH(libssl-lib,
+       [  --with-libssl-lib=dir     use libssl libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-lib])
+       fi])
+AC_ARG_WITH(libssl-include,
+       [  --with-libssl-include=dir use libssl headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-include])
+       fi])
+
+       if test "X$with_libssl" != "X"; then
+         if test "$with_libssl" != "yes" -a "$with_libssl" != no; then
+           ac_cv_libssl_where_lib=$with_libssl/$CMU_LIB_SUBDIR
+           ac_cv_libssl_where_inc=$with_libssl/include
+         fi
+       fi
+
+       if test "$with_libssl" != "no"; then 
+         if test "X$with_libssl_lib" != "X"; then
+           ac_cv_libssl_where_lib=$with_libssl_lib
+         fi
+         if test "X$ac_cv_libssl_where_lib" = "X"; then
+           CMU_LIBSSL_LIB_WHERE(/usr/local/$CMU_LIB_SUBDIR/openssl /usr/$CMU_LIB_SUBDIR/openssl /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_libssl_include" != "X"; then
+           ac_cv_libssl_where_inc=$with_libssl_include
+         fi
+         if test "X$ac_cv_libssl_where_inc" = "X"; then
+           CMU_LIBSSL_INC_WHERE(/usr/local/include /usr/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include libssl)
+       if test "X$ac_cv_libssl_where_lib" = "X" -a "X$ac_cv_libssl_where_inc" = "X"; then
+         ac_cv_found_libssl=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_libssl=yes
+         AC_MSG_RESULT(yes)
+         LIBSSL_INC_DIR=$ac_cv_libssl_where_inc
+         LIBSSL_LIB_DIR=$ac_cv_libssl_where_lib
+         LIBSSL_INC_FLAGS="-I${LIBSSL_INC_DIR}"
+         LIBSSL_LIB_FLAGS="-L${LIBSSL_LIB_DIR} -lssl -lcrypto"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBSSL_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       AC_SUBST(LIBSSL_INC_DIR)
+       AC_SUBST(LIBSSL_LIB_DIR)
+       AC_SUBST(LIBSSL_INC_FLAGS)
+       AC_SUBST(LIBSSL_LIB_FLAGS)
+       ])
+
+
+dnl kerberos_v4.m4--Kerberos 4 libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: kerberos_v4.m4,v 1.28 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_KRB_SENDAUTH_PROTO], [
+AC_MSG_CHECKING(for krb_sendauth prototype)
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_sendauth (long options, int fd, KTEXT ktext, char *service,
+                  char *inst, char *realm, u_long checksum,
+                  MSG_DAT *msg_data, CREDENTIALS *cred,
+                  Key_schedule schedule, struct sockaddr_in *laddr,
+                  struct sockaddr_in *faddr, char *version);],
+[int foo = krb_sendauth(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); ],
+ac_cv_krb_sendauth_proto=no,
+ac_cv_krb_sendauth_proto=yes)
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+if test "$ac_cv_krb_sendauth_proto" = yes; then
+        AC_DEFINE(HAVE_KRB_SENDAUTH_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+])
+
+AC_DEFUN([CMU_KRB_SET_KEY_PROTO], [
+AC_MSG_CHECKING(for krb_set_key prototype)
+AC_CACHE_VAL(ac_cv_krb_set_key_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_set_key(char *key, int cvt);],
+[int foo = krb_set_key(0, 0);],
+ac_cv_krb_set_key_proto=no,
+ac_cv_krb_set_key_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_set_key_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_SET_KEY_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_set_key_proto)
+])
+
+AC_DEFUN([CMU_KRB4_32_DEFN], [
+AC_MSG_CHECKING(for KRB4_32 definition)
+AC_CACHE_VAL(ac_cv_krb4_32_defn, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+],
+[KRB4_32 foo = 1;],
+ac_cv_krb4_32_defn=yes,
+ac_cv_krb4_32_defn=no)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb4_32_defn" = yes; then
+       AC_DEFINE(HAVE_KRB4_32_DEFINE)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb4_32_defn)
+])
+
+AC_DEFUN([CMU_KRB_RD_REQ_PROTO], [
+AC_MSG_CHECKING(for krb_rd_req prototype)
+AC_CACHE_VAL(ac_cv_krb_rd_req_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_rd_req(KTEXT authent, char *service, char *instance,
+unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn);],
+[int foo = krb_rd_req(0,0,0,0,0,0);],
+ac_cv_krb_rd_req_proto=no,
+ac_cv_krb_rd_req_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_rd_req_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_RD_REQ_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_rd_req_proto)
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <krb.h>],
+[struct ktext foo;],
+ac_cv_found_krb_inc=yes,
+ac_cv_found_krb_inc=no)
+if test "$ac_cv_found_krb_inc" = "no"; then
+  CPPFLAGS="$saved_CPPFLAGS -I$1 -I$1/kerberosIV"
+  AC_TRY_COMPILE([#include <krb.h>],
+  [struct ktext foo;],
+  [ac_cv_found_krb_inc=yes],
+  ac_cv_found_krb_inc=no)
+fi
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos headers in $i)
+      CMU_KRB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, krb)
+      if test "$ac_cv_found_krb_inc" = "yes"; then
+        ac_cv_krb_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for kerberos lib files
+#
+
+AC_DEFUN([CMU_KRB_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkrb ${KRB_LIBDES}"
+AC_TRY_LINK(,
+[dest_tkt();],
+[ac_cv_found_krb_lib=yes],
+ac_cv_found_krb_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_KRB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos libraries in $i)
+      CMU_KRB_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, krb)
+      if test "$ac_cv_found_krb_lib" = "yes" ; then
+        ac_cv_krb_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KRB4], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(krb4,
+       [  --with-krb4=PREFIX      Compile with Kerberos 4 support],
+       [if test "X$with_krb4" = "X"; then
+               with_krb4=yes
+       fi])
+AC_ARG_WITH(krb4-lib,
+       [  --with-krb4-lib=dir     use kerberos 4 libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-lib])
+       fi])
+AC_ARG_WITH(krb4-include,
+       [  --with-krb4-include=dir use kerberos 4 headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-include])
+       fi])
+
+       if test "X$with_krb4" != "X"; then
+         if test "$with_krb4" != "yes" -a "$with_krb4" != "no"; then
+           ac_cv_krb_where_lib=$with_krb4/$CMU_LIB_SUBDIR
+           ac_cv_krb_where_inc=$with_krb4/include
+         fi
+       fi
+       
+       if test "$with_krb4" != "no"; then
+         if test "X$with_krb4_lib" != "X"; then
+           ac_cv_krb_where_lib=$with_krb4_lib
+         fi
+         if test "X$with_krb4_include" != "X"; then
+           ac_cv_krb_where_inc=$with_krb4_include
+         fi
+         if test "X$ac_cv_krb_where_inc" = "X"; then
+           CMU_KRB_INC_WHERE(/usr/athena/include /usr/include/kerberosIV /usr/local/include /usr/include/kerberos)
+         fi
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],KRB_DES_LIB="",KRB_DES_LIB="maybe")
+          if test "X$KRB_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],KRB_DES_LIB="yes")
+              if test "X$KRB_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                  KRB_LIBDES="-ldes"
+                  KRB_LIBDESA='$(KRB_LIB_DIR)/libdes.a'
+              else
+                  LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                  AC_TRY_LINK([],
+                  [des_quad_cksum();],KRB_DES_LIB="libcrypto")
+                  if test "X$KRB_DES_LIB" = "Xlibcrypto"; then
+                      AC_MSG_RESULT([libcrypto])
+                      KRB_LIBDES="$LIBSSL_LIB_FLAGS"
+                      KRB_LIBDESA="$LIBSSL_LIB_FLAGS"
+                  else
+                      LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      AC_TRY_LINK([],
+                      [des_quad_cksum();],KRB_DES_LIB="libcrypto+descompat")
+                      if test "X$KRB_DES_LIB" = "Xlibcrypto+descompat"; then
+                          AC_MSG_RESULT([libcrypto+descompat])
+                          KRB_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                          KRB_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      else
+                          AC_MSG_RESULT([unknown])
+                          AC_MSG_ERROR([Could not use -ldes])
+                      fi 
+                  fi 
+              fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+          if test "X$ac_cv_krb_where_lib" = "X"; then
+            CMU_KRB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+          fi
+       fi
+         LIBS="${cmu_save_LIBS}"
+
+
+       AC_MSG_CHECKING([whether to include kerberos 4])
+       if test "X$ac_cv_krb_where_lib" = "X" -o "X$ac_cv_krb_where_inc" = "X"; then
+         ac_cv_found_krb=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_krb=yes
+         AC_MSG_RESULT(yes)
+         KRB_INC_DIR=$ac_cv_krb_where_inc
+         KRB_LIB_DIR=$ac_cv_krb_where_lib
+         KRB_INC_FLAGS="-I${KRB_INC_DIR}"
+         KRB_LIB_FLAGS="-L${KRB_LIB_DIR} -lkrb ${KRB_LIBDES}"
+         LIBS="${cmu_save_LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_LIB(resolv, dns_lookup, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lresolv",,"${KRB_LIB_FLAGS}")
+         AC_CHECK_LIB(crypt, crypt, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lcrypt",,"${KRB_LIB_FLAGS}")
+         LIBS="${LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_FUNCS(krb_get_int krb_life_to_time)
+          AC_SUBST(KRB_INC_FLAGS)
+          AC_SUBST(KRB_LIB_FLAGS)
+         LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(HAVE_KRB4,,[Kerberos V4 is present])dnl zephyr uses this
+         AC_DEFINE(KERBEROS,,[Use kerberos 4. find out what needs this symbol])
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${KRB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${KRB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${KRB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
+
+dnl
+dnl macros for configure.in to detect openssl
+dnl $Id: openssl.m4,v 1.11 2006/05/17 18:30:19 murch Exp $
+dnl
+
+AC_DEFUN([CMU_HAVE_OPENSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(openssl,[  --with-openssl=PATH     use OpenSSL from PATH],
+       with_openssl=$withval, with_openssl="yes")
+
+       save_CPPFLAGS=$CPPFLAGS
+       save_LDFLAGS=$LDFLAGS
+
+       if test -d $with_openssl; then
+         CPPFLAGS="${CPPFLAGS} -I${with_openssl}/include"
+         CMU_ADD_LIBPATH(${with_openssl}/$CMU_LIB_SUBDIR)
+       fi
+
+case "$with_openssl" in
+       no)
+         with_openssl="no";;
+       *) 
+         dnl if openssl has been compiled with the rsaref2 libraries,
+         dnl we need to include the rsaref libraries in the crypto check
+                LIB_RSAREF=""
+               AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                       cmu_have_rsaref=yes;
+                       [AC_CHECK_LIB(RSAglue, RSAPublicEncrypt,
+                               LIB_RSAREF="-lRSAglue -lrsaref",
+                               LIB_RSAREF="-lrsaref")],
+                       cmu_have_rsaref=no)
+
+               AC_CHECK_HEADER(openssl/evp.h, [
+                       AC_CHECK_LIB(crypto, EVP_DigestInit,
+                                       with_openssl="yes",
+                                       with_openssl="no", $LIB_RSAREF)],
+                       with_openssl=no)
+               ;;
+esac
+
+       if test "$with_openssl" != "no"; then
+               AC_DEFINE(HAVE_OPENSSL,[],[Do we have OpenSSL?])
+       else
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+       fi
+])
+
+dnl checking for kerberos 4 libraries (and DES)
+
+AC_DEFUN([SASL_DES_CHK], [
+AC_ARG_WITH(des, [  --with-des=DIR          with DES (look in DIR) [yes] ],
+       with_des=$withval,
+       with_des=yes)
+
+LIB_DES=""
+if test "$with_des" != no; then
+  if test -d $with_des; then
+    CPPFLAGS="$CPPFLAGS -I${with_des}/include"
+    LDFLAGS="$LDFLAGS -L${with_des}/lib"
+  fi
+
+  if test "$with_openssl" != no; then
+    dnl check for openssl installing -lcrypto, then make vanilla check
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+
+    dnl same test again, different symbol name
+    if test "$with_des" = no; then
+      AC_CHECK_LIB(crypto, DES_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+    fi
+  fi
+
+  if test "$with_des" = no; then
+    AC_CHECK_LIB(des, des_cbc_encrypt, [LIB_DES="-ldes";
+                                        with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des425, des_cbc_encrypt, [LIB_DES="-ldes425";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des524, des_cbc_encrypt, [LIB_DES="-ldes524";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+    dnl if openssl is around, we might be able to use that for des
+
+    dnl if openssl has been compiled with the rsaref2 libraries,
+    dnl we need to include the rsaref libraries in the crypto check
+    LIB_RSAREF=""
+    AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                 LIB_RSAREF="-lRSAglue -lrsaref"; cmu_have_rsaref=yes,
+                 cmu_have_rsaref=no)
+
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+       AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)], 
+        with_des=no, $LIB_RSAREF)
+  fi
+fi
+
+if test "$with_des" != no; then
+  AC_DEFINE(WITH_DES,[],[Use DES])
+fi
+
+AC_SUBST(LIB_DES)
+])
+
+AC_DEFUN([SASL_KERBEROS_V4_CHK], [
+  AC_REQUIRE([SASL_DES_CHK])
+
+  AC_ARG_ENABLE(krb4, [  --enable-krb4           enable KERBEROS_V4 authentication [[no]] ],
+    krb4=$enableval,
+    krb4=no)
+
+  if test "$krb4" != no; then
+    dnl In order to compile kerberos4, we need libkrb and libdes.
+    dnl (We've already gotten libdes from SASL_DES_CHK)
+    dnl we might need -lresolv for kerberos
+    AC_CHECK_LIB(resolv,res_search)
+
+    dnl if we were ambitious, we would look more aggressively for the
+    dnl krb4 install
+    if test -d ${krb4}; then
+       AC_CACHE_CHECK(for Kerberos includes, cyrus_krbinclude, [
+         for krbhloc in include/kerberosIV include/kerberos include
+         do
+           if test -f ${krb4}/${krbhloc}/krb.h ; then
+             cyrus_krbinclude=${krb4}/${krbhloc}
+             break
+           fi
+         done
+         ])
+
+       if test -n "${cyrus_krbinclude}"; then
+         CPPFLAGS="$CPPFLAGS -I${cyrus_krbinclude}"
+       fi
+       LDFLAGS="$LDFLAGS -L$krb4/lib"
+    fi
+
+    if test "$with_des" != no; then
+      AC_CHECK_HEADER(krb.h, [
+        AC_CHECK_LIB(com_err, com_err, [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR="-lcom_err"; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES -lcom_err)], [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES)])], krb4="no")
+
+      if test "$krb4" != "no" -a "$krb4lib" = "no"; then
+       AC_CHECK_LIB(krb4, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb4"; krb4=yes],
+                     krb4=no, $LIB_DES)
+      fi
+      if test "$krb4" = no; then
+          AC_WARN(No Kerberos V4 found)
+      fi
+    else
+      AC_WARN(No DES library found for Kerberos V4 support)
+      krb4=no
+    fi
+  fi
+
+  if test "$krb4" != no; then
+    cmu_save_LIBS="$LIBS"
+    LIBS="$LIBS $SASL_KRB_LIB"
+    AC_CHECK_FUNCS(krb_get_err_text)
+    LIBS="$cmu_save_LIBS"
+  fi
+
+  AC_MSG_CHECKING(KERBEROS_V4)
+  if test "$krb4" != no; then
+    AC_MSG_RESULT(enabled)
+    SASL_MECHS="$SASL_MECHS libkerberos4.la"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/kerberos4.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS kerberos4.o"
+    AC_DEFINE(STATIC_KERBEROS4,[],[User KERBEROS_V4 Staticly])
+    AC_DEFINE(HAVE_KRB,[],[Do we have Kerberos 4 Support?])
+    SASL_KRB_LIB="$SASL_KRB_LIB $LIB_DES $COM_ERR"
+  else
+    AC_MSG_RESULT(disabled)
+  fi
+  AC_SUBST(SASL_KRB_LIB)
+])
+
+
+# sasl2.m4--sasl2 libraries and includes
+# Rob Siemborski
+# $Id: sasl2.m4,v 1.52 2006/05/18 19:25:00 murch Exp $
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL_GSSAPI_CHK],
+[AC_REQUIRE([SASL2_CRYPT_CHK])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_ENABLE([gssapi],
+              [AC_HELP_STRING([--enable-gssapi=<DIR>],
+                              [enable GSSAPI authentication [yes]])],
+              [gssapi=$enableval],
+              [gssapi=yes])
+AC_ARG_WITH([gss_impl],
+            [AC_HELP_STRING([--with-gss_impl={heimdal|mit|cybersafe|seam|auto}],
+                            [choose specific GSSAPI implementation [[auto]]])],
+            [gss_impl=$withval],
+            [gss_impl=auto])
+
+if test "$gssapi" != no; then
+  platform=
+  case "${host}" in
+    *-*-linux*)
+      platform=__linux
+      ;;
+    *-*-hpux*)
+      platform=__hpux
+      ;;
+    *-*-irix*)
+      platform=__irix
+      ;;
+    *-*-solaris2*)
+# When should we use __sunos?
+      platform=__solaris
+      ;;
+    *-*-aix*)
+      platform=__aix
+      ;;
+    *)
+      AC_WARN([The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script])
+      if test "$gss_impl" = "cybersafe"; then
+        AC_ERROR([CyberSafe was forced, cannot continue as platform is not supported])
+      fi
+      ;;
+  esac
+
+  cmu_saved_CPPFLAGS=$CPPFLAGS
+
+  if test -d ${gssapi}; then
+    CPPFLAGS="$CPPFLAGS -I$gssapi/include"
+# We want to keep -I in our CPPFLAGS, but only if we succeed
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    LDFLAGS="$LDFLAGS -L$gssapi/lib"
+
+    if test -n "$platform"; then
+      if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+        CPPFLAGS="$CPPFLAGS -D$platform"
+        if test -d "${gssapi}/appsec-sdk/include"; then
+          CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+        fi
+      fi
+    fi
+  fi
+  AC_CHECK_HEADER([gssapi.h],
+                  [AC_DEFINE(HAVE_GSSAPI_H,,
+                             [Define if you have the gssapi.h header file])],
+                  [AC_CHECK_HEADER([gssapi/gssapi.h],,
+                                   [AC_WARN([Disabling GSSAPI - no include files found]); gssapi=no])])
+
+  CPPFLAGS=$cmu_saved_CPPFLAGS
+
+fi
+
+if test "$gssapi" != no; then
+  # We need to find out which gssapi implementation we are
+  # using. Supported alternatives are: MIT Kerberos 5,
+  # Heimdal Kerberos 5 (http://www.pdc.kth.se/heimdal),
+  # CyberSafe Kerberos 5 (http://www.cybersafe.com/)
+  # and Sun SEAM (http://wwws.sun.com/software/security/kerberos/)
+  #
+  # The choice is reflected in GSSAPIBASE_LIBS
+
+  AC_CHECK_LIB(resolv,res_search)
+  if test -d ${gssapi}; then
+     gssapi_dir="${gssapi}/lib"
+     GSSAPIBASE_LIBS="-L$gssapi_dir"
+     GSSAPIBASE_STATIC_LIBS="-L$gssapi_dir"
+  else
+     # FIXME: This is only used for building cyrus, and then only as
+     # a real hack.  it needs to be fixed.
+     gssapi_dir="/usr/local/lib"
+  fi
+
+  # Check a full link against the Heimdal libraries.
+  # If this fails, check a full link against the MIT libraries.
+  # If this fails, check a full link against the CyberSafe libraries.
+  # If this fails, check a full link against the Solaris 8 and up libgss.
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "heimdal"; then
+    gss_failed=0
+    AC_CHECK_LIB(gssapi,gss_unwrap,gss_impl="heimdal",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "mit"; then
+    # check for libkrb5support first
+    AC_CHECK_LIB(krb5support,krb5int_getspecific,K5SUP=-lkrb5support K5SUPSTATIC=$gssapi_dir/libkrb5support.a,,${LIB_SOCKET})
+
+    gss_failed=0
+    AC_CHECK_LIB(gssapi_krb5,gss_unwrap,gss_impl="mit",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP} ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  # For Cybersafe one has to set a platform define in order to make compilation work
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    cmu_saved_GSSAPIBASE_LIBS=$GSSAPIBASE_LIBS
+# FIXME - Note that the libraries are in .../lib64 for 64bit kernels
+    if test -d "${gssapi}/appsec-rt/lib"; then
+      GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -L${gssapi}/appsec-rt/lib"
+    fi
+    CPPFLAGS="$CPPFLAGS -D$platform"
+    if test -d "${gssapi}/appsec-sdk/include"; then
+      CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+    fi
+
+    gss_failed=0
+
+# Check for CyberSafe with two libraries first, than fall back to a single 
+# library (older CyberSafe)
+
+    unset ac_cv_lib_gss_csf_gss_acq_user
+    AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe03",
+                 [unset ac_cv_lib_gss_csf_gss_acq_user;
+                  AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe",
+                               gss_failed=1,$GSSAPIBASE_LIBS -lgss)],
+                 [${GSSAPIBASE_LIBS} -lgss -lcstbk5])
+
+    if test "$gss_failed" = "1"; then
+# Restore variables
+      GSSAPIBASE_LIBS=$cmu_saved_GSSAPIBASE_LIBS
+      CPPFLAGS=$cmu_saved_CPPFLAGS
+
+      if test "$gss_impl" != "auto"; then
+        gss_impl="failed"
+      fi
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "seam"; then
+    gss_failed=0
+    AC_CHECK_LIB(gss,gss_unwrap,gss_impl="seam",gss_failed=1,-lgss)
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "mit"; then
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}"
+  elif test "$gss_impl" = "heimdal"; then
+    CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}"
+  elif test "$gss_impl" = "cybersafe03"; then
+# Version of CyberSafe with two libraries
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss -lcstbk5"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "cybersafe"; then
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "seam"; then
+    GSSAPIBASE_LIBS=-lgss
+    # there is no static libgss on Solaris 8 and up
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "failed"; then
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - specified library not found])
+  else
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - no library])
+  fi
+fi
+
+#
+# Cybersafe defines both GSS_C_NT_HOSTBASED_SERVICE and GSS_C_NT_USER_NAME
+# in gssapi\rfckrb5.h
+#
+if test "$gssapi" != "no"; then
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(hostbased_service_gss_nt_yes,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_HOSTBASED_SERVICE
+                    hostbased_service_gss_nt_yes
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])],
+                 [AC_WARN([Cybersafe define not found])])
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  fi
+
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(user_name_yes_gss_nt,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_USER_NAME
+                   user_name_yes_gss_nt
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])],
+                 [AC_WARN([Cybersafe define not found])])
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  fi
+fi
+
+GSSAPI_LIBS=""
+AC_MSG_CHECKING([GSSAPI])
+if test "$gssapi" != no; then
+  AC_MSG_RESULT([with implementation ${gss_impl}])
+  AC_CHECK_LIB(resolv,res_search,GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lresolv")
+  SASL_MECHS="$SASL_MECHS libgssapiv2.la"
+  SASL_STATIC_OBJS="$SASL_STATIC_OBJS gssapi.o"
+  SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/gssapi.c"
+
+  cmu_save_LIBS="$LIBS"
+  LIBS="$LIBS $GSSAPIBASE_LIBS"
+  AC_CHECK_FUNCS(gsskrb5_register_acceptor_identity)
+  LIBS="$cmu_save_LIBS"
+else
+  AC_MSG_RESULT([disabled])
+fi
+AC_SUBST(GSSAPI_LIBS)
+AC_SUBST(GSSAPIBASE_LIBS)
+])# SASL_GSSAPI_CHK
+
+
+# SASL_SET_GSSAPI_LIBS
+# --------------------
+AC_DEFUN([SASL_SET_GSSAPI_LIBS],
+[SASL_GSSAPI_LIBS_SET="yes"
+])
+
+
+# CMU_SASL2
+# ---------
+# What we want to do here is setup LIB_SASL with what one would
+# generally want to have (e.g. if static is requested, make it that,
+# otherwise make it dynamic.
+#
+# We also want to create LIB_DYN_SASL and DYNSASLFLAGS.
+#
+# Also sets using_static_sasl to "no" "static" or "staticonly"
+#
+AC_DEFUN([CMU_SASL2],
+[AC_REQUIRE([SASL_GSSAPI_CHK])
+
+AC_ARG_WITH(sasl,
+            [AC_HELP_STRING([--with-sasl=DIR],[Compile with libsasl2 in <DIR>])],
+            with_sasl="$withval",
+            with_sasl="yes")
+
+AC_ARG_WITH(staticsasl,
+            [AC_HELP_STRING([--with-staticsasl=DIR],
+                            [Compile with staticly linked libsasl2 in <DIR>])],
+            [with_staticsasl="$withval";
+             if test $with_staticsasl != "no"; then
+               using_static_sasl="static"
+             fi],
+            [with_staticsasl="no"; using_static_sasl="no"])
+
+SASLFLAGS=""
+LIB_SASL=""
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+cmu_saved_LDFLAGS=$LDFLAGS
+cmu_saved_LIBS=$LIBS
+
+if test ${with_staticsasl} != "no"; then
+  if test -d ${with_staticsasl}; then
+    if test -d ${with_staticsasl}/lib64 ; then
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib64
+    else
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    fi
+    ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    ac_cv_sasl_where_inc=${with_staticsasl}/include
+
+    SASLFLAGS="-I$ac_cv_sasl_where_inc"
+    LIB_SASL="-L$ac_cv_sasl_where_lib"
+    CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+    LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+  else
+    with_staticsasl="/usr"
+  fi
+
+  AC_CHECK_HEADER(sasl/sasl.h,
+                  [AC_CHECK_HEADER(sasl/saslutil.h,
+                                   [for i42 in lib64 lib; do
+                                      if test -r ${with_staticsasl}/$i42/libsasl2.a; then
+                                        ac_cv_found_sasl=yes
+                                        AC_MSG_CHECKING([for static libsasl])
+                                        LIB_SASL="$LIB_SASL ${with_staticsasl}/$i42/libsasl2.a"
+                                      fi
+                                    done
+                                    if test ! "$ac_cv_found_sasl" = "yes"; then
+                                      AC_MSG_CHECKING([for static libsasl])
+                                      AC_ERROR([Could not find ${with_staticsasl}/lib*/libsasl2.a])
+                                    fi])])
+
+  AC_MSG_RESULT([found])
+
+  if test "x$SASL_GSSAPI_LIBS_SET" = "x"; then
+    LIB_SASL="$LIB_SASL $GSSAPIBASE_STATIC_LIBS"
+  else
+    SASL_GSSAPI_LIBS_SET=""
+    cmu_saved_LIBS="$GSSAPIBASE_STATIC_LIBS $cmu_saved_LIBS" 
+  fi
+fi
+
+if test -d ${with_sasl}; then
+  ac_cv_sasl_where_lib=${with_sasl}/lib
+  ac_cv_sasl_where_inc=${with_sasl}/include
+
+  DYNSASLFLAGS="-I$ac_cv_sasl_where_inc"
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, LIB_DYN_SASL)
+  fi
+  LIB_DYN_SASL="$LIB_DYN_SASL -lsasl2"
+  CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+  LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+fi
+
+# be sure to check for a SASLv2 specific function
+AC_CHECK_HEADER(sasl/sasl.h,
+                [AC_CHECK_HEADER(sasl/saslutil.h,
+                                 [AC_CHECK_LIB(sasl2, prop_get, 
+                                               ac_cv_found_sasl=yes,
+                                               ac_cv_found_sasl=no)],
+                                 ac_cv_found_sasl=no)],
+                ac_cv_found_sasl=no)
+
+if test "$ac_cv_found_sasl" = "yes"; then
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, DYNLIB_SASL)
+  fi
+  DYNLIB_SASL="$DYNLIB_SASL -lsasl2"
+  if test "$using_static_sasl" != "static"; then
+    LIB_SASL=$DYNLIB_SASL
+    SASLFLAGS=$DYNSASLFLAGS
+  fi
+else
+  DYNLIB_SASL=""
+  DYNSASLFLAGS=""
+  using_static_sasl="staticonly"
+fi
+
+if test "x$SASL_GSSAPI_LIBS_SET" != "x"; then
+  SASL_GSSAPI_LIBS_SET=""
+  cmu_saved_LIBS="$GSSAPIBASE_LIBS $cmu_saved_LIBS" 
+fi
+
+LIBS="$cmu_saved_LIBS"
+LDFLAGS="$cmu_saved_LDFLAGS"
+CPPFLAGS="$cmu_saved_CPPFLAGS"
+
+AC_SUBST(LIB_DYN_SASL)
+AC_SUBST(DYNSASLFLAGS)
+AC_SUBST(LIB_SASL)
+AC_SUBST(SASLFLAGS)
+])# CMU_SASL2
+
+
+# CMU_SASL2_REQUIRED
+# ------------------
+AC_DEFUN([CMU_SASL2_REQUIRED],
+[AC_REQUIRE([CMU_SASL2])
+if test "$ac_cv_found_sasl" != "yes"; then
+  AC_ERROR([Cannot continue without libsasl2.
+Get it from ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.])
+fi])
+
+
+# CMU_SASL2_REQUIRE_VER
+# ---------------------
+AC_DEFUN([CMU_SASL2_REQUIRE_VER],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $SASLFLAGS"
+
+AC_TRY_CPP([
+#include <sasl/sasl.h>
+
+#ifndef SASL_VERSION_MAJOR
+#error SASL_VERSION_MAJOR not defined
+#endif
+#ifndef SASL_VERSION_MINOR
+#error SASL_VERSION_MINOR not defined
+#endif
+#ifndef SASL_VERSION_STEP
+#error SASL_VERSION_STEP not defined
+#endif
+
+#if SASL_VERSION_MAJOR < $1 || SASL_VERSION_MINOR < $2 || SASL_VERSION_STEP < $3
+#error SASL version is less than $1.$2.$3
+#endif
+],,
+           [AC_ERROR([Incorrect SASL headers found.  This package requires SASL $1.$2.$3 or newer.])])
+
+CPPFLAGS=$cmu_saved_CPPFLAGS
+])# CMU_SASL2_REQUIRE_VER
+
+
+# CMU_SASL2_CHECKAPOP_REQUIRED
+# ----------------------------
+AC_DEFUN([CMU_SASL2_CHECKAPOP_REQUIRED],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_LDFLAGS=$LDFLAGS
+
+LDFLAGS="$LDFLAGS $LIB_SASL"
+
+AC_CHECK_LIB(sasl2, sasl_checkapop,
+             [AC_DEFINE(HAVE_APOP,[],[Does SASL support APOP?])],
+             [AC_MSG_ERROR([libsasl2 without working sasl_checkapop.  Cannot continue.])])
+
+LDFLAGS=$cmu_saved_LDFLAGS
+])# CMU_SASL2_CHECKAPOP_REQUIRED
+
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL2_CRYPT_CHK],
+[AC_CHECK_FUNC(crypt, cmu_have_crypt=yes,
+               [AC_CHECK_LIB(crypt, crypt,
+                             LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes,
+                             cmu_have_crypt=no)])
+AC_SUBST(LIB_CRYPT)
+])# SASL2_CRYPT_CHK
+
+dnl Check for PLAIN (and therefore crypt)
+
+AC_DEFUN([SASL_PLAIN_CHK],[
+AC_REQUIRE([SASL2_CRYPT_CHK])
+
+dnl PLAIN
+ AC_ARG_ENABLE(plain, [  --enable-plain          enable PLAIN authentication [yes] ],
+  plain=$enableval,
+  plain=yes)
+
+ PLAIN_LIBS=""
+ if test "$plain" != no; then
+  dnl In order to compile plain, we need crypt.
+  if test "$cmu_have_crypt" = yes; then
+    PLAIN_LIBS=$LIB_CRYPT
+  fi
+ fi
+ AC_SUBST(PLAIN_LIBS)
+
+ AC_MSG_CHECKING(PLAIN)
+ if test "$plain" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libplain.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS plain.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/plain.c"
+    AC_DEFINE(STATIC_PLAIN,[],[Link PLAIN Staticly])
+  fi
+ else
+  AC_MSG_RESULT(disabled)
+ fi
+])
+
+dnl
+dnl macros for configure.in to detect openldap
+dnl $Id: openldap.m4,v 1.2 2006/03/13 19:16:11 mel Exp $
+dnl
+
+dnl
+dnl Check for OpenLDAP version compatility
+AC_DEFUN([CMU_OPENLDAP_API],
+[AC_CACHE_CHECK([OpenLDAP api], [cmu_cv_openldap_api],[
+    AC_EGREP_CPP(__openldap_api,[
+#include <ldap.h>
+
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+char *__openldap_api = LDAP_API_FEATURE_X_OPENLDAP;
+#endif
+],      [cmu_cv_openldap_api=yes], [cmu_cv_openldap_api=no])])
+])
+
+dnl
+dnl Check for OpenLDAP version compatility
+AC_DEFUN([CMU_OPENLDAP_COMPAT],
+[AC_CACHE_CHECK([OpenLDAP version], [cmu_cv_openldap_compat],[
+    AC_EGREP_CPP(__openldap_compat,[
+#include <ldap.h>
+
+/* Require 2.1.27+ and 2.2.6+ */
+#if LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 1 && LDAP_VENDOR_VERSION_PATCH > 26
+char *__openldap_compat = "2.1.27 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 2 && LDAP_VENDOR_VERSION_PATCH > 5
+char *__openldap_compat = "2.2.6 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR > 2
+char *__openldap_compat = "2.3 or better okay"
+#endif
+],      [cmu_cv_openldap_compat=yes], [cmu_cv_openldap_compat=no])])
+])
+
+
+dnl See whether we can use IPv6 related functions
+dnl contributed by Hajimu UMEMOTO
+
+AC_DEFUN([IPv6_CHECK_FUNC], [
+AC_CHECK_FUNC($1, [dnl
+  ac_cv_lib_socket_$1=no
+  ac_cv_lib_inet6_$1=no
+], [dnl
+  AC_CHECK_LIB(socket, $1, [dnl
+    LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_$1=no
+  ], [dnl
+    AC_MSG_CHECKING([whether your system has IPv6 directory])
+    AC_CACHE_VAL(ipv6_cv_dir, [dnl
+      for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done])dnl
+    AC_MSG_RESULT($ipv6_cv_dir)
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_$1=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      AC_CHECK_LIB(inet6, $1, [dnl
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi],)dnl
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi])dnl
+])dnl
+ipv6_cv_$1=no
+if test $ac_cv_func_$1 = yes -o $ac_cv_lib_socket_$1 = yes \
+     -o $ac_cv_lib_inet6_$1 = yes
+then
+  ipv6_cv_$1=yes
+fi
+if test $ipv6_cv_$1 = no; then
+  if test $1 = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      AC_EGREP_HEADER(${ipv6_cv_pfx}$1, netdb.h,
+                     [AC_CHECK_FUNC(${ipv6_cv_pfx}$1)])
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}$1 = Xyes; then
+        AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo?])
+        ipv6_cv_$1=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_$1 = yes; then
+  ifelse([$2], , :, [$2])
+else
+  ifelse([$3], , :, [$3])
+fi])
+
+
+dnl See whether we have ss_family in sockaddr_storage
+AC_DEFUN([IPv6_CHECK_SS_FAMILY], [
+AC_MSG_CHECKING([whether you have ss_family in struct sockaddr_storage])
+AC_CACHE_VAL(ipv6_cv_ss_family, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+       [struct sockaddr_storage ss; int i = ss.ss_family;],
+       [ipv6_cv_ss_family=yes], [ipv6_cv_ss_family=no])])dnl
+if test $ipv6_cv_ss_family = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SS_FAMILY,[],[Is there an ss_family in sockaddr_storage?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_ss_family)])
+
+
+dnl whether you have sa_len in struct sockaddr
+AC_DEFUN([IPv6_CHECK_SA_LEN], [
+AC_MSG_CHECKING([whether you have sa_len in struct sockaddr])
+AC_CACHE_VAL(ipv6_cv_sa_len, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+              [struct sockaddr sa; int i = sa.sa_len;],
+              [ipv6_cv_sa_len=yes], [ipv6_cv_sa_len=no])])dnl
+if test $ipv6_cv_sa_len = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKADDR_SA_LEN,[],[Does sockaddr have an sa_len?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_sa_len)])
+
+
+dnl See whether sys/socket.h has socklen_t
+AC_DEFUN([IPv6_CHECK_SOCKLEN_T], [
+AC_MSG_CHECKING(for socklen_t)
+AC_CACHE_VAL(ipv6_cv_socklen_t, [dnl
+AC_TRY_LINK([#include <sys/types.h>
+#include <sys/socket.h>],
+           [socklen_t len = 0;],
+           [ipv6_cv_socklen_t=yes], [ipv6_cv_socklen_t=no])])dnl
+if test $ipv6_cv_socklen_t = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKLEN_T,[],[Do we have a socklen_t?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_socklen_t)])
+
+
diff --git a/cmulocal/COPYING b/cmulocal/COPYING
new file mode 100644 (file)
index 0000000..0176424
--- /dev/null
@@ -0,0 +1,20 @@
+        Copyright 1998 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon University
+not be used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+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.
+
diff --git a/cmulocal/README.andrew b/cmulocal/README.andrew
new file mode 100644 (file)
index 0000000..801e157
--- /dev/null
@@ -0,0 +1,71 @@
+This is a collection of autoconf macros which've been written by
+various people at CMU.  To use it, use "aclocal -I cmulocal" (after
+the first time, automake should automatically use the -I cmulocal, if
+you've called CMU_INIT_AUTOMAKE in configure.in).
+
+CMU_INIT_AUTOMAKE
+  If you use automake, you should call this after AM_INIT_AUTOMAKE.
+  It adds "-I cmulocal" to the aclocal command line, so that when
+  automake runs aclocal, aclocal'll continue to pick up these macros.
+
+CMU_ADD_LIBPATH
+  Add -L(arg), and possibly -R(arg) (or whatever the runpath is) to 
+  LDFLAGS.
+
+CMU_ADD_LIBPATH_TO
+  Likewise to above, except adds it to the specified variable (arg 2).
+
+CMU_GUESS_RUNPATH_SWITCH
+  Attempts to guess what the runpath switch is (-R or whatever).
+
+CMU_COMERR
+  Requires that com_err exist in the collection (at CMU, do this by
+  running "cvs checkout com_err", and adding com_err to DIST_SUBDIRS
+  in your Makefile.am).
+
+  It sets the output variable COMPILE_ET to the compile_et program to
+  use, and adds the appropriate paths to LDFLAGS and CPPFLAGS.
+
+  It does *not* add -lcom_err to LIBS (this would cause later library
+  checks to fail if com_err needs to be built), so Makefiles need to
+  explicitly add -lcom_err (which, after all, should always exist as
+  long as the com_err compile doesn't blow up).  Makefiles should do
+  this by using LIB_COMERR, which will substitute to the appropriate
+  magic to use to grab the library.  (This may involve a libtool archive;
+  you should be using libtool to link your program if you distribute
+  libraries with it that the program may link against).
+
+  Note that com_err will only be compiled if the configure script
+  can't find compile_et or libcom_err; if the system already has them,
+  the configure script will use the system installation (although, due
+  to some autoconf wonkiness, com_err will still be configured; it just
+  won't show up in the @subdirs@ expansion).
+
+CMU_NANA
+  Adds --with-nana, set by default; if set, attempts to link against
+  libnana.  If not set, or if libnana is unavailable, or if we're not
+  using gcc, it defines WITHOUT_NANA.
+
+CMU_PROG_LIBTOOL
+  Just like AM_PROG_LIBTOOL, except it performs a couple little hacks
+  to make sure that things don't break on picky vendor compilers
+  which whine about empty translation units. [DEPRECATED - DO NOT USE]
+
+CMU_PTHREADS
+  This attempts to link against libpthread (failing if it can't be found),
+  and attempts to do any system-specific setup required for thread
+  support (for example, most things want _REENTRANT to be defined,
+  but Solaris wants _POSIX_PTHREAD_SEMANTICS and __EXTENSIONS__, IRIX
+  wants to see _SGI_REENTRANT_FUNCTIONS, etc).
+
+CMU_SASL
+  This tries to find a SASL library, and calls AC_SUBST on LIB_SASL
+  if it finds one, or tells the user to go ftp it if it doesn't exist.
+
+  Provides --with-sasldir.
+
+CMU_KRB4
+  This attempts to find Kerberos 4 libraries and set up CFLAGS and LIBS
+  appropriately. It also updates and substitutes RPATH for shared library 
+  stuff.
+
diff --git a/cmulocal/afs.m4 b/cmulocal/afs.m4
new file mode 100644 (file)
index 0000000..1987d69
--- /dev/null
@@ -0,0 +1,314 @@
+dnl afs.m4--AFS libraries, includes, and dependencies
+dnl $Id: afs.m4,v 1.29 2005/04/26 19:14:07 shadow Exp $
+dnl Chaskiel Grundman
+dnl based on kerberos_v4.m4
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+
+AC_DEFUN([CMU_AFS_INC_WHERE1], [
+cmu_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$cmu_save_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <afs/param.h>],
+[#ifndef SYS_NAME
+choke me
+#endif
+int foo;],
+ac_cv_found_afs_inc=yes,
+ac_cv_found_afs_inc=no)
+CPPFLAGS=$cmu_save_CPPFLAGS
+])
+
+AC_DEFUN([CMU_AFS_LIB_WHERE1], [
+save_LIBS="$LIBS"
+save_LDFLAGS="$LDFLAGS"
+
+LIBS="-lauth $1/afs/util.a $LIB_SOCKET $LIBS"
+LDFLAGS="-L$1 -L$1/afs $LDFLAGS"
+dnl suppress caching
+AC_TRY_LINK([],[afsconf_Open();], ac_cv_found_afs_lib=yes, ac_cv_found_afs_lib=no)
+LIBS="$save_LIBS"
+LDFLAGS="$save_LDFLAGS"
+])
+
+AC_DEFUN([CMU_AFS_WHERE], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+   for i in $1; do
+      AC_MSG_CHECKING(for AFS in $i)
+      CMU_AFS_INC_WHERE1("$i/include")
+      ac_cv_found_lwp_inc=$ac_cv_found_afs_inc
+      CMU_TEST_INCPATH($i/include, lwp) 
+      ac_cv_found_afs_inc=$ac_cv_found_lwp_inc
+      if test "$ac_cv_found_afs_inc" = "yes"; then
+        CMU_AFS_LIB_WHERE1("$i/$CMU_LIB_SUBDIR")
+        if test "$ac_cv_found_afs_lib" = "yes"; then
+          ac_cv_afs_where=$i
+          AC_MSG_RESULT(found)
+          break
+        else
+          AC_MSG_RESULT(not found)
+        fi
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_AFS], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(AFS,
+       [  --with-afs=PREFIX      Compile with AFS support],
+       [if test "X$with_AFS" = "X"; then
+               with_AFS=yes
+       fi])
+
+       if test "X$with_AFS" != "X"; then
+         ac_cv_afs_where=$with_AFS
+       fi
+       if test "X$ac_cv_afs_where" = "X"; then
+         CMU_AFS_WHERE(/usr/afsws /usr/local /usr/athena /Library/OpenAFS/Tools)
+       fi
+
+       AC_MSG_CHECKING(whether to include AFS)
+       if test "X$ac_cv_afs_where" = "Xno" -o "X$ac_cv_afs_where" = "X"; then
+         ac_cv_found_afs=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_afs=yes
+         AC_MSG_RESULT(yes)
+         AFS_INC_DIR="$ac_cv_afs_where/include"
+         AFS_LIB_DIR="$ac_cv_afs_where/$CMU_LIB_SUBDIR"
+         AFS_TOP_DIR="$ac_cv_afs_where"
+         AFS_INC_FLAGS="-I${AFS_INC_DIR}"
+          AFS_LIB_FLAGS="-L${AFS_LIB_DIR} -L${AFS_LIB_DIR}/afs"
+          cmu_save_LIBS="$LIBS"
+          cmu_save_CPPFLAGS="$CPPFLAGS"
+          CPPFLAGS="$CPPFLAGS ${AFS_INC_FLAGS}"
+         cmu_save_LDFLAGS="$LDFLAGS"
+         LDFLAGS="$cmu_save_LDFLAGS ${AFS_LIB_FLAGS}"
+                        
+          AC_CHECK_HEADERS(afs/stds.h)
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],AFS_DES_LIB="",AFS_DES_LIB="maybe")
+          if test "X$AFS_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],AFS_DES_LIB="yes")
+              if test "X$AFS_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                 AFS_LIBDES="-ldes"
+                 AFS_LIBDESA="${AFS_LIB_DIR}/libdes.a"
+             else
+                 LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                 AC_TRY_LINK([],
+                 [des_quad_cksum();],AFS_DES_LIB="libcrypto")
+                 if test "X$AFS_DES_LIB" = "Xlibcrypto"; then
+                     AC_MSG_RESULT([libcrypto])
+                     AFS_LIBDES="$LIBSSL_LIB_FLAGS"
+                     AFS_LIBDESA="$LIBSSL_LIB_FLAGS"
+                 else
+                     LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     AC_TRY_LINK([],
+                     [des_quad_cksum();],AFS_DES_LIB="libcrypto+descompat")
+                     if test "X$AFS_DES_LIB" = "Xlibcrypto+descompat"; then
+                         AC_MSG_RESULT([libcrypto+descompat])
+                         AFS_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                         AFS_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     else
+                         AC_MSG_RESULT([unknown])
+                         AC_MSG_ERROR([Could not use -ldes])
+                     fi 
+                 fi 
+             fi 
+         else
+             AC_MSG_RESULT([no])
+          fi
+
+
+         AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS_STATIC="${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+         AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+         AFS_RX_LIBS="-lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS="-lauth ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_CHECK_FUNC(des_pcbc_init)
+          if test "X$ac_cv_func_des_pcbc_init" != "Xyes"; then
+           AC_CHECK_LIB(descompat, des_pcbc_init, AFS_DESCOMPAT_LIB="-ldescompat")
+           if test "X$AFS_DESCOMPAT_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_DESCOMPAT_LIB"
+           else
+
+           AC_MSG_CHECKING([if rxkad needs des_pcbc_init])
+           AC_TRY_LINK(,[tkt_DecodeTicket();],RXKAD_PROBLEM=no,RXKAD_PROBLEM=maybe)
+            if test "$RXKAD_PROBLEM" = "maybe"; then
+              AC_TRY_LINK([int des_pcbc_init() { return 0;}],
+              [tkt_DecodeTicket();],RXKAD_PROBLEM=yes,RXKAD_PROBLEM=error)
+              if test "$RXKAD_PROBLEM" = "yes"; then
+                    AC_MSG_RESULT([yes])
+                    AC_MSG_ERROR([cannot use rxkad])
+              else
+                    AC_MSG_RESULT([unknown])        
+                    AC_MSG_ERROR([Unknown error testing rxkad])
+              fi
+            else
+              AC_MSG_RESULT([no])
+            fi
+           fi
+          fi
+
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(flock)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_flock" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs flock])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int sigvec() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_FLOCK=no,AFS_FLOCK=yes)
+             if test $AFS_FLOCK = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, flock,:, [AC_CHECK_LIB(BSD, flock)])
+             fi
+          fi
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(sigvec)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_sigvec" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs sigvec])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int flock() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_SIGVEC=no,AFS_SIGVEC=yes)
+             if test $AFS_SIGVEC = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, sigvec,:,[AC_CHECK_LIB(BSD, sigvec)])
+             fi
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_LIB_FLAGS="${AFS_LIB_FLAGS} -L/usr/ucblib -R/usr/ucblib"
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lucb"
+          elif test "$ac_cv_lib_BSD_flock" = "yes" -o "$ac_cv_lib_BSD_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lBSD"
+          fi
+          if test "X$AFS_BSD_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_RX_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_BSD_LIB"
+          fi
+
+          AC_MSG_CHECKING([if libaudit is needed])
+         AFS_LIBAUDIT=""
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+          [afsconf_SuperUser();],AFS_AUDIT_LIB="",AFS_AUDIT_LIB="maybe")
+          if test "X$AFS_AUDIT_LIB" != "X"; then
+          LIBS="$cmu_save_LIBS -lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB $LIB_SOCKET"
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+             [afsconf_SuperUser();],AFS_AUDIT_LIB="yes")
+             if test "X$AFS_AUDIT_LIB" = "Xyes"; then
+                 AC_MSG_RESULT([yes])
+                AFS_LIBAUDIT="-laudit"
+                AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libaudit.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+                 AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+                 AFS_RX_LIBS="-lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+             else
+                 AC_MSG_RESULT([unknown])
+                 AC_MSG_ERROR([Could not use -lauth while testing for -laudit])
+             fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+
+         AC_CHECK_FUNCS(VL_ProbeServer)
+          AC_MSG_CHECKING([if new-style afs_ integer types are defined])
+          AC_CACHE_VAL(ac_cv_afs_int32,
+dnl The next few lines contain a quoted argument to egrep
+dnl It is critical that there be no leading or trailing whitespace
+dnl or newlines
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<(^|[^a-zA-Z_0-9])afs_int32[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif],
+ac_cv_afs_int32=yes, ac_cv_afs_int32=no)])
+          AC_MSG_RESULT($ac_cv_afs_int32)
+          if test $ac_cv_afs_int32 = yes ; then
+            AC_DEFINE(HAVE_AFS_INT32,, [AFS provides new "unambiguous" type names])
+          else
+            AC_DEFINE(afs_int16, int16, [it's a type definition])
+            AC_DEFINE(afs_int32, int32, [it's a type definition])
+            AC_DEFINE(afs_uint16, u_int16, [it's a type definition])
+            AC_DEFINE(afs_uint32, u_int32, [it's a type definition])
+          fi
+
+          CPPFLAGS="${cmu_save_CPPFLAGS}"
+          LDFLAGS="${cmu_save_LDFLAGS}"
+          LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(AFS_ENV,, [Use AFS. (find what needs this and nuke it)])
+          AC_DEFINE(AFS,, [Use AFS. (find what needs this and nuke it)])
+          AC_SUBST(AFS_CLIENT_LIBS_STATIC)
+          AC_SUBST(AFS_KTC_LIBS_STATIC)
+          AC_SUBST(AFS_CLIENT_LIBS)
+          AC_SUBST(AFS_RX_LIBS)
+          AC_SUBST(AFS_KTC_LIBS)
+          AC_SUBST(AFS_INC_FLAGS)
+          AC_SUBST(AFS_LIB_FLAGS)
+         AC_SUBST(AFS_TOP_DIR)
+         AC_SUBST(AFS_LIBAUDIT)
+         AC_SUBST(AFS_LIBDES)
+          AC_SUBST(AFS_LIBDESA)
+               fi
+       ])
+
+AC_DEFUN([CMU_NEEDS_AFS],
+[AC_REQUIRE([CMU_AFS])
+if test "$ac_cv_found_afs" != "yes"; then
+        AC_ERROR([Cannot continue without AFS])
+fi])
diff --git a/cmulocal/agentx.m4 b/cmulocal/agentx.m4
new file mode 100644 (file)
index 0000000..4028faa
--- /dev/null
@@ -0,0 +1,46 @@
+dnl agentx.m4--detect agentx libraries
+dnl copied from x-unixrc
+dnl Tim Martin
+dnl $Id: agentx.m4,v 1.5 2003/10/08 20:35:24 rjs3 Exp $
+
+AC_DEFUN([CMU_AGENTX], [
+
+       dnl
+       dnl CMU AgentX
+       dnl
+       AC_MSG_CHECKING([for AgentX])
+       AC_ARG_WITH(agentx, [  --with-agentx              CMU AgentX libraries located in (val)], AGENTX_DIR="$withval", AGENTX_DIR=no)
+
+       found_agentx="no"
+
+       if test "${AGENTX_DIR}" != "no" &&
+          test -f $AGENTX_DIR/lib${ABILIBDIR}/libagentx.a &&
+          test -f $AGENTX_DIR/include/agentx.h; then
+            AGENTX_DIR="$AGENTX_DIR"
+            found_agentx="yes"
+       elif test -d /usr/local &&
+          test -f /usr/local/lib${ABILIBDIR}/libagentx.a &&
+          test -f /usr/local/include/agentx.h; then
+            AGENTX_DIR="/usr/local"
+            found_agentx="yes"
+
+       elif test -d /usr/ng &&
+          test -f /usr/ng/lib${ABILIBDIR}/libagentx.a &&
+          test -f /usr/ng/include/agentx.h; then
+            AGENTX_DIR="/usr/ng"
+            found_agentx="yes"
+       fi
+
+       if test "$found_agentx" = "no"; then
+         AC_MSG_WARN([Could not locate AgentX Libraries! http://www.net.cmu.edu/groups/netdev/agentx/])
+       else
+         LIB_AGENTX="-L$AGENTX_DIR/lib${ABILIBDIR} -lagentx"
+         AC_SUBST(LIB_AGENTX)
+         AGENTXFLAGS="-I$AGENTX_DIR/include"
+          AC_SUBST(AGENTXFLAGS)   
+         AC_MSG_RESULT([found $AGENTX_DIR/lib${ABILIBDIR}/libagentx.a])        
+       fi
+
+
+
+])
diff --git a/cmulocal/arx.m4 b/cmulocal/arx.m4
new file mode 100644 (file)
index 0000000..8b87484
--- /dev/null
@@ -0,0 +1,155 @@
+dnl $Id: arx.m4,v 1.6 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_ARX_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <arx.h>],
+[arx_context *foo;],
+ac_cv_found_arx_inc=yes,
+ac_cv_found_arx_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_ARX_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for arx headers in $i)
+      CMU_ARX_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, arx)
+      if test "$ac_cv_found_arx_inc" = "yes"; then
+        ac_cv_arx_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for lib files
+#
+
+AC_DEFUN([CMU_ARX_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -larx $AFS_LIB_FLAGS $AFS_CLIENT_LIBS $KRB_LIB_FLAGS $LIB_SOCKET"
+AC_TRY_LINK(,
+[arx_Init();],
+[ac_cv_found_arx_lib=yes],
+ac_cv_found_arx_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_ARX_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for arx libraries in $i)
+      CMU_ARX_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, arx)
+      if test "$ac_cv_found_arx_lib" = "yes" ; then
+        ac_cv_arx_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_USE_ARX], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(arx,
+       [  --with-arx=PREFIX      Compile with arx support],
+       [if test "X$with_arx" = "X"; then
+               with_arx=yes
+       fi])
+AC_ARG_WITH(arx-lib,
+       [  --with-arx-lib=dir     use arx libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-arx-lib])
+       fi])
+AC_ARG_WITH(arx-include,
+       [  --with-arx-include=dir use arx headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-arx-include])
+       fi])
+
+       if test "X$with_arx" != "X"; then
+         if test "$with_arx" != "yes"; then
+           ac_cv_arx_where_lib=$with_arx/${CMU_LIB_SUBDIR}
+           ac_cv_arx_where_inc=$with_arx/include
+         fi
+       fi
+
+       if test "X$with_arx_lib" != "X"; then
+         ac_cv_arx_where_lib=$with_arx_lib
+       fi
+       if test "X$ac_cv_arx_where_lib" = "X"; then
+         CMU_ARX_LIB_WHERE(/usr/athena/${CMU_LIB_SUBDIR} /usr/local/${CMU_LIB_SUBDIR} /usr/${CMU_LIB_SUBDIR})
+       fi
+
+       if test "X$with_arx_include" != "X"; then
+         ac_cv_arx_where_inc=$with_arx_include
+       fi
+       if test "X$ac_cv_arx_where_inc" = "X"; then
+         CMU_ARX_INC_WHERE(/usr/athena/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include arx)
+       if test "X$ac_cv_arx_where_lib" = "X" -o "X$ac_cv_arx_where_inc" = "X"; then
+         ac_cv_found_arx=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_arx=yes
+         AC_MSG_RESULT(yes)
+         ARX_INC_DIR=$ac_cv_arx_where_inc
+         ARX_LIB_DIR=$ac_cv_arx_where_lib
+         ARX_INC_FLAGS="-I${ARX_INC_DIR}"
+         ARX_LIB_FLAGS="-L${ARX_LIB_DIR} -larx"
+         ARX_LD_FLAGS="-L${ARX_LIB_DIR}"
+          dnl Do not force configure.in to put these in CFLAGS and LIBS unconditionally
+          dnl Allow makefile substitutions....
+          AC_SUBST(ARX_INC_FLAGS)
+          AC_SUBST(ARX_LIB_FLAGS)
+          AC_SUBST(ARX_LD_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${ARX_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${ARX_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${ARX_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${ARX_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${ARX_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${ARX_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${ARX_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${ARX_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${ARX_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/ax_path_bdb.m4 b/cmulocal/ax_path_bdb.m4
new file mode 100644 (file)
index 0000000..c1d9470
--- /dev/null
@@ -0,0 +1,566 @@
+dnl @synopsis AX_PATH_BDB([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl
+dnl This macro finds the latest version of Berkeley DB on the system, 
+dnl and ensures that the header file and library versions match. If
+dnl MINIMUM-VERSION is specified, it will ensure that the library
+dnl found is at least that version.
+dnl 
+dnl It determines the name of the library as well as the path to the 
+dnl header file and library.  It will check both the default environment
+dnl as well as the default Berkeley DB install location.  When found, it
+dnl sets BDB_LIBS, BDB_CPPFLAGS, and BDB_LDFLAGS to the necessary values
+dnl to add to LIBS, CPPFLAGS, and LDFLAGS, as well as setting BDB_VERSION
+dnl to the version found.  HAVE_DB_H is defined also.
+dnl 
+dnl The option --with-bdb-dir=DIR can be used to specify a specific
+dnl Berkeley DB installation to use.
+dnl
+dnl An example of it's use is:
+dnl    AX_PATH_BDB([3],[
+dnl      LIBS="$BDB_LIBS $LIBS"
+dnl      LDFLAGS="$BDB_LDFLAGS $LDFLAGS"
+dnl      CPPFLAGS="$CPPFLAGS $BDB_CPPFLAGS"
+dnl    ])
+dnl which will locate the latest version of Berkeley DB on the system,
+dnl and ensure that it is version 3.0 or higher.
+dnl
+dnl Details: This macro does not use either AC_CHECK_HEADERS or 
+dnl AC_CHECK_LIB because, first, the functions inside the library are
+dnl sometimes renamed to contain a version code that is only available
+dnl from the db.h on the system, and second, because it is common to
+dnl have multiple db.h and libdb files on a system it is important to 
+dnl make sure the ones being used correspond to the same version.
+dnl Additionally, there are many different possible names for libdb
+dnl when installed by an OS distribution, and these need to be checked
+dnl if db.h does not correspond to libdb.
+dnl
+dnl When cross compiling, only header versions are verified since it
+dnl would be difficult to check the library version.  Additionally
+dnl the default Berkeley DB installation locations /usr/local/BerkeleyDB*
+dnl are not searched for higher versions of the library.
+dnl 
+dnl The format for the list of library names to search came from the
+dnl Cyrus IMAP distribution, although they are generated dynamically
+dnl here, and only for the version found in db.h.
+dnl 
+dnl The macro AX_COMPARE_VERSION is required to use this macro, and
+dnl should be available from the Autoconf Macro Archive.
+dnl
+dnl The author would like to acknowledge the generous and valuable feedback 
+dnl from Guido Draheim, without which this macro would be far less robust,
+dnl and have poor and inconsistent cross compilation support.
+dnl
+dnl @version $Id: ax_path_bdb.m4,v 1.1 2005/01/06 20:24:52 shadow Exp $
+dnl @author Tim Toolan <toolan@ele.uri.edu>
+dnl
+
+dnl #########################################################################
+AC_DEFUN([AX_PATH_BDB], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_ok=no
+
+  # Add --with-bdb-dir option to configure.
+  AC_ARG_WITH([bdb-dir],
+    [AC_HELP_STRING([--with-bdb-dir=DIR],
+                    [Berkeley DB installation directory])])
+
+  # Check if --with-bdb-dir was specified.
+  if test "x$with_bdb_dir" = "x" ; then 
+    # No option specified, so just search the system.
+    AX_PATH_BDB_NO_OPTIONS([$1], [HIGHEST], [
+      ax_path_bdb_ok=yes
+    ])
+   else
+     # Set --with-bdb-dir option.
+     ax_path_bdb_INC="$with_bdb_dir/include"
+     ax_path_bdb_LIB="$with_bdb_dir/lib"
+     dnl # Save previous environment, and modify with new stuff.
+     ax_path_bdb_save_CPPFLAGS="$CPPFLAGS"
+     CPPFLAGS="-I$ax_path_bdb_INC $CPPFLAGS"
+     ax_path_bdb_save_LDFLAGS=$LDFLAGS
+     LDFLAGS="-L$ax_path_bdb_LIB $LDFLAGS"
+     # Check for specific header file db.h
+     AC_MSG_CHECKING([db.h presence in $ax_path_bdb_INC])
+     if test -f "$ax_path_bdb_INC/db.h" ; then
+       AC_MSG_RESULT([yes])
+       # Check for library
+       AX_PATH_BDB_NO_OPTIONS([$1], [ENVONLY], [
+         ax_path_bdb_ok=yes
+         BDB_CPPFLAGS="-I$ax_path_bdb_INC"
+         BDB_LDFLAGS="-L$ax_path_bdb_LIB"
+       ])
+     else
+       AC_MSG_RESULT([no])
+       AC_MSG_NOTICE([no usable Berkeley DB not found]) 
+     fi
+     dnl # Restore the environment.
+     CPPFLAGS="$ax_path_bdb_save_CPPFLAGS"
+     LDFLAGS="$ax_path_bdb_save_LDFLAGS"
+
+  fi
+
+  dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+  if test "$ax_path_bdb_ok" = "yes" ; then
+    m4_ifvaln([$2],[$2],[:])dnl
+    m4_ifvaln([$3],[else $3])dnl
+  fi
+
+]) dnl AX_PATH_BDB
+
+dnl #########################################################################
+dnl Check for berkeley DB of at least MINIMUM-VERSION on system.
+dnl 
+dnl The OPTION argument determines how the checks occur, and can be one of:
+dnl
+dnl   HIGHEST -  Check both the environment and the default installation 
+dnl              directories for Berkeley DB and choose the version that
+dnl              is highest. (default)
+dnl   ENVFIRST - Check the environment first, and if no satisfactory 
+dnl              library is found there check the default installation 
+dnl              directories for Berkeley DB which is /usr/local/BerkeleyDB*
+dnl   ENVONLY -  Check the current environment only.
+dnl   
+dnl Requires AX_PATH_BDB_PATH_GET_VERSION, AX_PATH_BDB_PATH_FIND_HIGHEST,
+dnl          AX_PATH_BDB_ENV_CONFIRM_LIB, AX_PATH_BDB_ENV_GET_VERSION, and
+dnl          AX_COMPARE_VERSION macros.
+dnl
+dnl Result: sets ax_path_bdb_no_options_ok to yes or no
+dnl         sets BDB_LIBS, BDB_CPPFLAGS, BDB_LDFLAGS, BDB_VERSION
+dnl
+dnl AX_PATH_BDB_NO_OPTIONS([MINIMUM-VERSION], [OPTION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_NO_OPTIONS], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_no_options_ok=no
+
+  # Values to add to environment to use Berkeley DB.
+  BDB_VERSION=''
+  BDB_LIBS=''
+  BDB_CPPFLAGS=''
+  BDB_LDFLAGS=''
+
+  # Check cross compilation here.
+  if test "x$cross_compiling" = "xyes" ; then
+    # If cross compiling, can't use AC_RUN_IFELSE so do these tests.
+    # The AC_PREPROC_IFELSE confirms that db.h is preprocessable,
+    # and extracts the version number from it.
+    AC_MSG_CHECKING([for db.h])
+
+    AS_VAR_PUSHDEF([HEADER_VERSION],[ax_path_bdb_no_options_HEADER_VERSION])dnl
+    HEADER_VERSION=''
+    AC_PREPROC_IFELSE([
+      AC_LANG_SOURCE([[
+#include <db.h>
+AX_PATH_BDB_STUFF DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH
+      ]])
+    ],[
+      # Extract version from preprocessor output.
+      HEADER_VERSION=`eval "$ac_cpp conftest.$ac_ext" 2> /dev/null \
+        | grep AX_PATH_BDB_STUFF | sed 's/[[^0-9,]]//g;s/,/./g;1q'`
+    ],[])
+
+    if test "x$HEADER_VERSION" = "x" ; then
+      AC_MSG_RESULT([no])
+    else
+      AC_MSG_RESULT([$HEADER_VERSION])
+
+      # Check that version is high enough.
+      AX_COMPARE_VERSION([$HEADER_VERSION],[ge],[$1],[
+        # get major and minor version numbers
+        AS_VAR_PUSHDEF([MAJ],[ax_path_bdb_no_options_MAJOR])dnl
+        MAJ=`echo $HEADER_VERSION | sed 's,\..*,,'`
+        AS_VAR_PUSHDEF([MIN],[ax_path_bdb_no_options_MINOR])dnl
+        MIN=`echo $HEADER_VERSION | sed 's,^[[0-9]]*\.,,;s,\.[[0-9]]*$,,'`
+
+       dnl # Save LIBS.
+       ax_path_bdb_no_options_save_LIBS="$LIBS"
+
+        # Check that we can link with the library.
+        AC_SEARCH_LIBS([db_version], 
+          [db db-$MAJ.$MIN db$MAJ.$MIN db$MAJ$MIN db-$MAJ db$MAJ],[
+            # Sucessfully found library.
+            ax_path_bdb_no_options_ok=yes
+            BDB_VERSION=$HEADER_VERSION
+           
+           # Extract library from LIBS
+           ax_path_bdb_no_options_LEN=` \
+              echo "x$ax_path_bdb_no_options_save_LIBS" \
+              | awk '{print(length)}'`
+            BDB_LIBS=`echo "x$LIBS " \
+              | sed "s/.\{$ax_path_bdb_no_options_LEN\}\$//;s/^x//;s/ //g"`
+        ],[])
+
+        dnl # Restore LIBS
+       LIBS="$ax_path_bdb_no_options_save_LIBS"
+
+        AS_VAR_POPDEF([MAJ])dnl
+        AS_VAR_POPDEF([MIN])dnl
+      ])
+    fi
+
+    AS_VAR_POPDEF([HEADER_VERSION])dnl
+  else
+    # Not cross compiling.
+    # Check version of Berkeley DB in the current environment.
+    AX_PATH_BDB_ENV_GET_VERSION([
+      AX_COMPARE_VERSION([$ax_path_bdb_env_get_version_VERSION],[ge],[$1],[
+        # Found acceptable version in current environment.
+        ax_path_bdb_no_options_ok=yes
+        BDB_VERSION="$ax_path_bdb_env_get_version_VERSION"
+        BDB_LIBS="$ax_path_bdb_env_get_version_LIBS"
+      ])
+    ])
+
+    # Determine if we need to search /usr/local/BerkeleyDB*
+    ax_path_bdb_no_options_DONE=no
+    if test "x$2" = "xENVONLY" ; then
+      ax_path_bdb_no_options_DONE=yes
+    elif test "x$2" = "xENVFIRST" ; then
+      ax_path_bdb_no_options_DONE=$ax_path_bdb_no_options_ok
+    fi  
+
+    if test "$ax_path_bdb_no_options_DONE" = "no" ; then
+      # Check for highest in /usr/local/BerkeleyDB*
+      AX_PATH_BDB_PATH_FIND_HIGHEST([
+        if test "$ax_path_bdb_no_options_ok" = "yes" ; then
+        # If we already have an acceptable version use this if higher.
+          AX_COMPARE_VERSION(
+             [$ax_path_bdb_path_find_highest_VERSION],[gt],[$BDB_VERSION])
+        else
+          # Since we didn't have an acceptable version check if this one is.
+          AX_COMPARE_VERSION(
+             [$ax_path_bdb_path_find_highest_VERSION],[ge],[$1])
+        fi
+      ])
+
+      dnl # If result from _AX_COMPARE_VERSION is true we want this version.
+      if test "$ax_compare_version" = "true" ; then
+        ax_path_bdb_no_options_ok=yes
+        BDB_LIBS="-ldb"
+        BDB_CPPFLAGS="-I$ax_path_bdb_path_find_highest_DIR/include"
+        BDB_LDFLAGS="-L$ax_path_bdb_path_find_highest_DIR/lib"
+        BDB_VERSION="$ax_path_bdb_path_find_highest_VERSION"
+      fi
+    fi
+  fi
+
+  dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+  if test "$ax_path_bdb_no_options_ok" = "yes" ; then
+    AC_MSG_NOTICE([using Berkeley DB version $BDB_VERSION]) 
+    AC_DEFINE([HAVE_DB_H],[1],
+              [Define to 1 if you have the <db.h> header file.])
+    m4_ifvaln([$3],[$3])dnl
+  else
+    AC_MSG_NOTICE([no Berkeley DB version $1 or higher found]) 
+    m4_ifvaln([$4],[$4])dnl
+  fi 
+]) dnl AX_PATH_BDB_NO_OPTIONS
+
+dnl #########################################################################
+dnl Check the default installation directory for Berkeley DB which is
+dnl of the form /usr/local/BerkeleyDB* for the highest version.
+dnl
+dnl Result: sets ax_path_bdb_path_find_highest_ok to yes or no,
+dnl         sets ax_path_bdb_path_find_highest_VERSION to version,
+dnl         sets ax_path_bdb_path_find_highest_DIR to directory.
+dnl
+dnl AX_PATH_BDB_PATH_FIND_HIGHEST([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_PATH_FIND_HIGHEST], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_path_find_highest_ok=no
+
+  AS_VAR_PUSHDEF([VERSION],[ax_path_bdb_path_find_highest_VERSION])dnl
+  VERSION=''
+
+  ax_path_bdb_path_find_highest_DIR=''
+
+  # find highest verison in default install directory for Berkeley DB 
+  AS_VAR_PUSHDEF([CURDIR],[ax_path_bdb_path_find_highest_CURDIR])dnl
+  AS_VAR_PUSHDEF([CUR_VERSION],[ax_path_bdb_path_get_version_VERSION])dnl
+
+  for CURDIR in `ls -d /usr/local/BerkeleyDB* 2> /dev/null`
+  do
+    AX_PATH_BDB_PATH_GET_VERSION([$CURDIR],[
+      AX_COMPARE_VERSION([$CUR_VERSION],[gt],[$VERSION],[
+        ax_path_bdb_path_find_highest_ok=yes
+        ax_path_bdb_path_find_highest_DIR="$CURDIR"
+        VERSION="$CUR_VERSION"
+      ])
+    ])
+  done
+
+  AS_VAR_POPDEF([VERSION])dnl
+  AS_VAR_POPDEF([CUR_VERSION])dnl
+  AS_VAR_POPDEF([CURDIR])dnl
+
+  dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+  if test "$ax_path_bdb_path_find_highest_ok" = "yes" ; then
+    m4_ifvaln([$1],[$1],[:])dnl
+    m4_ifvaln([$2],[else $2])dnl
+  fi
+
+]) dnl AX_PATH_BDB_PATH_FIND_HIGHEST
+
+dnl #########################################################################
+dnl Checks for Berkeley DB in specified directory's lib and include 
+dnl subdirectories.  
+dnl
+dnl Result: sets ax_path_bdb_path_get_version_ok to yes or no,
+dnl         sets ax_path_bdb_path_get_version_VERSION to version.
+dnl
+dnl AX_PATH_BDB_PATH_GET_VERSION(BDB-DIR, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_PATH_GET_VERSION], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_path_get_version_ok=no
+
+  # Indicate status of checking for Berkeley DB header.
+  AC_MSG_CHECKING([in $1/include for db.h])
+  ax_path_bdb_path_get_version_got_header=no
+  test -f "$1/include/db.h" && ax_path_bdb_path_get_version_got_header=yes
+  AC_MSG_RESULT([$ax_path_bdb_path_get_version_got_header])
+
+  # Indicate status of checking for Berkeley DB library.
+  AC_MSG_CHECKING([in $1/lib for library -ldb])
+
+  ax_path_bdb_path_get_version_VERSION=''
+
+  if test -d "$1/include" && test -d "$1/lib" &&
+     test "$ax_path_bdb_path_get_version_got_header" = "yes" ; then
+    dnl # save and modify environment
+    ax_path_bdb_path_get_version_save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="-I$1/include $CPPFLAGS"
+
+    ax_path_bdb_path_get_version_save_LIBS="$LIBS"
+    LIBS="$LIBS -ldb"
+
+    ax_path_bdb_path_get_version_save_LDFLAGS="$LDFLAGS"
+    LDFLAGS="-L$1/lib $LDFLAGS"
+
+    # Compile and run a program that compares the version defined in
+    # the header file with a version defined in the library function
+    # db_version.
+    AC_RUN_IFELSE([
+      AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+  int major,minor,patch;
+  db_version(&major,&minor,&patch);
+  if (argc > 1)
+    printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+  if (DB_VERSION_MAJOR == major && DB_VERSION_MINOR == minor &&
+      DB_VERSION_PATCH == patch)
+    return 0;          
+  else
+    return 1;
+}
+      ]])
+    ],[
+      # Program compiled and ran, so get version by adding argument.
+      ax_path_bdb_path_get_version_VERSION=`./conftest$ac_exeext x`
+      ax_path_bdb_path_get_version_ok=yes
+    ],[],[])
+
+    dnl # restore environment
+    CPPFLAGS="$ax_path_bdb_path_get_version_save_CPPFLAGS"
+    LIBS="$ax_path_bdb_path_get_version_save_LIBS"
+    LDFLAGS="$ax_path_bdb_path_get_version_save_LDFLAGS"
+  fi
+
+  dnl # Finally, execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+  if test "$ax_path_bdb_path_get_version_ok" = "yes" ; then
+    AC_MSG_RESULT([$ax_path_bdb_path_get_version_VERSION])
+    m4_ifvaln([$2],[$2])dnl
+  else
+    AC_MSG_RESULT([no])
+    m4_ifvaln([$3],[$3])dnl
+  fi 
+]) dnl AX_PATH_BDB_PATH_GET_VERSION
+
+#############################################################################
+dnl Checks if version of library and header match specified version.  
+dnl Only meant to be used by AX_PATH_BDB_ENV_GET_VERSION macro.
+dnl 
+dnl Requires AX_COMPARE_VERSION macro.
+dnl 
+dnl Result: sets ax_path_bdb_env_confirm_lib_ok to yes or no.
+dnl
+dnl AX_PATH_BDB_ENV_CONFIRM_LIB(VERSION, [LIBNAME])
+AC_DEFUN([AX_PATH_BDB_ENV_CONFIRM_LIB], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_env_confirm_lib_ok=no
+
+  dnl # save and modify environment to link with library LIBNAME
+  ax_path_bdb_env_confirm_lib_save_LIBS="$LIBS"
+  LIBS="$LIBS $2"
+
+  # Compile and run a program that compares the version defined in
+  # the header file with a version defined in the library function
+  # db_version.
+  AC_RUN_IFELSE([
+    AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+  int major,minor,patch;
+  db_version(&major,&minor,&patch);
+  if (argc > 1)
+    printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+  if (DB_VERSION_MAJOR == major && DB_VERSION_MINOR == minor &&
+      DB_VERSION_PATCH == patch)
+    return 0;          
+  else
+    return 1;
+}
+    ]])
+  ],[
+    # Program compiled and ran, so get version by giving an argument,
+    # which will tell the program to print the output.
+    ax_path_bdb_env_confirm_lib_VERSION=`./conftest$ac_exeext x`
+
+    # If the versions all match up, indicate success.
+    AX_COMPARE_VERSION([$ax_path_bdb_env_confirm_lib_VERSION],[eq],[$1],[
+      ax_path_bdb_env_confirm_lib_ok=yes
+    ])
+  ],[],[])
+
+  dnl # restore environment
+  LIBS="$ax_path_bdb_env_confirm_lib_save_LIBS"
+
+]) dnl AX_PATH_BDB_ENV_CONFIRM_LIB
+
+#############################################################################
+dnl Finds the version and library name for Berkeley DB in the
+dnl current environment.  Tries many different names for library.
+dnl
+dnl Requires AX_PATH_BDB_ENV_CONFIRM_LIB macro.
+dnl
+dnl Result: set ax_path_bdb_env_get_version_ok to yes or no,
+dnl         set ax_path_bdb_env_get_version_VERSION to the version found,
+dnl         and ax_path_bdb_env_get_version_LIBNAME to the library name.
+dnl
+dnl AX_PATH_BDB_ENV_GET_VERSION([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+AC_DEFUN([AX_PATH_BDB_ENV_GET_VERSION], [
+  dnl # Used to indicate success or failure of this function.
+  ax_path_bdb_env_get_version_ok=no
+
+  ax_path_bdb_env_get_version_VERSION=''
+  ax_path_bdb_env_get_version_LIBS=''
+
+  AS_VAR_PUSHDEF([HEADER_VERSION],[ax_path_bdb_env_get_version_HEADER_VERSION])dnl
+  AS_VAR_PUSHDEF([TEST_LIBNAME],[ax_path_bdb_env_get_version_TEST_LIBNAME])dnl
+
+  # Indicate status of checking for Berkeley DB library.
+  AC_MSG_CHECKING([for db.h])
+
+  # Compile and run a program that determines the Berkeley DB version
+  # in the header file db.h.
+  HEADER_VERSION=''
+  AC_RUN_IFELSE([
+    AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <db.h>
+int main(int argc,char **argv)
+{
+  if (argc > 1)
+    printf("%d.%d.%d\n",DB_VERSION_MAJOR,DB_VERSION_MINOR,DB_VERSION_PATCH);
+  return 0;            
+}
+    ]])
+  ],[
+    # Program compiled and ran, so get version by adding an argument.
+    HEADER_VERSION=`./conftest$ac_exeext x`
+    AC_MSG_RESULT([$HEADER_VERSION])
+  ],[AC_MSG_RESULT([no])],[AC_MSG_RESULT([no])])
+
+  # Have header version, so try to find corresponding library.
+  # Looks for library names in the order:
+  #   nothing, db, db-X.Y, dbX.Y, dbXY, db-X, dbX
+  # and stops when it finds the first one that matches the version
+  # of the header file.  
+  if test "x$HEADER_VERSION" != "x" ; then 
+    AC_MSG_CHECKING([for library containing Berkeley DB $HEADER_VERSION])
+
+    AS_VAR_PUSHDEF([MAJOR],[ax_path_bdb_env_get_version_MAJOR])dnl
+    AS_VAR_PUSHDEF([MINOR],[ax_path_bdb_env_get_version_MINOR])dnl
+
+    # get major and minor version numbers
+    MAJOR=`echo $HEADER_VERSION | sed 's,\..*,,'`
+    MINOR=`echo $HEADER_VERSION | sed 's,^[[0-9]]*\.,,;s,\.[[0-9]]*$,,'`
+
+    # see if it is already specified in LIBS
+    TEST_LIBNAME=''
+    AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "db"
+      TEST_LIBNAME='-ldb'
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "db-X.Y"
+      TEST_LIBNAME="-ldb-${MAJOR}.$MINOR"
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "dbX.Y"
+      TEST_LIBNAME="-ldb${MAJOR}.$MINOR"
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "dbXY"
+      TEST_LIBNAME="-ldb$MAJOR$MINOR"
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "db-X"
+      TEST_LIBNAME="-ldb-$MAJOR"
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "no" ; then
+      # try format "dbX"
+      TEST_LIBNAME="-ldb$MAJOR"
+      AX_PATH_BDB_ENV_CONFIRM_LIB([$HEADER_VERSION], [$TEST_LIBNAME])
+    fi
+
+    dnl # Found a valid library.
+    if test "$ax_path_bdb_env_confirm_lib_ok" = "yes" ; then
+      if test "x$TEST_LIBNAME" = "x" ; then
+        AC_MSG_RESULT([none required])
+      else
+        AC_MSG_RESULT([$TEST_LIBNAME])
+      fi
+      ax_path_bdb_env_get_version_VERSION="$HEADER_VERSION"
+      ax_path_bdb_env_get_version_LIBS="$TEST_LIBNAME"
+      ax_path_bdb_env_get_version_ok=yes
+    else
+      AC_MSG_RESULT([no])
+    fi
+
+    AS_VAR_POPDEF([MAJOR])dnl
+    AS_VAR_POPDEF([MINOR])dnl
+  fi
+
+  AS_VAR_POPDEF([HEADER_VERSION])dnl
+  AS_VAR_POPDEF([TEST_LIBNAME])dnl
+
+  dnl # Execute ACTION-IF-FOUND / ACTION-IF-NOT-FOUND.
+  if test "$ax_path_bdb_env_confirm_lib_ok" = "yes" ; then
+    m4_ifvaln([$1],[$1],[:])dnl
+    m4_ifvaln([$2],[else $2])dnl
+  fi
+
+]) dnl BDB_ENV_GET_VERSION
+
+#############################################################################
+
diff --git a/cmulocal/berkdb.m4 b/cmulocal/berkdb.m4
new file mode 100644 (file)
index 0000000..3d61c01
--- /dev/null
@@ -0,0 +1,269 @@
+dnl $Id: berkdb.m4,v 1.20 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_DB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <db.h>],
+[DB *db;
+db_create(&db, NULL, 0);
+db->open(db, "foo.db", NULL, DB_UNKNOWN, DB_RDONLY, 0644);],
+ac_cv_found_db_inc=yes,
+ac_cv_found_db_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_DB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db headers in $i)
+      CMU_DB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, db)
+      if test "$ac_cv_found_db_inc" = "yes"; then
+        ac_cv_db_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for lib files
+#
+
+AC_DEFUN([CMU_DB3_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+  LIBS="$saved_LIBS -L$1 -ldb-3"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_3_lib=yes],
+ac_cv_found_db_3_lib=no)
+LIBS=$saved_LIBS
+])
+AC_DEFUN([CMU_DB4_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -ldb-4"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_4_lib=yes],
+ac_cv_found_db_4_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_DB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db libraries in $i)
+if test "$enable_db4" = "yes"; then
+      CMU_DB4_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-4])
+      ac_cv_found_db_lib=$ac_cv_found_db_4_lib
+else
+      CMU_DB3_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-3])
+      ac_cv_found_db_lib=$ac_cv_found_db_3_lib
+fi
+      if test "$ac_cv_found_db_lib" = "yes" ; then
+        ac_cv_db_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_USE_DB], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(db,
+       [  --with-db=PREFIX      Compile with db support],
+       [if test "X$with_db" = "X"; then
+               with_db=yes
+       fi])
+AC_ARG_WITH(db-lib,
+       [  --with-db-lib=dir     use db libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-lib])
+       fi])
+AC_ARG_WITH(db-include,
+       [  --with-db-include=dir use db headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-include])
+       fi])
+AC_ARG_ENABLE(db4,
+       [  --enable-db4          use db 4.x libraries])
+       
+       if test "X$with_db" != "X"; then
+         if test "$with_db" != "yes"; then
+           ac_cv_db_where_lib=$with_db/$CMU_LIB_SUBDIR
+           ac_cv_db_where_inc=$with_db/include
+         fi
+       fi
+
+       if test "X$with_db_lib" != "X"; then
+         ac_cv_db_where_lib=$with_db_lib
+       fi
+       if test "X$ac_cv_db_where_lib" = "X"; then
+         CMU_DB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_db_include" != "X"; then
+         ac_cv_db_where_inc=$with_db_include
+       fi
+       if test "X$ac_cv_db_where_inc" = "X"; then
+         CMU_DB_INC_WHERE(/usr/athena/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include db)
+       if test "X$ac_cv_db_where_lib" = "X" -o "X$ac_cv_db_where_inc" = "X"; then
+         ac_cv_found_db=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_db=yes
+         AC_MSG_RESULT(yes)
+         DB_INC_DIR=$ac_cv_db_where_inc
+         DB_LIB_DIR=$ac_cv_db_where_lib
+         DB_INC_FLAGS="-I${DB_INC_DIR}"
+          if test "$enable_db4" = "yes"; then
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-4"
+          else
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-3"
+          fi
+          dnl Do not force configure.in to put these in CFLAGS and LIBS unconditionally
+          dnl Allow makefile substitutions....
+          AC_SUBST(DB_INC_FLAGS)
+          AC_SUBST(DB_LIB_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${DB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${DB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${DB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
+
+
+dnl ---- CUT HERE ---
+
+dnl These are the Cyrus Berkeley DB macros.  In an ideal world these would be
+dnl identical to the above.
+
+dnl They are here so that they can be shared between Cyrus IMAPd
+dnl and Cyrus SASL with relative ease.
+
+dnl The big difference between this and the ones above is that we don't assume
+dnl that we know the name of the library, and we try a lot of permutations
+dnl instead.  We also assume that DB4 is acceptable.
+
+dnl When we're done, there will be a BDB_LIBADD and a BDB_INCADD which should
+dnl be used when necessary.  We should probably be smarter about our RPATH
+dnl handling.
+
+dnl Call these with BERKELEY_DB_CHK.
+
+dnl We will also set $dblib to "berkeley" if we are successful, "no" otherwise.
+
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named and where the db-3 header file is located.  arg.
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK_LIB],
+[
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, LDFLAGS)
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, BDB_LIBADD)
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           AC_TRY_LINK([#include <db.h>],
+           [db_create(NULL, NULL, 0);],
+           BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db,
+            dblib="no")
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           AC_TRY_LINK([#include <db.h>],
+           [db_open(NULL, 0, 0, 0, NULL, NULL, NULL);],
+           BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db,
+            dblib="no")
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_OPTS],
+[
+AC_ARG_WITH(bdb-libdir,
+       [  --with-bdb-libdir=DIR   Berkeley DB lib files are in DIR],
+       with_bdb_lib=$withval,
+       [ test "${with_bdb_lib+set}" = set || with_bdb_lib=none])
+AC_ARG_WITH(bdb-incdir,
+       [  --with-bdb-incdir=DIR   Berkeley DB include files are in DIR],
+       with_bdb_inc=$withval,
+       [ test "${with_bdb_inc+set}" = set || with_bdb_inc=none ])
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
+[
+       AC_REQUIRE([CYRUS_BERKELEY_DB_OPTS])
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+       dnl Note that FreeBSD puts it in a wierd place
+        dnl (but they should use with-bdb-incdir)
+        AC_CHECK_HEADER(db.h,
+                        [CYRUS_BERKELEY_DB_CHK_LIB()],
+                        dblib="no")
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+])
diff --git a/cmulocal/bsd_sockets.m4 b/cmulocal/bsd_sockets.m4
new file mode 100644 (file)
index 0000000..b811aa8
--- /dev/null
@@ -0,0 +1,39 @@
+dnl bsd_sockets.m4--which socket libraries do we need? 
+dnl Derrick Brashear
+dnl from Zephyr
+dnl $Id: bsd_sockets.m4,v 1.10 2005/04/26 19:14:07 shadow Exp $
+
+dnl Hacked on by Rob Earhart to not just toss stuff in LIBS
+dnl It now puts everything required for sockets into LIB_SOCKET
+
+AC_DEFUN([CMU_SOCKETS], [
+       save_LIBS="$LIBS"
+       LIB_SOCKET=""
+       AC_CHECK_FUNC(connect, :,
+               AC_CHECK_LIB(nsl, gethostbyname,
+                            LIB_SOCKET="-lnsl $LIB_SOCKET")
+               AC_CHECK_LIB(socket, connect,
+                            LIB_SOCKET="-lsocket $LIB_SOCKET")
+       )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNC(res_search, :,
+               LIBS="-lresolv $LIB_SOCKET $save_LIBS"
+               AC_TRY_LINK([[
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>]],[[
+const char host[12]="openafs.org";
+u_char ans[1024];
+res_search( host, C_IN, T_MX, (u_char *)&ans, sizeof(ans));
+return 0;
+]], LIB_SOCKET="-lresolv $LIB_SOCKET")
+        )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNCS(dn_expand dns_lookup)
+       LIBS="$save_LIBS"
+       AC_SUBST(LIB_SOCKET)
+       ])
diff --git a/cmulocal/c-attribute.m4 b/cmulocal/c-attribute.m4
new file mode 100644 (file)
index 0000000..54481b8
--- /dev/null
@@ -0,0 +1,31 @@
+dnl
+dnl $Id: c-attribute.m4,v 1.3 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN([CMU_C___ATTRIBUTE__], [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+  exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+  AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
diff --git a/cmulocal/c-fpic.m4 b/cmulocal/c-fpic.m4
new file mode 100644 (file)
index 0000000..0453518
--- /dev/null
@@ -0,0 +1,35 @@
+dnl
+dnl $Id: c-fpic.m4,v 1.2 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+
+dnl
+dnl Test for -fPIC
+dnl
+
+AC_DEFUN([CMU_C_FPIC], [
+AC_MSG_CHECKING(if compiler supports -fPIC)
+AC_CACHE_VAL(ac_cv_fpic, [
+save_CFLAGS=$CFLAGS
+CFLAGS="${CFLAGS} -fPIC"
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void
+foo(void)
+{
+  exit(1);
+}
+],
+ac_cv_fpic=yes,
+ac_cv_fpic=no)
+CFLAGS=$save_CFLAGS
+])
+if test "$ac_cv_fpic" = "yes"; then
+    FPIC_CFLAGS="-fPIC"
+else
+    FPIC_CFLAGS=""
+fi
+AC_MSG_RESULT($ac_cv_fpic)
+])
+
diff --git a/cmulocal/clamav.m4 b/cmulocal/clamav.m4
new file mode 100644 (file)
index 0000000..ea798a5
--- /dev/null
@@ -0,0 +1,35 @@
+dnl
+dnl macros for configure.in to detect clamav library
+dnl $Id: clamav.m4,v 1.2 2005/05/28 02:26:59 shadow Exp $
+dnl
+
+AC_DEFUN([CMU_CLAMAV], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(clamav,[  --with-clamav=PATH       use ClamAV - PATH to clamav-config (yes)],
+       with_clamav=$withval, with_clamav=yes)
+  have_clamav=no
+  if test "$with_clamav" != no; then
+       
+       if test -d $with_clamav; then
+               clamav_path=${with_clamav}:${with_clamav}/bin
+       else
+               clamav_path=/usr/local/bin:/usr/bin:$PATH
+       fi
+       AC_PATH_PROG(CLAMAV_CONFIG,clamav-config,,[$clamav_path])
+
+       if test -x "$CLAMAV_CONFIG"; then
+               LIB_CLAMAV="`$CLAMAV_CONFIG --libs` -lclamav"
+               CFLAGS_CLAMAV=`$CLAMAV_CONFIG --cflags`
+
+               if test -n "$LIB_CLAMAV"; then
+                       have_clamav=yes
+                       test -n "$CFLAGS_CLAMAV" && CPPFLAGS="$CPPFLAGS $CFLAGS_CLAMAV"
+                       AC_DEFINE(HAVE_CLAMAV,[],[Do we have ClamAV?])
+                       AC_SUBST(LIB_CLAMAV)
+               fi
+       fi
+   fi
+
+   AC_MSG_CHECKING(ClamAV support)
+   AC_MSG_RESULT($have_clamav)
+])
diff --git a/cmulocal/com_err.m4 b/cmulocal/com_err.m4
new file mode 100644 (file)
index 0000000..6bafedc
--- /dev/null
@@ -0,0 +1,28 @@
+dnl com_err.m4--com_err detection macro
+dnl Rob Earhart
+dnl $Id: com_err.m4,v 1.6 2003/10/08 20:35:24 rjs3 Exp $
+
+AC_DEFUN([CMU_COMERR], [
+        cmu_need_compile_et=no
+        AC_CHECK_PROGS(COMPILE_ET, compile_et, no)
+        if test "$COMPILE_ET" = no; then
+           COMPILE_ET="\$(top_builddir)/com_err/compile_et"
+           cmu_need_to_compile_com_err=yes
+        fi
+        AC_CHECK_HEADER(com_err.h,,CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/com_err")
+        cmu_save_LIBS="$LIBS"
+        AC_CHECK_LIB(com_err, com_err,
+                     LIB_COMERR="-lcom_err",
+                     LDFLAGS="$LDFLAGS -L`pwd`/com_err"
+                       LIB_COMERR="\$(top_builddir)/com_err/libcom_err.la"
+                     cmu_need_to_compile_com_err=yes)
+        AC_SUBST(LIB_COMERR)
+        LIBS="$cmu_save_LIBS"
+        AC_MSG_CHECKING(whether we need to compile com_err)
+        if test "$cmu_need_to_compile_com_err" = yes; then
+          AC_MSG_RESULT(yes)
+          AC_CONFIG_SUBDIRS(com_err)
+        else
+          AC_MSG_RESULT(no)
+        fi
+        ])
diff --git a/cmulocal/com_err_link.m4 b/cmulocal/com_err_link.m4
new file mode 100644 (file)
index 0000000..5a2f4eb
--- /dev/null
@@ -0,0 +1,157 @@
+dnl damnit, i don't want to figure out if I need to build an integral com_err
+dnl library with the collection, I just want to know where it's installed,
+dnl so don't bitch, Rob...
+dnl Derrick Brashear
+dnl $Id: com_err_link.m4,v 1.9 2006/02/25 18:32:46 cg2v Exp $
+
+
+AC_DEFUN([CMU_COMERR_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <com_err.h>],
+[int foo;],
+ac_cv_found_com_err_inc=yes,
+ac_cv_found_com_err_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_COMERR_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for com_err headers in $i)
+      CMU_COMERR_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, com_err)
+      if test "$ac_cv_found_com_err_inc" = "yes"; then
+        ac_cv_comerr_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for lib files
+#
+
+AC_DEFUN([CMU_COMERR_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lcom_err"
+AC_TRY_LINK(,
+[com_err();],
+[ac_cv_found_com_err_lib=yes],
+ac_cv_found_com_err_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_COMERR_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for com_err libraries in $i)
+      CMU_COMERR_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, com_err)
+      if test "$ac_cv_found_com_err_lib" = "yes" ; then
+        ac_cv_comerr_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_USE_COMERR], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(comerr,
+       [  --with-comerr=PREFIX      Compile with com_err support],
+       [if test "X$with_comerr" = "X"; then
+               with_comerr=yes
+       fi])
+AC_ARG_WITH(comerr-lib,
+       [  --with-comerr-lib=dir     use com_err libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-comerr-lib])
+       fi])
+AC_ARG_WITH(comerr-include,
+       [  --with-comerr-include=dir use com_err headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-comerr-include])
+       fi])
+
+       if test "X$with_comerr" != "X"; then
+         if test "$with_comerr" != "yes"; then
+           ac_cv_comerr_where_lib=$with_comerr/$CMU_LIB_SUBDIR
+           ac_cv_comerr_where_inc=$with_comerr/include
+         fi
+       fi
+
+       if test "X$with_comerr_lib" != "X"; then
+         ac_cv_comerr_where_lib=$with_comerr_lib
+       fi
+       if test "X$ac_cv_comerr_where_lib" = "X"; then
+         CMU_COMERR_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_comerr_include" != "X"; then
+         ac_cv_comerr_where_inc=$with_comerr_include
+       fi
+       if test "X$ac_cv_comerr_where_inc" = "X"; then
+         CMU_COMERR_INC_WHERE(/usr/athena/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include com_err)
+       if test "X$ac_cv_comerr_where_lib" = "X" -a "X$ac_cv_comerr_where_inc" = "X"; then
+         ac_cv_found_com_err=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_com_err=yes
+         AC_MSG_RESULT(yes)
+         COMERR_INC_DIR=$ac_cv_comerr_where_inc
+         COMERR_LIB_DIR=$ac_cv_comerr_where_lib
+         test "$COMERR_INC_DIR"  && COMERR_INC_FLAGS="-I${COMERR_INC_DIR}"
+         COMERR_LIB_FLAGS="-lcom_err"
+         test "$COMERR_LIB_DIR"  && COMERR_LIB_FLAGS="-L${COMERR_LIB_DIR} -lcom_err"
+          dnl Do not force configure.in to put these in CFLAGS and LIBS unconditionally
+          dnl Allow makefile substitutions....
+          AC_SUBST(COMERR_INC_FLAGS)
+          AC_SUBST(COMERR_LIB_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${COMERR_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${COMERR_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${COMERR_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${COMERR_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${COMERR_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${COMERR_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${COMERR_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${COMERR_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${COMERR_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/common.m4 b/cmulocal/common.m4
new file mode 100644 (file)
index 0000000..8855129
--- /dev/null
@@ -0,0 +1,61 @@
+dnl $Id: common.m4,v 1.13 2006/02/25 18:29:46 cg2v Exp $
+
+AC_DEFUN([CMU_TEST_LIBPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_lib, <<- *>>, <<__p>>))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/lib$2.a" -a \! -r "$1/lib$2.so" -a \! -r "$1/lib$2.sl" -a \! -r "$1/lib$2.dylib"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+AC_DEFUN([CMU_TEST_INCPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_inc, [ *], [_p]))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/$2.h"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+dnl CMU_CHECK_HEADER_NOCACHE(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([CMU_CHECK_HEADER_NOCACHE],
+[dnl Do the transliteration at runtime so arg 1 can be a shell variable.
+ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
+AC_MSG_CHECKING([for $1])
+AC_TRY_CPP([#include <$1>], eval "ac_cv_header_$ac_safe=yes",
+  eval "ac_cv_header_$ac_safe=no")
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  AC_MSG_RESULT(yes)
+  ifelse([$2], , :, [$2])
+else
+  AC_MSG_RESULT(no)
+ifelse([$3], , , [$3
+])dnl
+fi
+])
+
+AC_DEFUN([CMU_FIND_LIB_SUBDIR],
+[dnl
+AC_ARG_WITH([lib-subdir], AC_HELP_STRING([--with-lib-subdir=DIR],[Find libraries in DIR instead of lib]))
+AC_CHECK_SIZEOF(long)
+AC_CACHE_CHECK([what directory libraries are found in], [ac_cv_cmu_lib_subdir],
+[test "X$with_lib_subdir" = "Xyes" && with_lib_subdir=
+test "X$with_lib_subdir" = "Xno" && with_lib_subdir=
+if test "X$with_lib_subdir" = "X" ; then
+  ac_cv_cmu_lib_subdir=lib
+  if test $ac_cv_sizeof_long -eq 4 ; then
+    test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32
+  fi
+  if test $ac_cv_sizeof_long -eq 8 ; then
+    test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64
+  fi
+else
+  ac_cv_cmu_lib_subdir=$with_lib_subdir
+fi])
+AC_SUBST(CMU_LIB_SUBDIR, $ac_cv_cmu_lib_subdir)
+])
diff --git a/cmulocal/cyrus.m4 b/cmulocal/cyrus.m4
new file mode 100644 (file)
index 0000000..7f03978
--- /dev/null
@@ -0,0 +1,45 @@
+dnl
+dnl Additional macros for configure.in packaged up for easier theft.
+dnl $Id: cyrus.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+dnl tjs@andrew.cmu.edu 6-may-1998
+dnl
+
+dnl It would be good if ANDREW_ADD_LIBPATH could detect if something was
+dnl already there and not redundantly add it if it is.
+
+dnl add -L(arg), and possibly (runpath switch)(arg), to LDFLAGS
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH], [
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$1 ${LDFLAGS}"
+  else
+       LDFLAGS="-L$1 $andrew_runpath_switch$1 ${LDFLAGS}"
+  fi
+])
+
+dnl add -L(1st arg), and possibly (runpath switch)(1st arg), to (2nd arg)
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH_TO], [
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       $2="-L$1 ${$2}"
+  else
+       $2="-L$1 ${$2} $andrew_runpath_switch$1"
+  fi
+])
+
+dnl runpath initialization
+AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [
+   # CMU GUESS RUNPATH SWITCH
+  AC_CACHE_CHECK(for runpath switch, andrew_runpath_switch, [
+    # first, try -R
+    SAVE_LDFLAGS="${LDFLAGS}"
+    LDFLAGS="-R /usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-R"], [
+       LDFLAGS="-Wl,-rpath,/usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-Wl,-rpath,"],
+    [andrew_runpath_switch="none"])
+    ])
+  LDFLAGS="${SAVE_LDFLAGS}"
+  ])])
diff --git a/cmulocal/db.m4 b/cmulocal/db.m4
new file mode 100644 (file)
index 0000000..ebc1a89
--- /dev/null
@@ -0,0 +1,46 @@
+dnl $Id: db.m4,v 1.2 2004/02/14 21:16:18 cg2v Exp $
+dnl
+dnl tests for various db libraries
+dnl
+AC_DEFUN([rk_DB],[berkeley_db=db
+AC_ARG_WITH(berkeley-db,
+[  --without-berkeley-db   if you don't want berkeley db],[
+if test "$withval" = no; then
+       berkeley_db=""
+fi
+])
+if test "$berkeley_db"; then
+  AC_CHECK_HEADERS([                           \
+       db.h                                    \
+       db_185.h                                \
+  ])
+fi
+
+AC_FIND_FUNC_NO_LIBS2(dbopen, $berkeley_db, [
+#include <stdio.h>
+#if defined(HAVE_DB_185_H)
+#include <db_185.h>
+#elif defined(HAVE_DB_H)
+#include <db.h>
+#endif
+],[NULL, 0, 0, 0, NULL])
+
+AC_FIND_FUNC_NO_LIBS(dbm_firstkey, $berkeley_db gdbm ndbm)
+AC_FIND_FUNC_NO_LIBS2(db_create, $berkeley_db, [
+#include <stdio.h>
+#if defined(HAVE_DB_H)
+#include <db.h>
+#endif
+],[NULL, NULL, 0])
+
+
+DBLIB="$LIB_dbopen"
+if test "$LIB_dbopen" != "$LIB_db_create"; then
+        DBLIB="$DBLIB $LIB_db_create"
+fi
+if test "$LIB_dbopen" != "$LIB_dbm_firstkey"; then
+       DBLIB="$DBLIB $LIB_dbm_firstkey"
+fi
+AC_SUBST(DBLIB)dnl
+
+])
diff --git a/cmulocal/find-func-no-libs.m4 b/cmulocal/find-func-no-libs.m4
new file mode 100644 (file)
index 0000000..523fda3
--- /dev/null
@@ -0,0 +1,9 @@
+dnl $Id: find-func-no-libs.m4,v 1.2 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN([AC_FIND_FUNC_NO_LIBS], [
+AC_FIND_FUNC_NO_LIBS2([$1], ["" $2], [$3], [$4], [$5], [$6])])
diff --git a/cmulocal/find-func-no-libs2.m4 b/cmulocal/find-func-no-libs2.m4
new file mode 100644 (file)
index 0000000..8202b5d
--- /dev/null
@@ -0,0 +1,61 @@
+dnl $Id: find-func-no-libs2.m4,v 1.2 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+dnl
+dnl Look for function in any of the specified libraries
+dnl
+
+dnl AC_FIND_FUNC_NO_LIBS2(func, libraries, includes, arguments, extra libs, extra args)
+AC_DEFUN([AC_FIND_FUNC_NO_LIBS2], [
+
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(ac_cv_funclib_$1,
+[
+if eval "test \"\$ac_cv_func_$1\" != yes" ; then
+       ac_save_LIBS="$LIBS"
+       for ac_lib in $2; do
+               if test -n "$ac_lib"; then 
+                       ac_lib="-l$ac_lib"
+               else
+                       ac_lib=""
+               fi
+               LIBS="$6 $ac_lib $5 $ac_save_LIBS"
+               AC_TRY_LINK([$3],[$1($4)],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
+       done
+       eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
+       LIBS="$ac_save_LIBS"
+fi
+])
+
+eval "ac_res=\$ac_cv_funclib_$1"
+
+if false; then
+       AC_CHECK_FUNCS($1)
+dnl    AC_CHECK_LIBS($2, foo)
+fi
+# $1
+ac_tr_func=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ac_tr_lib=HAVE_LIB_`echo $ac_res |sed 's/-l//' | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+eval "LIB_$1=$ac_res"
+
+case "$ac_res" in
+       yes)
+       eval "ac_cv_func_$1=yes"
+       eval "LIB_$1="
+       AC_DEFINE_UNQUOTED($ac_tr_func)
+       AC_MSG_RESULT([yes])
+       ;;
+       no)
+       eval "ac_cv_func_$1=no"
+       eval "LIB_$1="
+       AC_MSG_RESULT([no])
+       ;;
+       *)
+       eval "ac_cv_func_$1=yes"
+       eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
+       AC_DEFINE_UNQUOTED($ac_tr_func)
+       AC_DEFINE_UNQUOTED($ac_tr_lib)
+       AC_MSG_RESULT([yes, in $ac_res])
+       ;;
+esac
+AC_SUBST(LIB_$1)
+])
diff --git a/cmulocal/find-func.m4 b/cmulocal/find-func.m4
new file mode 100644 (file)
index 0000000..38d7616
--- /dev/null
@@ -0,0 +1,9 @@
+dnl $Id: find-func.m4,v 1.2 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+dnl AC_FIND_FUNC(func, libraries, includes, arguments)
+AC_DEFUN([AC_FIND_FUNC], [
+AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
+if test -n "$LIB_$1"; then
+       LIBS="$LIB_$1 $LIBS"
+fi
+])
diff --git a/cmulocal/heimdal.m4 b/cmulocal/heimdal.m4
new file mode 100644 (file)
index 0000000..7286744
--- /dev/null
@@ -0,0 +1,197 @@
+dnl kerberos_v5.m4--Kerberos 5 libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: heimdal.m4,v 1.9 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_LIBHEIMDAL_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <krb5.h>],
+[krb5_keyblock foo;],
+ac_cv_found_libheimdal_inc=yes,
+ac_cv_found_libheimdal_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_LIBHEIMDAL_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for heimdal headers in $i)
+      CMU_LIBHEIMDAL_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, krb5)
+      if test "$ac_cv_found_libheimdal_inc" = "yes"; then
+        ac_cv_libheimdal_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for kerberos lib files
+#
+
+AC_DEFUN([CMU_LIBHEIMDAL_LIB_WHERE1], [
+AC_REQUIRE([CMU_SOCKETS])
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkadm5clnt -lkrb5 -lasn1 -lkadm5clnt -lroken $LIB_SOCKET"
+AC_TRY_LINK(,
+[krb5_get_in_tkt();],
+[ac_cv_found_libheimdal_lib=yes],
+ac_cv_found_libheimdal_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBHEIMDAL_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for heimdal libraries in $i)
+      CMU_LIBHEIMDAL_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, krb5)
+      if test "$ac_cv_found_libheimdal_lib" = "yes" ; then
+        ac_cv_libheimdal_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBHEIMDAL_LIBDES], [
+  AC_REQUIRE([CMU_LIBSSL])
+  cmu_save_LIBS=$LIBS
+  AC_MSG_CHECKING([if libdes is needed])
+  AC_TRY_LINK([],[des_quad_cksum();],HEIM_DES_LIB="",HEIM_DES_LIB="maybe")
+  if test "X$HEIM_DES_LIB" != "X"; then
+      LIBS="$cmu_save_LIBS -L$1 -ldes"
+      AC_TRY_LINK([], [des_quad_cksum();],HEIM_DES_LIB="yes")
+      if test "X$HEIM_DES_LIB" = "Xyes"; then
+          AC_MSG_RESULT([yes])
+          HEIM_LIBDES="-ldes"
+          HEIM_LIBDESA="$1/libdes.a"
+      else
+          LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+          AC_TRY_LINK([],
+          [des_quad_cksum();],HEIM_DES_LIB="libcrypto")
+          if test "X$HEIM_DES_LIB" = "Xlibcrypto"; then
+              AC_MSG_RESULT([libcrypto])
+              HEIM_LIBDES="$LIBSSL_LIB_FLAGS"
+              HEIM_LIBDESA="$LIBSSL_LIB_FLAGS"
+          else
+              LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+              AC_TRY_LINK([],
+              [des_quad_cksum();],HEIM_DES_LIB="libcrypto+descompat")
+              if test "X$HEIM_DES_LIB" = "Xlibcrypto+descompat"; then
+                  AC_MSG_RESULT([libcrypto+descompat])
+                  HEIM_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                  HEIM_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+              else
+                  AC_MSG_RESULT([unknown])
+                  AC_MSG_ERROR([Could not use -ldes])
+              fi 
+          fi 
+      fi 
+  else
+     AC_MSG_RESULT([no])
+  fi
+])
+
+AC_DEFUN([CMU_LIBHEIMDAL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_USE_COMERR])
+AC_ARG_WITH(LIBHEIMDAL,
+       [  --with-libheimdal=PREFIX      Compile with Heimdal support],
+       [if test "X$with_libheimdal" = "X"; then
+               with_libheimdal=yes
+       fi])
+AC_ARG_WITH(libheimdal-lib,
+       [  --with-libheimdal-lib=dir     use heimdal libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libheimdal-lib])
+       fi])
+AC_ARG_WITH(libheimdal-include,
+       [  --with-libheimdal-include=dir use heimdal headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libheimdal-include])
+       fi])
+
+       if test "X$with_libheimdal" != "X"; then
+         if test "$with_libheimdal" != "yes" -a "$with_libheimdal" != "no"; then
+           ac_cv_libheimdal_where_lib=$with_libheimdal/$CMU_LIB_SUBDIR
+           ac_cv_libheimdal_where_inc=$with_libheimdal/include
+         fi
+       fi
+
+       if test "$with_libheimdal" != "no"; then
+         if test "X$with_libheimdal_lib" != "X"; then
+           ac_cv_libheimdal_where_lib=$with_libheimdal_lib
+         fi
+         if test "X$ac_cv_libheimdal_where_lib" = "X"; then
+           CMU_LIBHEIMDAL_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/heimdal/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_libheimdal_include" != "X"; then
+           ac_cv_libheimdal_where_inc=$with_libheimdal_include
+         fi
+         if test "X$ac_cv_libheimdal_where_inc" = "X"; then
+           CMU_LIBHEIMDAL_INC_WHERE(/usr/athena/include /usr/heimdal/include /usr/local/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include heimdal)
+       if test "X$ac_cv_libheimdal_where_lib" = "X" -a "X$ac_cv_libheimdal_where_inc" = "X"; then
+         ac_cv_found_libheimdal=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_libheimdal=yes
+         AC_MSG_RESULT(yes)
+         LIBHEIMDAL_INC_DIR=$ac_cv_libheimdal_where_inc
+         LIBHEIMDAL_LIB_DIR=$ac_cv_libheimdal_where_lib
+         CMU_LIBHEIMDAL_LIBDES($LIBHEIMDAL_LIB_DIR)
+         LIBHEIMDAL_INC_FLAGS="-I${LIBHEIMDAL_INC_DIR}"
+         LIBHEIMDAL_LIB_FLAGS="-L${LIBHEIMDAL_LIB_DIR} -lkadm5clnt -lkrb5 -lasn1 ${HEIM_LIBDES} -lroken $LIB_SOCKET"
+         AC_SUBST(LIBHEIMDAL_INC_FLAGS)
+         AC_SUBST(LIBHEIMDAL_LIB_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBHEIMDAL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBHEIMDAL_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBHEIMDAL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBHEIMDAL_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBHEIMDAL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBHEIMDAL_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBHEIMDAL_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBHEIMDAL_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBHEIMDAL_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/init_automake.m4 b/cmulocal/init_automake.m4
new file mode 100644 (file)
index 0000000..e643d70
--- /dev/null
@@ -0,0 +1,8 @@
+dnl init_automake.m4--cmulocal automake setup macro
+dnl Rob Earhart
+dnl $Id: init_automake.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+
+AC_DEFUN([CMU_INIT_AUTOMAKE], [
+       AC_REQUIRE([AM_INIT_AUTOMAKE])
+       ACLOCAL="$ACLOCAL -I \$(top_srcdir)/cmulocal"
+       ])
diff --git a/cmulocal/ipv6.m4 b/cmulocal/ipv6.m4
new file mode 100644 (file)
index 0000000..7e50c96
--- /dev/null
@@ -0,0 +1,111 @@
+dnl See whether we can use IPv6 related functions
+dnl contributed by Hajimu UMEMOTO
+
+AC_DEFUN([IPv6_CHECK_FUNC], [
+AC_CHECK_FUNC($1, [dnl
+  ac_cv_lib_socket_$1=no
+  ac_cv_lib_inet6_$1=no
+], [dnl
+  AC_CHECK_LIB(socket, $1, [dnl
+    LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_$1=no
+  ], [dnl
+    AC_MSG_CHECKING([whether your system has IPv6 directory])
+    AC_CACHE_VAL(ipv6_cv_dir, [dnl
+      for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done])dnl
+    AC_MSG_RESULT($ipv6_cv_dir)
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_$1=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      AC_CHECK_LIB(inet6, $1, [dnl
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi],)dnl
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi])dnl
+])dnl
+ipv6_cv_$1=no
+if test $ac_cv_func_$1 = yes -o $ac_cv_lib_socket_$1 = yes \
+     -o $ac_cv_lib_inet6_$1 = yes
+then
+  ipv6_cv_$1=yes
+fi
+if test $ipv6_cv_$1 = no; then
+  if test $1 = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      AC_EGREP_HEADER(${ipv6_cv_pfx}$1, netdb.h,
+                     [AC_CHECK_FUNC(${ipv6_cv_pfx}$1)])
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}$1 = Xyes; then
+        AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo?])
+        ipv6_cv_$1=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_$1 = yes; then
+  ifelse([$2], , :, [$2])
+else
+  ifelse([$3], , :, [$3])
+fi])
+
+
+dnl See whether we have ss_family in sockaddr_storage
+AC_DEFUN([IPv6_CHECK_SS_FAMILY], [
+AC_MSG_CHECKING([whether you have ss_family in struct sockaddr_storage])
+AC_CACHE_VAL(ipv6_cv_ss_family, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+       [struct sockaddr_storage ss; int i = ss.ss_family;],
+       [ipv6_cv_ss_family=yes], [ipv6_cv_ss_family=no])])dnl
+if test $ipv6_cv_ss_family = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SS_FAMILY,[],[Is there an ss_family in sockaddr_storage?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_ss_family)])
+
+
+dnl whether you have sa_len in struct sockaddr
+AC_DEFUN([IPv6_CHECK_SA_LEN], [
+AC_MSG_CHECKING([whether you have sa_len in struct sockaddr])
+AC_CACHE_VAL(ipv6_cv_sa_len, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+              [struct sockaddr sa; int i = sa.sa_len;],
+              [ipv6_cv_sa_len=yes], [ipv6_cv_sa_len=no])])dnl
+if test $ipv6_cv_sa_len = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKADDR_SA_LEN,[],[Does sockaddr have an sa_len?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_sa_len)])
+
+
+dnl See whether sys/socket.h has socklen_t
+AC_DEFUN([IPv6_CHECK_SOCKLEN_T], [
+AC_MSG_CHECKING(for socklen_t)
+AC_CACHE_VAL(ipv6_cv_socklen_t, [dnl
+AC_TRY_LINK([#include <sys/types.h>
+#include <sys/socket.h>],
+           [socklen_t len = 0;],
+           [ipv6_cv_socklen_t=yes], [ipv6_cv_socklen_t=no])])dnl
+if test $ipv6_cv_socklen_t = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKLEN_T,[],[Do we have a socklen_t?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_socklen_t)])
+
diff --git a/cmulocal/kafs.m4 b/cmulocal/kafs.m4
new file mode 100644 (file)
index 0000000..8b89cfd
--- /dev/null
@@ -0,0 +1,167 @@
+dnl kerberos_v4.m4--Kafs libraries and includes
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: kafs.m4,v 1.7 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_KAFS_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([
+#include <krb.h>
+#include <sys/ioctl.h>
+#include <kafs.h>
+],
+[struct ClearToken foo;],
+ac_cv_found_kafs_inc=yes,
+ac_cv_found_kafs_inc=no)
+if test "$ac_cv_found_kafs_inc" = "no"; then
+  CPPFLAGS="$saved_CPPFLAGS -I$1 -I$1/kerberosIV"
+  AC_TRY_COMPILE([
+#include <krb.h>
+#include <sys/ioctl.h>
+#include <kafs.h>
+],
+  [struct ClearToken foo;],
+  [ac_cv_found_kafs_inc=yes],
+  ac_cv_found_kafs_inc=no)
+fi
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_KAFS_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kafs headers in $i)
+      CMU_KAFS_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, kafs)
+      if test "$ac_cv_found_kafs_inc" = "yes"; then
+        ac_cv_kafs_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KAFS_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkafs $KRB_LIB_FLAGS $KRB5_LIB_FLAGS"
+AC_TRY_LINK(,
+[krb_afslog();],
+[ac_cv_found_kafs_lib=yes],
+ac_cv_found_kafs_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_KAFS_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kafs libraries in $i)
+      CMU_KAFS_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, kafs)
+      if test "$ac_cv_found_kafs_lib" = "yes" ; then
+        ac_cv_kafs_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KAFS], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_KRB4])
+AC_REQUIRE([CMU_KRB5])
+AC_ARG_WITH(kafs,
+       [  --with-kafs=PREFIX      Compile with Kafs support],
+       [if test "X$with_kafs" = "X"; then
+               with_kafs=yes
+       fi])
+AC_ARG_WITH(kafs-lib,
+       [  --with-kafs-lib=dir     use kafs libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-kafs-lib])
+       fi])
+AC_ARG_WITH(kafs-include,
+       [  --with-kafs-include=dir use kafs headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-kafs-include])
+       fi])
+
+       if test "X$with_kafs" != "X"; then
+         if test "$with_kafs" != "yes" -a "$with_kafs" != no; then
+           ac_cv_kafs_where_lib=$with_kafs/$CMU_LIB_SUBDIR
+           ac_cv_kafs_where_inc=$with_kafs/include
+         fi
+       fi
+
+       if test "$with_kafs" != "no"; then 
+         if test "X$with_kafs_lib" != "X"; then
+           ac_cv_kafs_where_lib=$with_kafs_lib
+         fi
+         if test "X$ac_cv_kafs_where_lib" = "X"; then
+           CMU_KAFS_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_kafs_include" != "X"; then
+           ac_cv_kafs_where_inc=$with_kafs_include
+         fi
+         if test "X$ac_cv_kafs_where_inc" = "X"; then
+           CMU_KAFS_INC_WHERE(/usr/athena/include /usr/include/kerberosIV /usr/local/include /usr/include/kerberos)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include kafs)
+       if test "X$ac_cv_kafs_where_lib" = "X" -a "X$ac_cv_kafs_where_inc" = "X"; then
+         ac_cv_found_kafs=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_kafs=yes
+         AC_MSG_RESULT(yes)
+         KAFS_INC_DIR=$ac_cv_kafs_where_inc
+         KAFS_LIB_DIR=$ac_cv_kafs_where_lib
+         KAFS_INC_FLAGS="-I${KAFS_INC_DIR}"
+         KAFS_LIB_FLAGS="-L${KAFS_LIB_DIR} -lkafs"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KAFS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KAFS_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${KAFS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KAFS_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KAFS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KAFS_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${KAFS_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${KAFS_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${KAFS_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/kerberos_v4.m4 b/cmulocal/kerberos_v4.m4
new file mode 100644 (file)
index 0000000..8c3be39
--- /dev/null
@@ -0,0 +1,285 @@
+dnl kerberos_v4.m4--Kerberos 4 libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: kerberos_v4.m4,v 1.28 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_KRB_SENDAUTH_PROTO], [
+AC_MSG_CHECKING(for krb_sendauth prototype)
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_sendauth (long options, int fd, KTEXT ktext, char *service,
+                  char *inst, char *realm, u_long checksum,
+                  MSG_DAT *msg_data, CREDENTIALS *cred,
+                  Key_schedule schedule, struct sockaddr_in *laddr,
+                  struct sockaddr_in *faddr, char *version);],
+[int foo = krb_sendauth(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); ],
+ac_cv_krb_sendauth_proto=no,
+ac_cv_krb_sendauth_proto=yes)
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+if test "$ac_cv_krb_sendauth_proto" = yes; then
+        AC_DEFINE(HAVE_KRB_SENDAUTH_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+])
+
+AC_DEFUN([CMU_KRB_SET_KEY_PROTO], [
+AC_MSG_CHECKING(for krb_set_key prototype)
+AC_CACHE_VAL(ac_cv_krb_set_key_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_set_key(char *key, int cvt);],
+[int foo = krb_set_key(0, 0);],
+ac_cv_krb_set_key_proto=no,
+ac_cv_krb_set_key_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_set_key_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_SET_KEY_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_set_key_proto)
+])
+
+AC_DEFUN([CMU_KRB4_32_DEFN], [
+AC_MSG_CHECKING(for KRB4_32 definition)
+AC_CACHE_VAL(ac_cv_krb4_32_defn, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+],
+[KRB4_32 foo = 1;],
+ac_cv_krb4_32_defn=yes,
+ac_cv_krb4_32_defn=no)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb4_32_defn" = yes; then
+       AC_DEFINE(HAVE_KRB4_32_DEFINE)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb4_32_defn)
+])
+
+AC_DEFUN([CMU_KRB_RD_REQ_PROTO], [
+AC_MSG_CHECKING(for krb_rd_req prototype)
+AC_CACHE_VAL(ac_cv_krb_rd_req_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_rd_req(KTEXT authent, char *service, char *instance,
+unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn);],
+[int foo = krb_rd_req(0,0,0,0,0,0);],
+ac_cv_krb_rd_req_proto=no,
+ac_cv_krb_rd_req_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_rd_req_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_RD_REQ_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_rd_req_proto)
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <krb.h>],
+[struct ktext foo;],
+ac_cv_found_krb_inc=yes,
+ac_cv_found_krb_inc=no)
+if test "$ac_cv_found_krb_inc" = "no"; then
+  CPPFLAGS="$saved_CPPFLAGS -I$1 -I$1/kerberosIV"
+  AC_TRY_COMPILE([#include <krb.h>],
+  [struct ktext foo;],
+  [ac_cv_found_krb_inc=yes],
+  ac_cv_found_krb_inc=no)
+fi
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos headers in $i)
+      CMU_KRB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, krb)
+      if test "$ac_cv_found_krb_inc" = "yes"; then
+        ac_cv_krb_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for kerberos lib files
+#
+
+AC_DEFUN([CMU_KRB_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkrb ${KRB_LIBDES}"
+AC_TRY_LINK(,
+[dest_tkt();],
+[ac_cv_found_krb_lib=yes],
+ac_cv_found_krb_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_KRB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos libraries in $i)
+      CMU_KRB_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, krb)
+      if test "$ac_cv_found_krb_lib" = "yes" ; then
+        ac_cv_krb_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KRB4], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(krb4,
+       [  --with-krb4=PREFIX      Compile with Kerberos 4 support],
+       [if test "X$with_krb4" = "X"; then
+               with_krb4=yes
+       fi])
+AC_ARG_WITH(krb4-lib,
+       [  --with-krb4-lib=dir     use kerberos 4 libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-lib])
+       fi])
+AC_ARG_WITH(krb4-include,
+       [  --with-krb4-include=dir use kerberos 4 headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-include])
+       fi])
+
+       if test "X$with_krb4" != "X"; then
+         if test "$with_krb4" != "yes" -a "$with_krb4" != "no"; then
+           ac_cv_krb_where_lib=$with_krb4/$CMU_LIB_SUBDIR
+           ac_cv_krb_where_inc=$with_krb4/include
+         fi
+       fi
+       
+       if test "$with_krb4" != "no"; then
+         if test "X$with_krb4_lib" != "X"; then
+           ac_cv_krb_where_lib=$with_krb4_lib
+         fi
+         if test "X$with_krb4_include" != "X"; then
+           ac_cv_krb_where_inc=$with_krb4_include
+         fi
+         if test "X$ac_cv_krb_where_inc" = "X"; then
+           CMU_KRB_INC_WHERE(/usr/athena/include /usr/include/kerberosIV /usr/local/include /usr/include/kerberos)
+         fi
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],KRB_DES_LIB="",KRB_DES_LIB="maybe")
+          if test "X$KRB_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],KRB_DES_LIB="yes")
+              if test "X$KRB_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                  KRB_LIBDES="-ldes"
+                  KRB_LIBDESA='$(KRB_LIB_DIR)/libdes.a'
+              else
+                  LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                  AC_TRY_LINK([],
+                  [des_quad_cksum();],KRB_DES_LIB="libcrypto")
+                  if test "X$KRB_DES_LIB" = "Xlibcrypto"; then
+                      AC_MSG_RESULT([libcrypto])
+                      KRB_LIBDES="$LIBSSL_LIB_FLAGS"
+                      KRB_LIBDESA="$LIBSSL_LIB_FLAGS"
+                  else
+                      LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      AC_TRY_LINK([],
+                      [des_quad_cksum();],KRB_DES_LIB="libcrypto+descompat")
+                      if test "X$KRB_DES_LIB" = "Xlibcrypto+descompat"; then
+                          AC_MSG_RESULT([libcrypto+descompat])
+                          KRB_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                          KRB_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      else
+                          AC_MSG_RESULT([unknown])
+                          AC_MSG_ERROR([Could not use -ldes])
+                      fi 
+                  fi 
+              fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+          if test "X$ac_cv_krb_where_lib" = "X"; then
+            CMU_KRB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+          fi
+       fi
+         LIBS="${cmu_save_LIBS}"
+
+
+       AC_MSG_CHECKING([whether to include kerberos 4])
+       if test "X$ac_cv_krb_where_lib" = "X" -o "X$ac_cv_krb_where_inc" = "X"; then
+         ac_cv_found_krb=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_krb=yes
+         AC_MSG_RESULT(yes)
+         KRB_INC_DIR=$ac_cv_krb_where_inc
+         KRB_LIB_DIR=$ac_cv_krb_where_lib
+         KRB_INC_FLAGS="-I${KRB_INC_DIR}"
+         KRB_LIB_FLAGS="-L${KRB_LIB_DIR} -lkrb ${KRB_LIBDES}"
+         LIBS="${cmu_save_LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_LIB(resolv, dns_lookup, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lresolv",,"${KRB_LIB_FLAGS}")
+         AC_CHECK_LIB(crypt, crypt, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lcrypt",,"${KRB_LIB_FLAGS}")
+         LIBS="${LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_FUNCS(krb_get_int krb_life_to_time)
+          AC_SUBST(KRB_INC_FLAGS)
+          AC_SUBST(KRB_LIB_FLAGS)
+         LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(HAVE_KRB4,,[Kerberos V4 is present])dnl zephyr uses this
+         AC_DEFINE(KERBEROS,,[Use kerberos 4. find out what needs this symbol])
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${KRB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${KRB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${KRB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/kerberos_v5.m4 b/cmulocal/kerberos_v5.m4
new file mode 100644 (file)
index 0000000..a523af0
--- /dev/null
@@ -0,0 +1,185 @@
+dnl kerberos_v5.m4--Kerberos 5 libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: kerberos_v5.m4,v 1.9 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_KRB5_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <krb5.h>],
+[krb5_keyblock foo;],
+ac_cv_found_krb5_inc=yes,
+ac_cv_found_krb5_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_KRB5_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for krb5 headers in $i)
+      CMU_KRB5_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, krb5)
+      if test "$ac_cv_found_krb5_inc" = "yes"; then
+        ac_cv_krb5_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for kerberos lib files
+#
+
+AC_DEFUN([CMU_KRB5_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkrb5 -lk5crypto"
+AC_TRY_LINK(,
+[krb5_get_in_tkt();],
+[ac_cv_found_krb5_lib=yes],
+ac_cv_found_krb5_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_KRB5_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for krb5 libraries in $i)
+      CMU_KRB5_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, krb5)
+      if test "$ac_cv_found_krb5_lib" = "yes" ; then
+        ac_cv_krb5_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KRB5], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_USE_COMERR])
+AC_ARG_WITH(krb5,
+       [  --with-krb5=PREFIX      Compile with Kerberos 5 support],
+       [if test "X$with_krb5" = "X"; then
+               with_krb5=yes
+       fi])
+AC_ARG_WITH(krb5-lib,
+       [  --with-krb5-lib=dir     use kerberos 5 libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb5-lib])
+       fi])
+AC_ARG_WITH(krb5-include,
+       [  --with-krb5-include=dir use kerberos 5 headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb5-include])
+       fi])
+AC_ARG_WITH(krb5-impl,
+       [  --with-krb5-impl=heimdal use heimdal kerberos 5 libraries
+  --with-krb5-impl=mit     use MIT kerberos 5 libraries],
+       [if test "$withval" != "heimdal" -a "$withval" != "mit"; then
+               AC_MSG_ERROR([Invalid argument for --with-krb5-impl])
+       fi])
+
+       if test "X$with_krb5" != "X"; then
+         if test "$with_krb5" != "yes" -a "$with_krb5" != "no"; then
+           ac_cv_krb5_where_lib=$with_krb5/$CMU_LIB_SUBDIR
+           ac_cv_krb5_where_inc=$with_krb5/include
+           ac_cv_krb5_impl=mit
+         fi
+       fi
+
+       if test "$with_krb5" != "no"; then
+         if test "X$with_krb5_lib" != "X"; then
+           ac_cv_krb5_where_lib=$with_krb5_lib
+           ac_cv_krb5_impl=mit
+         fi
+         if test "X$with_krb5_impl" != "X"; then
+           ac_cv_krb5_impl=$with_krb5_impl
+         fi
+         if test "X$ac_cv_krb5_where_lib" = "X" -a "X$with_krb5_impl" != "Xheimdal"; then
+           CMU_KRB5_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+           if test "X$ac_cv_krb5_where_lib" != "X"; then
+              ac_cv_krb5_impl=mit
+           fi
+         fi
+         if test "X$ac_cv_krb5_where_lib" = "X" -a "X$with_krb5_impl" != "Xmit"; then
+           CMU_LIBHEIMDAL_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/heimdal/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+           if test "X$ac_cv_libheimdal_where_lib" != "X"; then
+             ac_cv_krb5_where_lib=$ac_cv_libheimdal_where_lib
+             ac_cv_krb5_impl=heimdal
+           fi
+         fi
+
+         if test "X$with_krb5_include" != "X"; then
+           ac_cv_krb5_where_inc=$with_krb5_include
+         fi
+         if test "X$ac_cv_krb5_where_inc" = "X"; then
+           CMU_KRB5_INC_WHERE(/usr/athena/include /usr/include/kerberos /usr/local/include /usr/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include kerberos 5)
+       if test "X$ac_cv_krb5_where_lib" = "X" -o "X$ac_cv_krb5_where_inc" = "X"; then
+         ac_cv_found_krb5=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_krb5=yes
+         AC_MSG_RESULT(yes)
+         KRB5_INC_DIR=$ac_cv_krb5_where_inc
+         KRB5_LIB_DIR=$ac_cv_krb5_where_lib
+         if test "X$ac_cv_krb5_impl" != "Xheimdal"; then
+           KRB5_LIB_FLAGS="-L${KRB5_LIB_DIR} -lkrb5 -lk5crypto"
+         else
+           CMU_LIBHEIMDAL_LIBDES($KRB5_LIB_DIR)
+           KRB5_LIB_FLAGS="-L${KRB5_LIB_DIR} -lkadm5clnt -lkrb5 -lasn1 ${HEIM_LIBDES} -lroken $LIB_SOCKET"
+           AC_DEFINE(HEIMDAL,,[we found heimdal krb5 and not MIT krb5])
+         fi
+         KRB5_INC_FLAGS="-I${KRB5_INC_DIR}"
+         AC_SUBST(KRB5_INC_FLAGS)
+         AC_SUBST(KRB5_LIB_FLAGS)
+         AC_DEFINE(HAVE_KRB5,,[Kerberos V5 is present])dnl zephyr uses this
+         AC_DEFINE(KRB5,,[Use Kerberos 5. (maybe find what needs this and nuke it)])
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB5_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB5_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${KRB5_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB5_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB5_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB5_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${KRB5_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${KRB5_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${KRB5_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/libXau.m4 b/cmulocal/libXau.m4
new file mode 100644 (file)
index 0000000..1000811
--- /dev/null
@@ -0,0 +1,147 @@
+dnl $Id: libXau.m4,v 1.5 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_XAU_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([
+#include <X11/Xauth.h>
+],
+[Xauth foo;],
+ac_cv_found_Xau_inc=yes,
+ac_cv_found_Xau_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_XAU_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for Xau headers in $i)
+      CMU_XAU_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, X11/Xauth)
+      if test "$ac_cv_found_Xau_inc" = "yes"; then
+        ac_cv_Xau_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_XAU_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lXau $LIB_SOCKET"
+AC_TRY_LINK(,
+[XauDisposeAuth();],
+[ac_cv_found_Xau_lib=yes],
+ac_cv_found_Xau_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_XAU_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for Xau libraries in $i)
+      CMU_XAU_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, Xau)
+      if test "$ac_cv_found_Xau_lib" = "yes" ; then
+        ac_cv_Xau_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_XAU], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(Xau,
+       [  --with-Xau=PREFIX      Compile with Xau support],
+       [if test "X$with_Xau" = "X"; then
+               with_Xau=yes
+       fi])
+AC_ARG_WITH(Xau-lib,
+       [  --with-Xau-lib=dir     use Xau libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-Xau-lib])
+       fi])
+AC_ARG_WITH(Xau-include,
+       [  --with-Xau-include=dir use Xau headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-Xau-include])
+       fi])
+
+       if test "X$with_Xau" != "X"; then
+         if test "$with_Xau" != "yes"; then
+           ac_cv_Xau_where_lib=$with_Xau/$CMU_LIB_SUBDIR
+           ac_cv_Xau_where_inc=$with_Xau/include
+         fi
+       fi
+
+       if test "X$with_Xau_lib" != "X"; then
+         ac_cv_Xau_where_lib=$with_Xau_lib
+       fi
+       if test "X$ac_cv_Xau_where_lib" = "X"; then
+         CMU_XAU_LIB_WHERE(/usr/X11R6/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/openwin/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_Xau_include" != "X"; then
+         ac_cv_Xau_where_inc=$with_Xau_include
+       fi
+       if test "X$ac_cv_Xau_where_inc" = "X"; then
+         CMU_XAU_INC_WHERE(/usr/X11R6/include /usr/local/include /usr/openwin/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include Xau)
+       if test "X$ac_cv_Xau_where_lib" = "X" -a "X$ac_cv_Xau_where_inc" = "X"; then
+         ac_cv_found_Xau=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_Xau=yes
+         AC_MSG_RESULT(yes)
+         XAU_INC_DIR=$ac_cv_Xau_where_inc
+         XAU_LIB_DIR=$ac_cv_Xau_where_lib
+         XAU_INC_FLAGS="-I${XAU_INC_DIR}"
+         XAU_LIB_FLAGS="-L${XAU_LIB_DIR} -lXau"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${XAU_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${XAU_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${XAU_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${XAU_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${XAU_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${XAU_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${XAU_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${XAU_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${XAU_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/libcyrus.m4 b/cmulocal/libcyrus.m4
new file mode 100644 (file)
index 0000000..1b142dc
--- /dev/null
@@ -0,0 +1,155 @@
+dnl libcyrus.m4--Cyrus libraries and includes
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: libcyrus.m4,v 1.20 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBCYRUS_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1 $SASLFLAGS"
+CMU_CHECK_HEADER_NOCACHE(cyrus/imclient.h,
+ac_cv_found_cyrus_inc=yes,
+ac_cv_found_cyrus_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_LIBCYRUS_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libcyrus headers in $i)
+      CMU_LIBCYRUS_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, imclient)
+      if test "$ac_cv_found_cyrus_inc" = "yes"; then
+        ac_cv_cyrus_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBCYRUS_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lcyrus ${LIB_SASL} ${LIBSSL_LIB_FLAGS} ${LIB_SOCKET}"
+AC_TRY_LINK([void fatal(){}],
+[imclient_authenticate();],
+[ac_cv_found_cyrus_lib=yes],
+ac_cv_found_cyrus_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBCYRUS_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libcyrus libraries in $i)
+      CMU_LIBCYRUS_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, cyrus)
+      if test "$ac_cv_found_cyrus_lib" = "yes" ; then
+        ac_cv_cyrus_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBCYRUS], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_SASL2])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(libcyrus,
+       [  --with-libcyrus=PREFIX      Compile with Libcyrus support],
+       [if test "X$with_libcyrus" = "X"; then
+               with_libcyrus=yes
+       fi])
+AC_ARG_WITH(libcyrus-lib,
+       [  --with-libcyrus-lib=dir     use libcyrus libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libcyrus-lib])
+       fi])
+AC_ARG_WITH(libcyrus-include,
+       [  --with-libcyrus-include=dir use libcyrus headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libcyrus-include])
+       fi])
+
+       if test "X$with_libcyrus" != "X"; then
+         if test "$with_libcyrus" != "yes" -a "$with_libcyrus" != no; then
+           ac_cv_cyrus_where_lib=$with_libcyrus/$CMU_LIB_SUBDIR
+           ac_cv_cyrus_where_inc=$with_libcyrus/include
+         fi
+       fi
+
+       if test "$with_libcyrus" != "no"; then 
+         if test "X$with_libcyrus_lib" != "X"; then
+           ac_cv_cyrus_where_lib=$with_libcyrus_lib
+         fi
+         if test "X$ac_cv_cyrus_where_lib" = "X"; then
+           CMU_LIBCYRUS_LIB_WHERE(/usr/cyrus/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_libcyrus_include" != "X"; then
+           ac_cv_cyrus_where_inc=$with_libcyrus_include
+         fi
+         if test "X$ac_cv_cyrus_where_inc" = "X"; then
+           CMU_LIBCYRUS_INC_WHERE(/usr/cyrus/include /usr/local/include /usr/local/include/cyrus /usr/include/cyrus)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include libcyrus)
+       if test "X$ac_cv_cyrus_where_lib" = "X" -o "X$ac_cv_cyrus_where_inc" = "X"; then
+         ac_cv_found_cyrus=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_cyrus=yes
+         AC_MSG_RESULT(yes)
+         LIBCYRUS_INC_DIR=$ac_cv_cyrus_where_inc
+         LIBCYRUS_LIB_DIR=$ac_cv_cyrus_where_lib
+         LIBCYRUS_INC_FLAGS="-I${LIBCYRUS_INC_DIR}"
+         LIBCYRUS_LIB_FLAGS="-L${LIBCYRUS_LIB_DIR} -lcyrus"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBCYRUS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBCYRUS_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBCYRUS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBCYRUS_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBCYRUS_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBCYRUS_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBCYRUS_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBCYRUS_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBCYRUS_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       AC_SUBST(LIBCYRUS_INC_DIR)
+       AC_SUBST(LIBCYRUS_LIB_DIR)
+       AC_SUBST(LIBCYRUS_INC_FLAGS)
+       AC_SUBST(LIBCYRUS_LIB_FLAGS)
+       ])
+
diff --git a/cmulocal/libloguse.m4 b/cmulocal/libloguse.m4
new file mode 100644 (file)
index 0000000..ca3e901
--- /dev/null
@@ -0,0 +1,103 @@
+dnl libloguse.m4--LOGUSE libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: libloguse.m4,v 1.7 2006/02/25 18:26:22 cg2v Exp $
+
+AC_DEFUN([CMU_LOGUSE_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lloguse"
+AC_TRY_LINK(,
+[loguse("","","");],
+[ac_cv_found_loguse_lib=yes],
+ac_cv_found_loguse_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LOGUSE_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for loguse library in $i)
+      CMU_LOGUSE_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, loguse)
+      if test "$ac_cv_found_loguse_lib" = "yes" ; then
+        ac_cv_loguse_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(no found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LOGUSE], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(loguse,
+       [  --with-loguse=PREFIX      Compile with LOGUSE support],
+       [if test "X$with_loguse" = "X"; then
+               with_loguse=yes
+       fi])
+
+       if test "X$with_loguse" != "X"; then
+         if test "$with_loguse" != "yes"; then
+           ac_cv_loguse_where_lib=$with_loguse/$CMU_LIB_SUBDIR
+         fi
+       fi
+
+       if test "X$with_loguse_lib" != "X"; then
+         ac_cv_loguse_where_lib=$with_loguse_lib
+       fi
+       if test "X$ac_cv_loguse_where_lib" = "X"; then
+         CMU_LOGUSE_LIB_WHERE(/usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       AC_MSG_CHECKING(whether to include loguse)
+       if test "X$ac_cv_loguse_where_lib" = "X"; then
+         ac_cv_found_loguse=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_loguse=yes
+         AC_DEFINE(HAVE_LOGUSE,, [Use libloguse])
+         AC_MSG_RESULT(yes)
+         LOGUSE_LIB_DIR=$ac_cv_loguse_where_lib
+         LOGUSE_LIB_FLAGS="-L${LOGUSE_LIB_DIR} -lloguse"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LOGUSE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LOGUSE_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LOGUSE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LOGUSE_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LOGUSE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LOGUSE_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LOGUSE_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LOGUSE_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LOGUSE_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/libnet.m4 b/cmulocal/libnet.m4
new file mode 100644 (file)
index 0000000..670564b
--- /dev/null
@@ -0,0 +1,192 @@
+dnl libnet.m4--libnet and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: libnet.m4,v 1.8 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBNET_CFG_WHERE1], [
+ac_cv_found_libnet_bin=no
+if test -f "$1/libnet-config" ; then
+  ac_cv_found_libnet_cfg=yes
+fi
+])
+
+AC_DEFUN([CMU_LIBNET_CFG_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libnet config in $i)
+      CMU_LIBNET_CFG_WHERE1($i)
+      if test "$ac_cv_found_libnet_cfg" = "yes"; then
+        ac_cv_libnet_where_cfg=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBNET_INC_WHERE1], [
+ac_cv_found_libnet_inc=no
+if test -f "$1/libnet.h" ; then
+  ac_cv_found_libnet_inc=yes
+fi
+])
+
+AC_DEFUN([CMU_LIBNET_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libnet header in $i)
+      CMU_LIBNET_INC_WHERE1($i)
+      if test "$ac_cv_found_libnet_inc" = "yes"; then
+        ac_cv_libnet_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBNET_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lnet"
+AC_TRY_LINK(,
+[open_link_interface("","");],
+[ac_cv_found_libnet_lib=yes],
+AC_TRY_LINK(,
+[libnet_open_link_interface("","");],
+[
+CMU_LIBNET_CFLAGS_ADD="-DNEW_LIBNET_INTERFACE"
+ac_cv_found_libnet_lib=yes
+],
+ac_cv_found_libnet_lib=no)
+)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBNET_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libnet library in $i)
+      CMU_LIBNET_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, net)
+      if test "$ac_cv_found_libnet_lib" = "yes" ; then
+        ac_cv_libnet_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBNET], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(libnet,
+       [  --with-libnet=PREFIX      Compile with LIBNET support],
+       [if test "X$with_libnet" = "X"; then
+               with_libnet=yes
+       fi])
+AC_ARG_WITH(libnet-config,
+       [  --with-libnet-config=dir  use libnet config program in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libnet-config])
+       fi])
+AC_ARG_WITH(libnet-lib,
+       [  --with-libnet-lib=dir     use libnet libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libnet-lib])
+       fi])
+AC_ARG_WITH(libnet-include,
+       [  --with-libnet-include=dir use libnet headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libnet-include])
+       fi])
+
+       if test "X$with_libnet" != "X"; then
+         if test "$with_libnet" != "yes"; then
+            if test -f "$with_libnet/libnet-config"; then
+             ac_cv_libnet_where_cfg=$with_libnet
+            else
+             ac_cv_libnet_where_cfg=$with_libnet/bin
+            fi
+           ac_cv_libnet_where_lib=$with_libnet/$CMU_LIB_SUBDIR
+           ac_cv_libnet_where_inc=$with_libnet/include
+         fi
+       fi
+
+       if test "X$with_libnet_cfg" != "X"; then
+         ac_cv_libnet_where_cfg=$with_libnet_cfg
+       fi
+       if test "X$ac_cv_libnet_where_cfg" = "X"; then
+         CMU_LIBNET_CFG_WHERE(/usr/ng/bin /usr/bin /usr/local/bin)
+       fi
+
+       if test "X$with_libnet_lib" != "X"; then
+         ac_cv_libnet_where_lib=$with_libnet_lib
+       fi
+       if test "X$ac_cv_libnet_where_lib" = "X"; then
+         CMU_LIBNET_LIB_WHERE(/usr/ng/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_libnet_include" != "X"; then
+         ac_cv_libnet_where_inc=$with_libnet_include
+       fi
+       if test "X$ac_cv_libnet_where_inc" = "X"; then
+         CMU_LIBNET_INC_WHERE(/usr/ng/include /usr/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include libnet)
+       if test "X$ac_cv_libnet_where_lib" = "X" -o "X$ac_cv_libnet_where_inc" = "X" -o "X$ac_cv_libnet_where_cfg" = "X"; then
+         ac_cv_found_libnet=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_libnet=yes
+         AC_MSG_RESULT(yes)
+         LIBNET_CONFIG=$ac_cv_libnet_where_cfg/libnet-config
+         LIBNET_INC_DIR=$ac_cv_libnet_where_inc
+         LIBNET_LIB_DIR=$ac_cv_libnet_where_lib
+
+         LIBNET_CFLAGS="`$LIBNET_CONFIG --cflags` ${CMU_LIBNET_CFLAGS_ADD}"
+         LIBNET_DEF_FLAGS="`$LIBNET_CONFIG --defines`"
+         LIBNET_INC_FLAGS="-I${LIBNET_INC_DIR}"
+         LIBNET_LIB_FLAGS="-L${LIBNET_LIB_DIR} `${LIBNET_CONFIG} --libs`"
+
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBNET_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBNET_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBNET_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBNET_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBNET_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBNET_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBNET_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBNET_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBNET_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/libpcap.m4 b/cmulocal/libpcap.m4
new file mode 100644 (file)
index 0000000..4796ab9
--- /dev/null
@@ -0,0 +1,142 @@
+dnl libpcap.m4--PCAP libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: libpcap.m4,v 1.9 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_PCAP_INC_WHERE1], [
+ac_cv_found_pcap_inc=no
+if test -f "$1/pcap.h" ; then
+  ac_cv_found_pcap_inc=yes
+fi
+])
+
+AC_DEFUN([CMU_PCAP_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for pcap header in $i)
+      CMU_PCAP_INC_WHERE1($i)
+      if test "$ac_cv_found_pcap_inc" = "yes"; then
+        ac_cv_pcap_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(no found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_PCAP_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lpcap"
+AC_TRY_LINK(,
+[pcap_lookupdev("");],
+[ac_cv_found_pcap_lib=yes],
+ac_cv_found_pcap_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_PCAP_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for pcap library in $i)
+      CMU_PCAP_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, pcap)
+      if test "$ac_cv_found_pcap_lib" = "yes" ; then
+        ac_cv_pcap_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(no found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_PCAP], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(pcap,
+       [  --with-pcap=PREFIX      Compile with PCAP support],
+       [if test "X$with_pcap" = "X"; then
+               with_pcap=yes
+       fi])
+AC_ARG_WITH(pcap-lib,
+       [  --with-pcap-lib=dir     use pcap libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-pcap-lib])
+       fi])
+AC_ARG_WITH(pcap-include,
+       [  --with-pcap-include=dir use pcap headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-pcap-include])
+       fi])
+
+       if test "X$with_pcap" != "X"; then
+         if test "$with_pcap" != "yes"; then
+           ac_cv_pcap_where_lib=$with_pcap/$CMU_LIB_SUBDIR
+           ac_cv_pcap_where_inc=$with_pcap/include
+         fi
+       fi
+
+       if test "X$with_pcap_lib" != "X"; then
+         ac_cv_pcap_where_lib=$with_pcap_lib
+       fi
+       if test "X$ac_cv_pcap_where_lib" = "X"; then
+         CMU_PCAP_LIB_WHERE(/usr/ng/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_pcap_include" != "X"; then
+         ac_cv_pcap_where_inc=$with_pcap_include
+       fi
+       if test "X$ac_cv_pcap_where_inc" = "X"; then
+         CMU_PCAP_INC_WHERE(/usr/ng/include /usr/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include pcap)
+       if test "X$ac_cv_pcap_where_lib" = "X" -a "X$ac_cv_pcap_where_inc" = "X"; then
+         ac_cv_found_pcap=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_pcap=yes
+         AC_MSG_RESULT(yes)
+         PCAP_INC_DIR=$ac_cv_pcap_where_inc
+         PCAP_LIB_DIR=$ac_cv_pcap_where_lib
+         PCAP_INC_FLAGS="-I${PCAP_INC_DIR}"
+         PCAP_LIB_FLAGS="-L${PCAP_LIB_DIR} -lpcap"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${PCAP_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${PCAP_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${PCAP_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${PCAP_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${PCAP_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${PCAP_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${PCAP_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${PCAP_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${PCAP_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/librestrict.m4 b/cmulocal/librestrict.m4
new file mode 100644 (file)
index 0000000..ec80b93
--- /dev/null
@@ -0,0 +1,102 @@
+dnl librestrict.m4--restrict libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: librestrict.m4,v 1.6 2006/02/25 18:26:22 cg2v Exp $
+
+AC_DEFUN([CMU_RESTRICT_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lrestrict"
+AC_TRY_LINK(,
+[ConsoleInUse();],
+[ac_cv_found_restrict_lib=yes],
+ac_cv_found_restrict_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_RESTRICT_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for restrict library in $i)
+      CMU_RESTRICT_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, restrict)
+      if test "$ac_cv_found_restrict_lib" = "yes" ; then
+        ac_cv_restrict_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(no found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_RESTRICT], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(restrict,
+       [  --with-restrict=PREFIX      Compile with RESTRICT support],
+       [if test "X$with_restrict" = "X"; then
+               with_restrict=yes
+       fi])
+
+       if test "X$with_restrict" != "X"; then
+         if test "$with_restrict" != "yes"; then
+           ac_cv_restrict_where_lib=$with_restrict/$CMU_LIB_SUBDIR
+         fi
+       fi
+
+       if test "X$with_restrict_lib" != "X"; then
+         ac_cv_restrict_where_lib=$with_restrict_lib
+       fi
+       if test "X$ac_cv_restrict_where_lib" = "X"; then
+         CMU_RESTRICT_LIB_WHERE(/usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       AC_MSG_CHECKING(whether to include restrict)
+       if test "X$ac_cv_restrict_where_lib" = "X"; then
+         ac_cv_found_restrict=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_restrict=yes
+         AC_DEFINE(HAVE_RESTRICT,, [Use librestrict])
+         AC_MSG_RESULT(yes)
+         RESTRICT_LIB_DIR=$ac_cv_restrict_where_lib
+         RESTRICT_LIB_FLAGS="-L${RESTRICT_LIB_DIR} -lrestrict"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${RESTRICT_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${RESTRICT_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${RESTRICT_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${RESTRICT_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${RESTRICT_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${RESTRICT_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${RESTRICT_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${RESTRICT_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${RESTRICT_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
diff --git a/cmulocal/libssl.m4 b/cmulocal/libssl.m4
new file mode 100644 (file)
index 0000000..4d1b2a1
--- /dev/null
@@ -0,0 +1,153 @@
+dnl libssl.m4--Ssl libraries and includes
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: libssl.m4,v 1.10 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+CMU_CHECK_HEADER_NOCACHE(openssl/ssl.h,
+ac_cv_found_libssl_inc=yes,
+ac_cv_found_libssl_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl headers in $i)
+      CMU_LIBSSL_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, ssl)
+      if test "$ac_cv_found_libssl_inc" = "yes"; then
+        ac_cv_libssl_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lssl -lcrypto $LIB_SOCKET"
+AC_TRY_LINK(,
+[SSL_write();],
+[ac_cv_found_ssl_lib=yes],
+ac_cv_found_ssl_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl libraries in $i)
+      CMU_LIBSSL_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, ssl)
+      if test "$ac_cv_found_ssl_lib" = "yes" ; then
+        ac_cv_libssl_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(libssl,
+       [  --with-libssl=PREFIX      Compile with Libssl support],
+       [if test "X$with_libssl" = "X"; then
+               with_libssl=yes
+       fi])
+AC_ARG_WITH(libssl-lib,
+       [  --with-libssl-lib=dir     use libssl libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-lib])
+       fi])
+AC_ARG_WITH(libssl-include,
+       [  --with-libssl-include=dir use libssl headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-include])
+       fi])
+
+       if test "X$with_libssl" != "X"; then
+         if test "$with_libssl" != "yes" -a "$with_libssl" != no; then
+           ac_cv_libssl_where_lib=$with_libssl/$CMU_LIB_SUBDIR
+           ac_cv_libssl_where_inc=$with_libssl/include
+         fi
+       fi
+
+       if test "$with_libssl" != "no"; then 
+         if test "X$with_libssl_lib" != "X"; then
+           ac_cv_libssl_where_lib=$with_libssl_lib
+         fi
+         if test "X$ac_cv_libssl_where_lib" = "X"; then
+           CMU_LIBSSL_LIB_WHERE(/usr/local/$CMU_LIB_SUBDIR/openssl /usr/$CMU_LIB_SUBDIR/openssl /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_libssl_include" != "X"; then
+           ac_cv_libssl_where_inc=$with_libssl_include
+         fi
+         if test "X$ac_cv_libssl_where_inc" = "X"; then
+           CMU_LIBSSL_INC_WHERE(/usr/local/include /usr/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include libssl)
+       if test "X$ac_cv_libssl_where_lib" = "X" -a "X$ac_cv_libssl_where_inc" = "X"; then
+         ac_cv_found_libssl=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_libssl=yes
+         AC_MSG_RESULT(yes)
+         LIBSSL_INC_DIR=$ac_cv_libssl_where_inc
+         LIBSSL_LIB_DIR=$ac_cv_libssl_where_lib
+         LIBSSL_INC_FLAGS="-I${LIBSSL_INC_DIR}"
+         LIBSSL_LIB_FLAGS="-L${LIBSSL_LIB_DIR} -lssl -lcrypto"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBSSL_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       AC_SUBST(LIBSSL_INC_DIR)
+       AC_SUBST(LIBSSL_LIB_DIR)
+       AC_SUBST(LIBSSL_INC_FLAGS)
+       AC_SUBST(LIBSSL_LIB_FLAGS)
+       ])
+
diff --git a/cmulocal/libtoolhack.m4 b/cmulocal/libtoolhack.m4
new file mode 100644 (file)
index 0000000..be1dc2c
--- /dev/null
@@ -0,0 +1,33 @@
+dnl libtoolhack.m4--hack to make libtool behave better
+dnl Rob Earhart
+dnl $Id: libtoolhack.m4,v 1.4 2003/10/08 20:35:25 rjs3 Exp $
+
+dnl Libtool tries to compile an empty file to see whether it can build
+dnl shared libraries, and treats *any* warning as a problem.
+dnl Solaris's and HP's cc complains about the empty file.  So we hack
+dnl the CFLAGS to make cc not complain.
+
+AC_DEFUN([CMU_PROG_LIBTOOL], [
+AC_REQUIRE([AC_PROG_CC])
+if test "$ac_cv_prog_gcc" = no; then
+  case "$host_os" in
+    solaris2*)
+      save_cflags="${CFLAGS}"
+      CFLAGS="-erroff=E_EMPTY_TRANSLATION_UNIT ${CFLAGS}"
+      ;;
+    hpux*)
+      save_cflags="${CFLAGS}"
+      CFLAGS="-w"
+      ;;
+  esac
+fi
+
+AC_PROG_LIBTOOL
+
+if test "$ac_cv_prog_gcc" = no; then
+  case "$host_os" in
+    solaris2*|hpux*)
+      CFLAGS="${save_cflags}"
+  esac
+fi
+])
diff --git a/cmulocal/libwrap.m4 b/cmulocal/libwrap.m4
new file mode 100644 (file)
index 0000000..876a49c
--- /dev/null
@@ -0,0 +1,30 @@
+dnl libwrap.m4 --- do we have libwrap, the access control library?
+dnl $Id: libwrap.m4,v 1.10 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBWRAP], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+  AC_REQUIRE([CMU_SOCKETS])
+  AC_ARG_WITH(libwrap, 
+              [  --with-libwrap=DIR      use libwrap (rooted in DIR) [yes] ],
+              with_libwrap=$withval, with_libwrap=yes)
+  if test "$with_libwrap" != no; then
+    if test -d "$with_libwrap"; then
+      CPPFLAGS="$CPPFLAGS -I${with_libwrap}/include"
+      LDFLAGS="$LDFLAGS -L${with_libwrap}/$CMU_LIB_SUBDIR"
+    fi
+    cmu_save_LIBS="$LIBS"
+    AC_CHECK_LIB(wrap, request_init, [
+                AC_CHECK_HEADER(tcpd.h,, with_libwrap=no)],
+                with_libwrap=no, ${LIB_SOCKET})
+    LIBS="$cmu_save_LIBS"
+  fi
+  AC_MSG_CHECKING(libwrap support)
+  AC_MSG_RESULT($with_libwrap)
+  LIB_WRAP=""
+  if test "$with_libwrap" != no; then
+    AC_DEFINE(HAVE_LIBWRAP,[],[Do we have TCP wrappers?])
+    LIB_WRAP="-lwrap"
+    AC_CHECK_LIB(nsl, yp_get_default_domain, LIB_WRAP="${LIB_WRAP} -lnsl")
+  fi
+  AC_SUBST(LIB_WRAP)
+])
diff --git a/cmulocal/mips-abi.m4 b/cmulocal/mips-abi.m4
new file mode 100644 (file)
index 0000000..a58a126
--- /dev/null
@@ -0,0 +1,93 @@
+dnl mips-abi.m4--Check for MIPS/IRIX ABI flags. Sets $abi and $abilibdirext
+dnl to some value
+dnl Derrick Brashear
+dnl from KTH krb (from CMU)
+dnl $Id: mips-abi.m4,v 1.5 2003/10/08 20:35:25 rjs3 Exp $
+
+AC_DEFUN([AC_MIPS_ABI], [
+AC_ARG_WITH(mips_abi,
+[  --with-mips-abi=abi     ABI to use for IRIX (32, n32, or 64)])
+
+case "$host_os" in
+irix*)
+with_mips_abi="${with_mips_abi:-yes}"
+if test -n "$GCC"; then
+
+# GCC < 2.8 only supports the O32 ABI. GCC >= 2.8 has a flag to select
+# which ABI to use, but only supports (as of 2.8.1) the N32 and 64 ABIs.
+#
+# Default to N32, but if GCC doesn't grok -mabi=n32, we assume an old
+# GCC and revert back to O32. The same goes if O32 is asked for - old
+# GCCs doesn't like the -mabi option, and new GCCs can't output O32.
+#
+# Don't you just love *all* the different SGI ABIs?
+
+case "${with_mips_abi}" in 
+        32|o32) abi='-mabi=32';  abilibdirext=''     ;;
+       n32|yes) abi='-mabi=n32'; abilibdirext='32'  ;;
+        64) abi='-mabi=64';  abilibdirext='64'   ;;
+       no) abi=''; abilibdirext='';;
+         *) AC_ERROR("Invalid ABI specified") ;;
+esac
+if test -n "$abi" ; then
+ac_foo=krb_cv_gcc_`echo $abi | tr =- __`
+dnl
+dnl can't use AC_CACHE_CHECK here, since it doesn't quote CACHE-ID to
+dnl AC_MSG_RESULT
+dnl
+AC_MSG_CHECKING([if $CC supports the $abi option])
+AC_CACHE_VAL($ac_foo, [
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $abi"
+AC_TRY_COMPILE(,int x;, eval $ac_foo=yes, eval $ac_foo=no)
+CFLAGS="$save_CFLAGS"
+])
+ac_res=`eval echo \\\$$ac_foo`
+AC_MSG_RESULT($ac_res)
+if test $ac_res = no; then
+# Try to figure out why that failed...
+case $abi in
+       -mabi=32) 
+       save_CFLAGS="$CFLAGS"
+       CFLAGS="$CFLAGS -mabi=n32"
+       AC_TRY_COMPILE(,int x;, ac_res=yes, ac_res=no)
+       CLAGS="$save_CFLAGS"
+       if test $ac_res = yes; then
+               # New GCC
+               AC_ERROR([$CC does not support the $with_mips_abi ABI])
+       fi
+       # Old GCC
+       abi=''
+       abilibdirext=''
+       ;;
+       -mabi=n32|-mabi=64)
+               if test $with_mips_abi = yes; then
+                       # Old GCC, default to O32
+                       abi=''
+                       abilibdirext=''
+               else
+                       # Some broken GCC
+                       AC_ERROR([$CC does not support the $with_mips_abi ABI])
+               fi
+       ;;
+esac
+fi #if test $ac_res = no; then
+fi #if test -n "$abi" ; then
+else
+case "${with_mips_abi}" in
+        32|o32) abi='-32'; abilibdirext=''     ;;
+       n32|yes) abi='-n32'; abilibdirext='32'  ;;
+        64) abi='-64'; abilibdirext='64'   ;;
+       no) abi=''; abilibdirext='';;
+         *) AC_ERROR("Invalid ABI specified") ;;
+esac
+fi #if test -n "$GCC"; then
+;;
+esac
+
+dnl And then we munge variables to make things work
+CFLAGS="${CFLAGS} $abi"
+libdir=`echo $libdir | sed 's,/*$,$abilibdirext,'`
+LDFLAGS=`echo $LDFLAGS | sed -e "s,/lib$,/lib$abilibdirext," -e "s,\\\(/lib[^a-zA-Z]\\\),\\\1$abilibdirext,g"`
+
+])
diff --git a/cmulocal/nadine.m4 b/cmulocal/nadine.m4
new file mode 100644 (file)
index 0000000..59cc787
--- /dev/null
@@ -0,0 +1,164 @@
+dnl nadine.m4--The nadine event library
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: nadine.m4,v 1.6 2003/10/08 20:35:25 rjs3 Exp $
+
+AC_DEFUN([CMU_NADINE_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+CMU_CHECK_HEADER_NOCACHE(libevent/libevent.h,
+ac_cv_found_event_inc=yes,
+ac_cv_found_event_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_NADINE_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for nadine headers in $i)
+      CMU_NADINE_INC_WHERE1($i)
+dnl      CMU_TEST_INCPATH($i, ssl)
+dnl   CMU_TEST_INCPATH isn't very versatile
+      if test "$ac_cv_found_event_inc" = "yes"; then
+        if test \! -f $i/libevent/libevent.h ; then
+          ac_cv_found_event_inc=no
+        fi
+      fi
+      if test "$ac_cv_found_event_inc" = "yes"; then
+        ac_cv_event_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_NADINE_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -levent"
+AC_TRY_LINK(,
+[libevent_Initialize();],
+[ac_cv_found_event_lib=yes],
+ac_cv_found_event_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_NADINE_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for event libraries in $i)
+      CMU_NADINE_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, event)
+      if test "$ac_cv_found_event_lib" = "yes" ; then
+        ac_cv_event_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_NADINE], [
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(nadine,
+       [  --with-nadine=PREFIX      Compile with nadine libevent support],
+       [if test "X$with_nadine" = "X"; then
+               with_nadine=yes
+       fi])
+AC_ARG_WITH(nadine-lib,
+       [  --with-nadine-lib=dir     use nadine libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-nadine-lib])
+       fi])
+AC_ARG_WITH(nadine-include,
+       [  --with-nadine-include=dir use nadine headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-nadine-include])
+       fi])
+
+        if test "$with_ucdsnmp" = "no" ; then
+             AC_MSG_WARN([Nadine requires UCD SNMP. Disabling Nadine support])
+             with_nadine=no
+             with_nadine_lib=no
+             with_nadine_include=no
+        fi
+       if test "X$with_nadine" != "X"; then
+         if test "$with_nadine" != "yes" -a "$with_nadine" != no; then
+           ac_cv_event_where_lib=$with_nadine/lib
+           ac_cv_event_where_inc=$with_nadine/include
+         fi
+       fi
+
+       if test "$with_nadine" != "no"; then 
+         if test "X$with_nadine_lib" != "X"; then
+           ac_cv_event_where_lib=$with_nadine_lib
+         fi
+         if test "X$ac_cv_event_where_lib" = "X"; then
+           CMU_NADINE_LIB_WHERE(/usr/local/lib /usr/ng/lib /usr/lib)
+         fi
+
+         if test "X$with_nadine_include" != "X"; then
+           ac_cv_event_where_inc=$with_nadine_include
+         fi
+         if test "X$ac_cv_event_where_inc" = "X"; then
+           CMU_NADINE_INC_WHERE(/usr/local/include /usr/ng/include /usr/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include nadine)
+       if test "X$ac_cv_event_where_lib" = "X" -a "X$ac_cv_event_where_inc" = "X"; then
+         ac_cv_found_event=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_event=yes
+         AC_MSG_RESULT(yes)
+         NADINE_INC_DIR=$ac_cv_event_where_inc
+         NADINE_LIB_DIR=$ac_cv_event_where_lib
+         NADINE_INC_FLAGS="-I${NADINE_INC_DIR}"
+         NADINE_LIB_FLAGS="-L${NADINE_LIB_DIR} -levent"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${NADINE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${NADINE_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${NADINE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${NADINE_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${NADINE_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${NADINE_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${NADINE_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${NADINE_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${NADINE_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       AC_SUBST(NADINE_INC_DIR)
+       AC_SUBST(NADINE_LIB_DIR)
+       AC_SUBST(NADINE_INC_FLAGS)
+       AC_SUBST(NADINE_LIB_FLAGS)
+       ])
+
diff --git a/cmulocal/nana.m4 b/cmulocal/nana.m4
new file mode 100644 (file)
index 0000000..4c280e0
--- /dev/null
@@ -0,0 +1,27 @@
+dnl nana.m4--nana macro
+dnl Rob Earhart
+dnl $Id: nana.m4,v 1.5 2003/10/08 20:35:25 rjs3 Exp $
+
+AC_DEFUN([CMU_NANA], [
+  AC_REQUIRE([AC_PROG_CC])
+  AC_ARG_WITH(nana, [[  --with-nana             use NANA [yes] ]],,with_nana=yes)
+  if test "$GCC" != yes; then
+    with_nana=no
+  elif test "$with_nana" = yes; then
+    AC_CHECK_PROGS(NANA, nana, :)
+    if test "$NANA" = ":"; then
+      with_nana=no
+    else
+      AC_CHECK_HEADER(nana.h,
+                     AC_CHECK_LIB(nana, nana_error,,with_nana=no),
+                     with_nana=no)
+    fi
+  else
+    with_nana=no
+  fi
+  AC_MSG_CHECKING([whether to use NANA])
+  AC_MSG_RESULT($with_nana)
+  if test "$with_nana" != yes; then
+    AC_DEFINE(WITHOUT_NANA)
+  fi
+])
diff --git a/cmulocal/openldap.m4 b/cmulocal/openldap.m4
new file mode 100644 (file)
index 0000000..301062b
--- /dev/null
@@ -0,0 +1,36 @@
+dnl
+dnl macros for configure.in to detect openldap
+dnl $Id: openldap.m4,v 1.2 2006/03/13 19:16:11 mel Exp $
+dnl
+
+dnl
+dnl Check for OpenLDAP version compatility
+AC_DEFUN([CMU_OPENLDAP_API],
+[AC_CACHE_CHECK([OpenLDAP api], [cmu_cv_openldap_api],[
+    AC_EGREP_CPP(__openldap_api,[
+#include <ldap.h>
+
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+char *__openldap_api = LDAP_API_FEATURE_X_OPENLDAP;
+#endif
+],      [cmu_cv_openldap_api=yes], [cmu_cv_openldap_api=no])])
+])
+
+dnl
+dnl Check for OpenLDAP version compatility
+AC_DEFUN([CMU_OPENLDAP_COMPAT],
+[AC_CACHE_CHECK([OpenLDAP version], [cmu_cv_openldap_compat],[
+    AC_EGREP_CPP(__openldap_compat,[
+#include <ldap.h>
+
+/* Require 2.1.27+ and 2.2.6+ */
+#if LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 1 && LDAP_VENDOR_VERSION_PATCH > 26
+char *__openldap_compat = "2.1.27 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 2 && LDAP_VENDOR_VERSION_PATCH > 5
+char *__openldap_compat = "2.2.6 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR > 2
+char *__openldap_compat = "2.3 or better okay"
+#endif
+],      [cmu_cv_openldap_compat=yes], [cmu_cv_openldap_compat=no])])
+])
+
diff --git a/cmulocal/openssl.m4 b/cmulocal/openssl.m4
new file mode 100644 (file)
index 0000000..1b9b488
--- /dev/null
@@ -0,0 +1,47 @@
+dnl
+dnl macros for configure.in to detect openssl
+dnl $Id: openssl.m4,v 1.11 2006/05/17 18:30:19 murch Exp $
+dnl
+
+AC_DEFUN([CMU_HAVE_OPENSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(openssl,[  --with-openssl=PATH     use OpenSSL from PATH],
+       with_openssl=$withval, with_openssl="yes")
+
+       save_CPPFLAGS=$CPPFLAGS
+       save_LDFLAGS=$LDFLAGS
+
+       if test -d $with_openssl; then
+         CPPFLAGS="${CPPFLAGS} -I${with_openssl}/include"
+         CMU_ADD_LIBPATH(${with_openssl}/$CMU_LIB_SUBDIR)
+       fi
+
+case "$with_openssl" in
+       no)
+         with_openssl="no";;
+       *) 
+         dnl if openssl has been compiled with the rsaref2 libraries,
+         dnl we need to include the rsaref libraries in the crypto check
+                LIB_RSAREF=""
+               AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                       cmu_have_rsaref=yes;
+                       [AC_CHECK_LIB(RSAglue, RSAPublicEncrypt,
+                               LIB_RSAREF="-lRSAglue -lrsaref",
+                               LIB_RSAREF="-lrsaref")],
+                       cmu_have_rsaref=no)
+
+               AC_CHECK_HEADER(openssl/evp.h, [
+                       AC_CHECK_LIB(crypto, EVP_DigestInit,
+                                       with_openssl="yes",
+                                       with_openssl="no", $LIB_RSAREF)],
+                       with_openssl=no)
+               ;;
+esac
+
+       if test "$with_openssl" != "no"; then
+               AC_DEFINE(HAVE_OPENSSL,[],[Do we have OpenSSL?])
+       else
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+       fi
+])
diff --git a/cmulocal/pthreads.m4 b/cmulocal/pthreads.m4
new file mode 100644 (file)
index 0000000..b457623
--- /dev/null
@@ -0,0 +1,23 @@
+dnl pthreads.m4--pthreads setup macro
+dnl Rob Earhart
+dnl $Id: pthreads.m4,v 1.11 2003/10/08 20:35:25 rjs3 Exp $
+
+AC_DEFUN([CMU_PTHREADS], [
+   AC_REQUIRE([AC_CANONICAL_HOST])
+   cmu_save_LIBS="$LIBS"
+   AC_CHECK_LIB(pthread, pthread_create,LIB_PTHREAD="-lpthread",
+     AC_CHECK_LIB(c_r, pthread_create,LIB_PTHREAD="-lc_r",
+       AC_ERROR([Can't compile without pthreads])))
+  LIBS="$cmu_save_LIBS"
+   AC_SUBST(LIB_PTHREAD)
+   AC_DEFINE(_REENTRANT)
+   case "$host_os" in
+   solaris2*)
+       AC_DEFINE(_POSIX_PTHREAD_SEMANTICS)
+       AC_DEFINE(__EXTENSIONS__)
+       ;;
+   irix6*)
+       AC_DEFINE(_SGI_REENTRANT_FUNCTIONS)
+       ;;
+   esac
+])
diff --git a/cmulocal/sasl.m4 b/cmulocal/sasl.m4
new file mode 100644 (file)
index 0000000..aed58d9
--- /dev/null
@@ -0,0 +1,94 @@
+dnl sasl.m4--sasl libraries and includes
+dnl Derrick Brashear
+dnl from KTH sasl and Arla
+dnl $Id: sasl.m4,v 1.23 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_SASL_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+CMU_CHECK_HEADER_NOCACHE(sasl.h,
+ac_cv_found_sasl_inc=yes,
+ac_cv_found_sasl_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_SASL_INC_WHERE], [
+   for i in $1; do
+      CMU_SASL_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, sasl)
+      if test "$ac_cv_found_sasl_inc" = "yes"; then
+        ac_cv_sasl_where_inc=$i
+        break
+      fi
+    done
+])
+
+AC_DEFUN([CMU_SASL_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lsasl"
+AC_TRY_LINK(,
+[sasl_getprop();],
+[ac_cv_found_sasl_lib=yes],
+ac_cv_found_sasl_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_SASL_LIB_WHERE], [
+   for i in $1; do
+      CMU_SASL_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, sasl)
+      if test "$ac_cv_found_sasl_lib" = "yes" ; then
+        ac_cv_sasl_where_lib=$i
+        break
+      fi
+    done
+])
+
+AC_DEFUN([CMU_SASL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(sasl,
+            [  --with-sasl=DIR        Compile with libsasl in <DIR>],
+           with_sasl="$withval",
+            with_sasl="yes")
+
+       SASLFLAGS=""
+       LIB_SASL=""
+
+       cmu_saved_CPPFLAGS=$CPPFLAGS
+       cmu_saved_LDFLAGS=$LDFLAGS
+       cmu_saved_LIBS=$LIBS
+       if test -d ${with_sasl}; then
+          ac_cv_sasl_where_lib=${with_sasl}/$CMU_LIB_SUBDIR
+          ac_cv_sasl_where_inc=${with_sasl}/include
+
+         SASLFLAGS="-I$ac_cv_sasl_where_inc"
+         LIB_SASL="-L$ac_cv_sasl_where_lib"
+         CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+         LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+       fi
+
+       AC_CHECK_HEADER(sasl.h,
+         AC_CHECK_LIB(sasl, sasl_getprop, 
+                       ac_cv_found_sasl=yes,
+                      ac_cv_found_sasl=no), ac_cv_found_sasl=no)
+
+       LIBS="$cmu_saved_LIBS"
+       LDFLAGS="$cmu_saved_LDFLAGS"
+       CPPFLAGS="$cmu_saved_CPPFLAGS"
+       if test "$ac_cv_found_sasl" = yes; then
+         LIB_SASL="$LIB_SASL -lsasl"
+       else
+         LIB_SASL=""
+         SASLFLAGS=""
+       fi
+       AC_SUBST(LIB_SASL)
+       AC_SUBST(SASLFLAGS)
+       ])
+
+AC_DEFUN([CMU_SASL_REQUIRED],
+[AC_REQUIRE([CMU_SASL])
+if test "$ac_cv_found_sasl" != "yes"; then
+        AC_ERROR([Cannot continue without libsasl.
+Get it from ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.])
+fi])
diff --git a/cmulocal/sasl2.m4 b/cmulocal/sasl2.m4
new file mode 100644 (file)
index 0000000..de4d77c
--- /dev/null
@@ -0,0 +1,472 @@
+# sasl2.m4--sasl2 libraries and includes
+# Rob Siemborski
+# $Id: sasl2.m4,v 1.52 2006/05/18 19:25:00 murch Exp $
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL_GSSAPI_CHK],
+[AC_REQUIRE([SASL2_CRYPT_CHK])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_ENABLE([gssapi],
+              [AC_HELP_STRING([--enable-gssapi=<DIR>],
+                              [enable GSSAPI authentication [yes]])],
+              [gssapi=$enableval],
+              [gssapi=yes])
+AC_ARG_WITH([gss_impl],
+            [AC_HELP_STRING([--with-gss_impl={heimdal|mit|cybersafe|seam|auto}],
+                            [choose specific GSSAPI implementation [[auto]]])],
+            [gss_impl=$withval],
+            [gss_impl=auto])
+
+if test "$gssapi" != no; then
+  platform=
+  case "${host}" in
+    *-*-linux*)
+      platform=__linux
+      ;;
+    *-*-hpux*)
+      platform=__hpux
+      ;;
+    *-*-irix*)
+      platform=__irix
+      ;;
+    *-*-solaris2*)
+# When should we use __sunos?
+      platform=__solaris
+      ;;
+    *-*-aix*)
+###_AIX
+      platform=__aix
+      ;;
+    *)
+      AC_WARN([The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script])
+      if test "$gss_impl" = "cybersafe"; then
+        AC_ERROR([CyberSafe was forced, cannot continue as platform is not supported])
+      fi
+      ;;
+  esac
+
+  cmu_saved_CPPFLAGS=$CPPFLAGS
+
+  if test -d ${gssapi}; then
+    CPPFLAGS="$CPPFLAGS -I$gssapi/include"
+# We want to keep -I in our CPPFLAGS, but only if we succeed
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+### I am not sure how useful is this (and whether this is required at all
+### especially when we have to provide two -L flags for new CyberSafe
+    LDFLAGS="$LDFLAGS -L$gssapi/lib"
+
+    if test -n "$platform"; then
+      if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+        CPPFLAGS="$CPPFLAGS -D$platform"
+        if test -d "${gssapi}/appsec-sdk/include"; then
+          CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+        fi
+      fi
+    fi
+  fi
+  AC_CHECK_HEADER([gssapi.h],
+                  [AC_DEFINE(HAVE_GSSAPI_H,,
+                             [Define if you have the gssapi.h header file])],
+                  [AC_CHECK_HEADER([gssapi/gssapi.h],,
+                                   [AC_WARN([Disabling GSSAPI - no include files found]); gssapi=no])])
+
+  CPPFLAGS=$cmu_saved_CPPFLAGS
+
+fi
+
+if test "$gssapi" != no; then
+  # We need to find out which gssapi implementation we are
+  # using. Supported alternatives are: MIT Kerberos 5,
+  # Heimdal Kerberos 5 (http://www.pdc.kth.se/heimdal),
+  # CyberSafe Kerberos 5 (http://www.cybersafe.com/)
+  # and Sun SEAM (http://wwws.sun.com/software/security/kerberos/)
+  #
+  # The choice is reflected in GSSAPIBASE_LIBS
+
+  AC_CHECK_LIB(resolv,res_search)
+  if test -d ${gssapi}; then
+     gssapi_dir="${gssapi}/lib"
+     GSSAPIBASE_LIBS="-L$gssapi_dir"
+     GSSAPIBASE_STATIC_LIBS="-L$gssapi_dir"
+  else
+     # FIXME: This is only used for building cyrus, and then only as
+     # a real hack.  it needs to be fixed.
+     gssapi_dir="/usr/local/lib"
+  fi
+
+  # Check a full link against the Heimdal libraries.
+  # If this fails, check a full link against the MIT libraries.
+  # If this fails, check a full link against the CyberSafe libraries.
+  # If this fails, check a full link against the Solaris 8 and up libgss.
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "heimdal"; then
+    gss_failed=0
+    AC_CHECK_LIB(gssapi,gss_unwrap,gss_impl="heimdal",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "mit"; then
+    # check for libkrb5support first
+    AC_CHECK_LIB(krb5support,krb5int_getspecific,K5SUP=-lkrb5support K5SUPSTATIC=$gssapi_dir/libkrb5support.a,,${LIB_SOCKET})
+
+    gss_failed=0
+    AC_CHECK_LIB(gssapi_krb5,gss_unwrap,gss_impl="mit",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP} ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  # For Cybersafe one has to set a platform define in order to make compilation work
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    cmu_saved_GSSAPIBASE_LIBS=$GSSAPIBASE_LIBS
+# FIXME - Note that the libraries are in .../lib64 for 64bit kernels
+    if test -d "${gssapi}/appsec-rt/lib"; then
+      GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -L${gssapi}/appsec-rt/lib"
+    fi
+    CPPFLAGS="$CPPFLAGS -D$platform"
+    if test -d "${gssapi}/appsec-sdk/include"; then
+      CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+    fi
+
+    gss_failed=0
+
+# Check for CyberSafe with two libraries first, than fall back to a single 
+# library (older CyberSafe)
+
+    unset ac_cv_lib_gss_csf_gss_acq_user
+    AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe03",
+                 [unset ac_cv_lib_gss_csf_gss_acq_user;
+                  AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe",
+                               gss_failed=1,$GSSAPIBASE_LIBS -lgss)],
+                 [${GSSAPIBASE_LIBS} -lgss -lcstbk5])
+
+    if test "$gss_failed" = "1"; then
+# Restore variables
+      GSSAPIBASE_LIBS=$cmu_saved_GSSAPIBASE_LIBS
+      CPPFLAGS=$cmu_saved_CPPFLAGS
+
+      if test "$gss_impl" != "auto"; then
+        gss_impl="failed"
+      fi
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "seam"; then
+    gss_failed=0
+    AC_CHECK_LIB(gss,gss_unwrap,gss_impl="seam",gss_failed=1,-lgss)
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "mit"; then
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}"
+  elif test "$gss_impl" = "heimdal"; then
+    CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}"
+  elif test "$gss_impl" = "cybersafe03"; then
+# Version of CyberSafe with two libraries
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss -lcstbk5"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "cybersafe"; then
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "seam"; then
+    GSSAPIBASE_LIBS=-lgss
+    # there is no static libgss on Solaris 8 and up
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "failed"; then
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - specified library not found])
+  else
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - no library])
+  fi
+fi
+
+#
+# Cybersafe defines both GSS_C_NT_HOSTBASED_SERVICE and GSS_C_NT_USER_NAME
+# in gssapi\rfckrb5.h
+#
+if test "$gssapi" != "no"; then
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(hostbased_service_gss_nt_yes,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_HOSTBASED_SERVICE
+                    hostbased_service_gss_nt_yes
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])],
+                 [AC_WARN([Cybersafe define not found])])
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  fi
+
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(user_name_yes_gss_nt,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_USER_NAME
+                   user_name_yes_gss_nt
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])],
+                 [AC_WARN([Cybersafe define not found])])
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  fi
+fi
+
+GSSAPI_LIBS=""
+AC_MSG_CHECKING([GSSAPI])
+if test "$gssapi" != no; then
+  AC_MSG_RESULT([with implementation ${gss_impl}])
+  AC_CHECK_LIB(resolv,res_search,GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lresolv")
+  SASL_MECHS="$SASL_MECHS libgssapiv2.la"
+  SASL_STATIC_OBJS="$SASL_STATIC_OBJS gssapi.o"
+  SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/gssapi.c"
+
+  cmu_save_LIBS="$LIBS"
+  LIBS="$LIBS $GSSAPIBASE_LIBS"
+  AC_CHECK_FUNCS(gsskrb5_register_acceptor_identity)
+  LIBS="$cmu_save_LIBS"
+else
+  AC_MSG_RESULT([disabled])
+fi
+AC_SUBST(GSSAPI_LIBS)
+AC_SUBST(GSSAPIBASE_LIBS)
+])# SASL_GSSAPI_CHK
+
+
+# SASL_SET_GSSAPI_LIBS
+# --------------------
+AC_DEFUN([SASL_SET_GSSAPI_LIBS],
+[SASL_GSSAPI_LIBS_SET="yes"
+])
+
+
+# CMU_SASL2
+# ---------
+# What we want to do here is setup LIB_SASL with what one would
+# generally want to have (e.g. if static is requested, make it that,
+# otherwise make it dynamic.
+#
+# We also want to create LIB_DYN_SASL and DYNSASLFLAGS.
+#
+# Also sets using_static_sasl to "no" "static" or "staticonly"
+#
+AC_DEFUN([CMU_SASL2],
+[AC_REQUIRE([SASL_GSSAPI_CHK])
+
+AC_ARG_WITH(sasl,
+            [AC_HELP_STRING([--with-sasl=DIR],[Compile with libsasl2 in <DIR>])],
+            with_sasl="$withval",
+            with_sasl="yes")
+
+AC_ARG_WITH(staticsasl,
+            [AC_HELP_STRING([--with-staticsasl=DIR],
+                            [Compile with staticly linked libsasl2 in <DIR>])],
+            [with_staticsasl="$withval";
+             if test $with_staticsasl != "no"; then
+               using_static_sasl="static"
+             fi],
+            [with_staticsasl="no"; using_static_sasl="no"])
+
+SASLFLAGS=""
+LIB_SASL=""
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+cmu_saved_LDFLAGS=$LDFLAGS
+cmu_saved_LIBS=$LIBS
+
+if test ${with_staticsasl} != "no"; then
+  if test -d ${with_staticsasl}; then
+    if test -d ${with_staticsasl}/lib64 ; then
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib64
+    else
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    fi
+    ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    ac_cv_sasl_where_inc=${with_staticsasl}/include
+
+    SASLFLAGS="-I$ac_cv_sasl_where_inc"
+    LIB_SASL="-L$ac_cv_sasl_where_lib"
+    CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+    LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+  else
+    with_staticsasl="/usr"
+  fi
+
+  AC_CHECK_HEADER(sasl/sasl.h,
+                  [AC_CHECK_HEADER(sasl/saslutil.h,
+                                   [for i42 in lib64 lib; do
+                                      if test -r ${with_staticsasl}/$i42/libsasl2.a; then
+                                        ac_cv_found_sasl=yes
+                                        AC_MSG_CHECKING([for static libsasl])
+                                        LIB_SASL="$LIB_SASL ${with_staticsasl}/$i42/libsasl2.a"
+                                      fi
+                                    done
+                                    if test ! "$ac_cv_found_sasl" = "yes"; then
+                                      AC_MSG_CHECKING([for static libsasl])
+                                      AC_ERROR([Could not find ${with_staticsasl}/lib*/libsasl2.a])
+                                    fi])])
+
+  AC_MSG_RESULT([found])
+
+  if test "x$SASL_GSSAPI_LIBS_SET" = "x"; then
+    LIB_SASL="$LIB_SASL $GSSAPIBASE_STATIC_LIBS"
+  else
+    SASL_GSSAPI_LIBS_SET=""
+    cmu_saved_LIBS="$GSSAPIBASE_STATIC_LIBS $cmu_saved_LIBS" 
+  fi
+fi
+
+if test -d ${with_sasl}; then
+  ac_cv_sasl_where_lib=${with_sasl}/lib
+  ac_cv_sasl_where_inc=${with_sasl}/include
+
+  DYNSASLFLAGS="-I$ac_cv_sasl_where_inc"
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, LIB_DYN_SASL)
+  fi
+  LIB_DYN_SASL="$LIB_DYN_SASL -lsasl2"
+  CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+  LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+fi
+
+# be sure to check for a SASLv2 specific function
+AC_CHECK_HEADER(sasl/sasl.h,
+                [AC_CHECK_HEADER(sasl/saslutil.h,
+                                 [AC_CHECK_LIB(sasl2, prop_get, 
+                                               ac_cv_found_sasl=yes,
+                                               ac_cv_found_sasl=no)],
+                                 ac_cv_found_sasl=no)],
+                ac_cv_found_sasl=no)
+
+if test "$ac_cv_found_sasl" = "yes"; then
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, DYNLIB_SASL)
+  fi
+  DYNLIB_SASL="$DYNLIB_SASL -lsasl2"
+  if test "$using_static_sasl" != "static"; then
+    LIB_SASL=$DYNLIB_SASL
+    SASLFLAGS=$DYNSASLFLAGS
+  fi
+else
+  DYNLIB_SASL=""
+  DYNSASLFLAGS=""
+  using_static_sasl="staticonly"
+fi
+
+if test "x$SASL_GSSAPI_LIBS_SET" != "x"; then
+  SASL_GSSAPI_LIBS_SET=""
+  cmu_saved_LIBS="$GSSAPIBASE_LIBS $cmu_saved_LIBS" 
+fi
+
+LIBS="$cmu_saved_LIBS"
+LDFLAGS="$cmu_saved_LDFLAGS"
+CPPFLAGS="$cmu_saved_CPPFLAGS"
+
+AC_SUBST(LIB_DYN_SASL)
+AC_SUBST(DYNSASLFLAGS)
+AC_SUBST(LIB_SASL)
+AC_SUBST(SASLFLAGS)
+])# CMU_SASL2
+
+
+# CMU_SASL2_REQUIRED
+# ------------------
+AC_DEFUN([CMU_SASL2_REQUIRED],
+[AC_REQUIRE([CMU_SASL2])
+if test "$ac_cv_found_sasl" != "yes"; then
+  AC_ERROR([Cannot continue without libsasl2.
+Get it from ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.])
+fi])
+
+
+# CMU_SASL2_REQUIRE_VER
+# ---------------------
+AC_DEFUN([CMU_SASL2_REQUIRE_VER],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $SASLFLAGS"
+
+AC_TRY_CPP([
+#include <sasl/sasl.h>
+
+#ifndef SASL_VERSION_MAJOR
+#error SASL_VERSION_MAJOR not defined
+#endif
+#ifndef SASL_VERSION_MINOR
+#error SASL_VERSION_MINOR not defined
+#endif
+#ifndef SASL_VERSION_STEP
+#error SASL_VERSION_STEP not defined
+#endif
+
+#if SASL_VERSION_MAJOR < $1 || SASL_VERSION_MINOR < $2 || SASL_VERSION_STEP < $3
+#error SASL version is less than $1.$2.$3
+#endif
+],,
+           [AC_ERROR([Incorrect SASL headers found.  This package requires SASL $1.$2.$3 or newer.])])
+
+CPPFLAGS=$cmu_saved_CPPFLAGS
+])# CMU_SASL2_REQUIRE_VER
+
+
+# CMU_SASL2_CHECKAPOP_REQUIRED
+# ----------------------------
+AC_DEFUN([CMU_SASL2_CHECKAPOP_REQUIRED],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_LDFLAGS=$LDFLAGS
+
+LDFLAGS="$LDFLAGS $LIB_SASL"
+
+AC_CHECK_LIB(sasl2, sasl_checkapop,
+             [AC_DEFINE(HAVE_APOP,[],[Does SASL support APOP?])],
+             [AC_MSG_ERROR([libsasl2 without working sasl_checkapop.  Cannot continue.])])
+
+LDFLAGS=$cmu_saved_LDFLAGS
+])# CMU_SASL2_CHECKAPOP_REQUIRED
+
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL2_CRYPT_CHK],
+[AC_CHECK_FUNC(crypt, cmu_have_crypt=yes,
+               [AC_CHECK_LIB(crypt, crypt,
+                             LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes,
+                             cmu_have_crypt=no)])
+AC_SUBST(LIB_CRYPT)
+])# SASL2_CRYPT_CHK
diff --git a/cmulocal/tcl.m4 b/cmulocal/tcl.m4
new file mode 100644 (file)
index 0000000..e99f847
--- /dev/null
@@ -0,0 +1,160 @@
+dnl FIRST PASS AFTER STEALING THIS FROM CYRUS!
+dnl USE AT YOUR OWN PERIL!
+dnl I MEAN IT!
+dnl
+dnl tcl.m4: an autoconf Tcl locator
+dnl $Id: tcl.m4,v 1.4 2003/10/08 20:35:25 rjs3 Exp $
+dnl
+dnl This is rob's Tcl macro, fixed by tjs.  It may need occasional tweaking,
+dnl but until the next impediment to compilation, it's fill-in-the-blank,
+dnl and it should be able to do reasonable things with user input.
+dnl
+dnl This will probably just work on Andrew systems, but given the variety
+dnl and apparent creativity of people who compile Tcl elsewhere, I don't know
+dnl what it will do.  I have yet to see an autoconf Tcl test that users were
+dnl happy with.
+dnl
+dnl BUGS
+dnl   The command-line arguments are overcomplicated.
+dnl   There are doubtlessly others...
+
+dnl To use this macro, just do CMU_TCL.  It outputs
+dnl TCL_LIBS, TCL_CPPFLAGS, and TCL_DEFS and SUBSTs them.  
+dnl If successful, these have stuff in them.  If not, they're empty.
+dnl If not successful, with_tcl has the value "no".
+
+AC_DEFUN([CMU_TCL], [
+# --- BEGIN CMU_TCL ---
+dnl To link against Tcl, configure does several things to make my life
+dnl "easier".
+dnl
+dnl * maybe ask the user where they think Tcl lives, and try to find it
+dnl * maybe ask the user what "tclsh" is called this week (i.e., "tclsh8.0")
+dnl * run tclsh, ask it for a path, then run that path through sed
+dnl * sanity check its result (many installs are a little broken)
+dnl * try to figure out where Tcl is based on this result
+dnl * try to guess where the Tcl include files are
+dnl
+dnl Notes from previous incarnations:
+dnl > XXX MUST CHECK FOR TCL BEFORE KERBEROS V4 XXX
+dnl > This is because some genius at MIT named one of the Kerberos v4
+dnl > library functions log().  This of course conflicts with the
+dnl > logarithm function in the standard math library, used by Tcl.
+dnl
+dnl > Checking for Tcl first puts -lm before -lkrb on the library list.
+dnl
+
+dnl Check for some information from the user on what the world looks like
+AC_ARG_WITH(tclconfig,[  --with-tclconfig=PATH   use tclConfig.sh from PATH
+                          (configure gets Tcl configuration from here)],
+        dnl trim tclConfig.sh off the end so we can add it back on later.
+       TclLibBase=`echo ${withval} | sed s/tclConfig.sh\$//`)
+AC_ARG_WITH(tcl,      [  --with-tcl=PATH         use Tcl from PATH],
+       TclLibBase="${withval}/lib")
+AC_ARG_WITH(tclsh,    [  --with-tclsh=TCLSH      use TCLSH as the tclsh program
+                          (let configure find Tcl using this program)],
+       TCLSH="${withval}")
+
+if test "$TCLSH" = "no" -o "$with_tclconfig" = "no" ; then
+  AC_MSG_WARN([Tcl disabled because tclsh or tclconfig specified as "no"])
+  with_tcl=no
+fi
+
+if test "$with_tcl" != "no"; then
+  if test \! -z "$with_tclconfig" -a \! -d "$with_tclconfig" ; then
+    AC_MSG_ERROR([--with-tclconfig requires a directory argument.])
+  fi
+
+  if test \! -z "$TCLSH" -a \! -x "$TCLSH" ; then
+    AC_MSG_ERROR([--with-tclsh must specify an executable file.])
+  fi
+
+  if test -z "$TclLibBase"; then # do we already know?
+    # No? Run tclsh and ask it where it lives.
+
+    # Do we know where a tclsh lives?
+    if test -z "$TCLSH"; then
+      # Try and find tclsh.  Any tclsh.
+      # If a new version of tcl comes out and unfortunately adds another
+      # filename, it should be safe to add it (to the front of the line --
+      # somef vendors have older, badly installed tclshs that we want to avoid
+      # if we can)
+      AC_PATH_PROGS(TCLSH, [tclsh8.1 tclsh8.0 tclsh], "unknown")
+    fi
+
+    # Do we know where to get a tclsh?
+    if test "${TCLSH}" != "unknown"; then
+      AC_MSG_CHECKING([where Tcl says it lives])
+      TclLibBase=`echo puts \\\$tcl_library | ${TCLSH} | sed -e 's,[^/]*$,,'`
+      AC_MSG_RESULT($TclLibBase)
+    fi
+  fi
+
+  if test -z "$TclLibBase" ; then
+    AC_MSG_RESULT([can't find tclsh])
+    AC_MSG_WARN([can't find Tcl installtion; use of Tcl disabled.])
+    with_tcl=no
+  else
+    AC_MSG_CHECKING([for tclConfig.sh])
+    # Check a list of places where the tclConfig.sh file might be.
+    for tcldir in "${TclLibBase}" \
+                  "${TclLibBase}/.." \
+                 "${TclLibBase}"`echo ${TCLSH} | sed s/sh//` ; do
+      if test -f "${tcldir}/tclConfig.sh"; then
+        TclLibBase="${tcldir}"
+        break
+      fi
+    done
+
+    if test -z "${TclLibBase}" ; then
+      AC_MSG_RESULT("unknown")
+      AC_MSG_WARN([can't find Tcl configuration; use of Tcl disabled.])
+      with_tcl=no
+    else
+      AC_MSG_RESULT(${TclLibBase}/)
+    fi
+
+    if test "${with_tcl}" != no ; then
+      AC_MSG_CHECKING([Tcl configuration on what Tcl needs to compile])
+      . ${TclLibBase}/tclConfig.sh
+      AC_MSG_RESULT(ok)
+      dnl no TK stuff for us.
+      dnl . ${TclLibBase}/tkConfig.sh
+    fi
+
+    if test "${with_tcl}" != no ; then
+      dnl Now, hunt for the Tcl include files, since we don't strictly
+      dnl know where they are; some folks put them (properly) in the 
+      dnl default include path, or maybe in /usr/local; the *BSD folks
+      dnl put them in other places.
+      AC_MSG_CHECKING([where Tcl includes are])
+      for tclinclude in "${TCL_PREFIX}/include/tcl${TCL_VERSION}" \
+                        "${TCL_PREFIX}/include/tcl" \
+                        "${TCL_PREFIX}/include" ; do
+        if test -r "${tclinclude}/tcl.h" ; then
+          TCL_CPPFLAGS="-I${tclinclude}"
+          break
+        fi
+      done
+      if test -z "${TCL_CPPFLAGS}" ; then
+        AC_MSG_WARN(can't find Tcl includes; use of Tcl disabled.)
+        with_tcl=no
+      fi
+      AC_MSG_RESULT(${TCL_CPPFLAGS})
+    fi
+    
+    # Finally, pick up the Tcl configuration if we haven't found an
+    # excuse not to.
+    if test "${with_tcl}" != no; then
+      dnl TCL_LIBS="${TK_LIB_SPEC} ${TK_XLIBSW} ${TCL_LD_SEARCH_FLAGS} ${TCL_LIB_SPEC}"
+      TCL_LIBS="${TCL_LD_SEARCH_FLAGS} ${TCL_LIB_SPEC} ${TCL_LIBS}"
+    fi
+  fi
+fi
+
+AC_SUBST(TCL_DEFS)
+AC_SUBST(TCL_LIBS)
+AC_SUBST(TCL_CPPFLAGS)
+
+# --- END CMU_TCL ---
+]) dnl CMU_TCL
diff --git a/cmulocal/telnet.m4 b/cmulocal/telnet.m4
new file mode 100644 (file)
index 0000000..9575fe9
--- /dev/null
@@ -0,0 +1,180 @@
+dnl telnet.m4--telnet special macros
+dnl Derrick Brashear
+dnl $Id: telnet.m4,v 1.13 2006/02/25 18:36:36 cg2v Exp $
+
+AC_DEFUN([CMU_TELNET_WHICH_TERM], [
+AC_CHECK_LIB(termlib, setupterm, [
+AC_DEFINE(HAVE_SETUPTERM,, [Define to 1 if you have the `setupterm' function.]) 
+AC_CHECK_LIB(c, setupterm, TCLIB="/usr/ccs/lib/libtermlib.a",TCLIB="-ltermlib","/usr/ccs/lib/libtermlib.a")
+],  TCLIB="-ltermcap")
+])
+
+AC_DEFUN([CMU_TELNET_CC_T], 
+[
+AC_MSG_CHECKING(for cc_t definition)
+AC_CACHE_VAL(cmu_cv_cc_t_definition, [
+AC_TRY_COMPILE(
+[
+#ifdef HAVE_SYS_TERMIOS_H
+#include <sys/termios.h>
+#else
+#ifdef HAVE_SYS_TERMIO_H
+#include <sys/termio.h>
+#endif
+#endif
+],
+[cc_t ffoo;],
+cmu_cv_cc_t_definition=yes,
+cmu_cv_cc_t_definition=no)
+])
+if test "$cmu_cv_cc_t_definition" = "no"; then
+        AC_DEFINE(NO_CC_T,, [The type `cc_t' is not available])
+fi
+AC_MSG_RESULT($cmu_cv_cc_t_definition)
+])
+
+AC_DEFUN([CMU_STREAMS], [
+if test "$ac_cv_header_sys_stropts_h" = "yes" -o "$ac_cv_header_stropts_h" = "yes"; then 
+       AC_DEFINE(HAVE_STREAMS,, [STREAMS are available])dnl
+fi
+])
+
+AC_DEFUN([CMU_TERMIO_MODEL], [
+if test "$ac_cv_header_sys_termio_h" = "yes" -o "$ac_cv_header_sys_termios_h" = "yes"; then 
+       AC_DEFINE(USE_TERMIO,, [Use termios for tty configuration])dnl
+       if test "$ac_cv_header_sys_termios_h" = "no"; then
+               AC_DEFINE(SYSV_TERMIO,, [Use SysV termios])dnl
+       fi
+fi
+])
+
+AC_DEFUN([CMU_TELNET_DES_STRING_TO_KEY_PROTO], [
+AC_MSG_CHECKING(for des_string_to_key prototype)
+AC_CACHE_VAL(cmu_cv_des_string_to_key_proto, [
+AC_TRY_COMPILE(
+[#include <des.h>
+typedef unsigned char Block[8];
+int  des_string_to_key(char *, Block);],
+[int foo = des_string_to_key(NULL, NULL);],
+cmu_cv_des_string_to_key_proto=no,
+cmu_cv_des_string_to_key_proto=yes)
+])
+if test "$cmu_cv_des_string_to_key_proto" = yes; then
+        AC_DEFINE(HAVE_DES_STRING_TO_KEY_PROTO,, [define to 1 if `des_string_to_key' has a prototype])dnl
+fi
+AC_MSG_RESULT($cmu_cv_des_string_to_key_proto)
+])
+
+AC_DEFUN([CMU_TELNET_DES_KEY_SCHED_PROTO], [
+AC_MSG_CHECKING(for des_key_sched prototype)
+AC_CACHE_VAL(cmu_cv_des_key_sched_proto, [
+AC_TRY_COMPILE(
+[
+#include <des.h>
+char des_key_sched(int foo, int bar);
+],
+[des_key_sched(NULL, NULL);],
+cmu_cv_des_key_sched_proto=no,
+cmu_cv_des_key_sched_proto=yes)
+])
+if test "$cmu_cv_des_key_sched_proto" = yes; then
+        AC_DEFINE(HAVE_DES_KEY_SCHED_PROTO,, [define to 1 if `des_key_sched' has a prototype])dnl
+fi
+AC_MSG_RESULT($cmu_cv_des_key_sched_proto)
+])
+
+AC_DEFUN([CMU_TELNET_DES_SET_RANDOM_GENERATOR_SEED_PROTO], [
+AC_MSG_CHECKING(for des_set_random_generator_seed prototype)
+AC_CACHE_VAL(cmu_cv_des_set_random_generator_seed_proto, [
+AC_TRY_COMPILE(
+[
+#include <des.h>
+char des_set_random_generator_seed(int foo, int bar);
+],
+[des_set_random_generator_seed(NULL, NULL);],
+cmu_cv_des_set_random_generator_seed_proto=no,
+cmu_cv_des_set_random_generator_seed_proto=yes)
+])
+if test "$cmu_cv_des_set_random_generator_seed_proto" = yes; then
+        AC_DEFINE(HAVE_DES_SET_RANDOM_GENERATOR_SEED_PROTO,, [define to 1 if `des_set_random_generator_seed' has a prototype])dnl
+fi
+AC_MSG_RESULT($cmu_cv_des_set_random_generator_seed_proto)
+])
+
+AC_DEFUN([CMU_TELNET_DES_NEW_RANDOM_KEY_PROTO], [
+AC_MSG_CHECKING(for des_new_random_key prototype)
+AC_CACHE_VAL(cmu_cv_des_new_random_key_proto, [
+AC_TRY_COMPILE(
+[
+#include <des.h>
+char des_new_random_key(int foo, int bar);
+],
+[des_new_random_key(NULL, NULL);],
+cmu_cv_des_new_random_key_proto=no,
+cmu_cv_des_new_random_key_proto=yes)
+])
+if test "$cmu_cv_des_new_random_key_proto" = yes; then
+        AC_DEFINE(HAVE_DES_NEW_RANDOM_KEY_PROTO,, [define to 1 if `des_new_random_key' has a prototype])dnl
+fi
+AC_MSG_RESULT($cmu_cv_des_new_random_key_proto)
+])
+
+AC_DEFUN([CMU_TELNET_DES_ECB_ENCRYPT_PROTO], [
+AC_MSG_CHECKING(for des_ecb_encrypt prototype)
+AC_CACHE_VAL(cmu_cv_des_ecb_encrypt_proto, [
+AC_TRY_COMPILE(
+[#include <des.h>
+typedef unsigned char Block[8];
+typedef struct { Block _; } Schedule[16];
+void des_ecb_encrypt(Block, Block, Schedule, int);],
+[int foo = des_ecb_encrypt(NULL, NULL, NULL, 0);],
+cmu_cv_des_ecb_encrypt_proto=no,
+cmu_cv_des_ecb_encrypt_proto=yes)
+])
+if test "$cmu_cv_des_ecb_encrypt_proto" = yes; then
+        AC_DEFINE(HAVE_DES_ECB_ENCRYPT_PROTO,, [define to 1 if `des_ecb_encrypt' has a prototype])dnl
+fi
+AC_MSG_RESULT($cmu_cv_des_ecb_encrypt_proto)
+])
+
+AC_DEFUN([CMU_TELNET_GETTYTAB], [
+        if test -f "/etc/gettytab"; then
+               AC_CHECK_FUNCS(getent getstr)
+               if test "X$ac_cv_func_getent" != "Xyes"; then
+                       AC_DEFINE(HAVE_GETTYTAB,, [gettytab support is present])
+                       if test "X$ac_cv_func_getstr" = "Xyes"; then
+                               CFLAGS="$CFLAGS -Dgetstr=ggetstr"
+                       fi
+               fi
+        else
+               AC_CHECK_FUNCS(cgetent)
+        fi
+        ])
+
+AC_DEFUN([CMU_TELNET_ISSUE], [
+        if test -f "/etc/issue.net"; then
+               AC_DEFINE(ISSUE_FILE, "/etc/issue.net", [path of issue file to use])
+        else
+               if test -f "/etc/issue"; then
+                       AC_DEFINE(ISSUE_FILE, "/etc/issue", [path of issue file to use])
+               fi
+        fi
+        ])
+
+AC_DEFUN([CMU_TELNET_PTYDIR], [
+
+        if test -d /dev/pts -o -d /dev/pty; then
+               case "${host}" in
+                 *-*-irix*)
+                   ;;
+                 *-*-linux*)
+                   AC_DEFINE(PTYDIR,, [Has /dev/ptX and pty allocation funcs])
+                   ;;
+                 *)
+                   AC_DEFINE(PTYDIR,, [Has /dev/ptX and pty allocation funcs])
+                   AC_DEFINE(STREAMSPTY,, [ptys are streams devices])
+                   ;;
+               esac
+        fi
+        ])
+
diff --git a/cmulocal/ucdsnmp.m4 b/cmulocal/ucdsnmp.m4
new file mode 100644 (file)
index 0000000..6c14fa1
--- /dev/null
@@ -0,0 +1,71 @@
+dnl look for the (ucd|net)snmp libraries
+dnl $Id: ucdsnmp.m4,v 1.11 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_UCDSNMP], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+  AC_REQUIRE([CMU_SOCKETS])
+  AC_ARG_WITH(snmp, 
+              [  --with-snmp=DIR         use ucd|net snmp (rooted in DIR) [yes] ],
+              with_snmp=$withval, with_snmp=yes)
+
+  dnl
+  dnl Maintain backwards compatibility with old --with-ucdsnmp option
+  dnl
+  AC_ARG_WITH(ucdsnmp,, with_snmp=$withval,)
+
+if test "$with_snmp" != "no"; then
+
+  dnl
+  dnl Try net-snmp first
+  dnl
+  if test "$with_snmp" = "yes"; then
+    AC_PATH_PROG(SNMP_CONFIG,net-snmp-config,,[/usr/local/bin:$PATH])
+  else
+    SNMP_CONFIG="$with_snmp/bin/net-snmp-config"
+  fi
+
+  if test -x "$SNMP_CONFIG"; then
+    AC_MSG_CHECKING(NET SNMP libraries)
+
+    SNMP_LIBS=`$SNMP_CONFIG --agent-libs`
+    SNMP_PREFIX=`$SNMP_CONFIG --prefix`
+
+    if test -n "$SNMP_LIBS" && test -n "$SNMP_PREFIX"; then
+      CPPFLAGS="$CPPFLAGS -I${SNMP_PREFIX}/include"
+      LIB_UCDSNMP=$SNMP_LIBS
+      AC_DEFINE(HAVE_NETSNMP,1,[Do we have Net-SNMP support?])
+      AC_SUBST(LIB_UCDSNMP)
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no)
+      AC_MSG_WARN([Could not find the required paths. Please check your net-snmp installation.])
+    fi
+  else
+    dnl
+    dnl Try ucd-snmp if net-snmp test failed
+    dnl
+    if test "$with_snmp" != no; then
+      if test -d "$with_snmp"; then
+        CPPFLAGS="$CPPFLAGS -I${with_snmp}/include"
+        LDFLAGS="$LDFLAGS -L${with_snmp}/$CMU_LIB_SUBDIR"
+      fi
+      cmu_save_LIBS="$LIBS"
+      AC_CHECK_LIB(snmp, sprint_objid, [
+                AC_CHECK_HEADER(ucd-snmp/version.h,, with_snmp=no)],
+                with_snmp=no, ${LIB_SOCKET})
+      LIBS="$cmu_save_LIBS"
+    fi
+    AC_MSG_CHECKING(UCD SNMP libraries)
+    AC_MSG_RESULT($with_snmp)
+    LIB_UCDSNMP=""
+    if test "$with_snmp" != no; then
+      AC_DEFINE(HAVE_UCDSNMP,1,[Do we have UCD-SNMP support?])
+      LIB_UCDSNMP="-lucdagent -lucdmibs -lsnmp"
+      AC_CHECK_LIB(rpm, rpmdbOpen,
+                LIB_UCDSNMP="${LIB_UCDSNMP} -lrpm -lpopt",,-lpopt)
+    fi
+    AC_SUBST(LIB_UCDSNMP)
+  fi
+fi
+
+])
diff --git a/cmulocal/util.m4 b/cmulocal/util.m4
new file mode 100644 (file)
index 0000000..c3b0f80
--- /dev/null
@@ -0,0 +1,73 @@
+dnl util.m4--robutil macro
+dnl Rob Earhart
+dnl $Id: util.m4,v 1.10 2003/10/08 20:35:26 rjs3 Exp $
+
+dnl robutil is a collection of stuff I (Rob Earhart) have found useful
+dnl to have around when writing code; it's the stuff I wind up rewriting
+dnl every time I start a project.  This does the autoconf setup
+dnl necessary for it.
+
+dnl This is a helper macro, here because there're times when I
+dnl want to know if a type exists or not, but don't want to define
+dnl it to something else (the way AC_CHECK_TYPE does).
+
+AC_DEFUN([CMU_CHECK_TYPE_EXISTS], [
+changequote(<<, >>)
+define(<<CMU_TYPE_NAME>>, translit(CMU_HAVE_$1, [a-z *], [A-Z_P]))
+define(<<CMU_CV_NAME>>, translit(cmu_cv_type_$1, [ *], [_p]))
+changequote([, ])
+  AC_REQUIRE([AC_HEADER_STDC])
+  AC_MSG_CHECKING(for $1)
+  AC_CACHE_VAL(CMU_CV_NAME, [
+    AC_EGREP_CPP([$1[[^a-zA-Z_0-9]]], [
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+], CMU_CV_NAME=yes, CMU_CV_NAME=no)])
+  AC_MSG_RESULT($CMU_CV_NAME)
+  if test $CMU_CV_NAME = yes; then
+    AC_DEFINE(CMU_TYPE_NAME)
+  fi
+])
+
+AC_DEFUN([CMU_UTIL], [
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AM_PROG_CC_STDC])
+  AC_REQUIRE([AC_PROG_RANLIB])
+  AC_REQUIRE([CMU_NANA])
+  AC_REQUIRE([CMU_COMERR])
+  AC_REQUIRE([AC_HEADER_STDC])
+  AC_REQUIRE([AC_TYPE_MODE_T])
+  AC_REQUIRE([AC_C_CONST])
+  AC_CHECK_HEADERS(sys/sysmacros.h)
+  AC_CHECK_HEADER(inttypes.h, AC_DEFINE(HAVE_INTTYPES_H),
+                 CMU_CHECK_TYPE_EXISTS(int8_t)
+                 CMU_CHECK_TYPE_EXISTS(uint8_t)
+                 CMU_CHECK_TYPE_EXISTS(u_int8_t)
+                 CMU_CHECK_TYPE_EXISTS(int16_t)
+                 CMU_CHECK_TYPE_EXISTS(uint16_t)
+                 CMU_CHECK_TYPE_EXISTS(u_int16_t)
+                 CMU_CHECK_TYPE_EXISTS(int32_t)
+                 CMU_CHECK_TYPE_EXISTS(uint32_t)
+                 CMU_CHECK_TYPE_EXISTS(u_int32_t)
+  )
+  dnl I'm not sure why autoconf gets so annoyed when these
+  dnl are embedded as part of the inttypes check, but, whatever,
+  dnl this works.
+  if test "$ac_cv_header_inttypes_h" = no; then
+    AC_CHECK_SIZEOF(short)
+    AC_CHECK_SIZEOF(int)
+    AC_CHECK_SIZEOF(long)
+  fi
+
+  AC_CHECK_TYPE(ssize_t, signed)
+  THREADED_UTIL_OBJECTS=""
+  AC_SUBST(THREADED_UTIL_OBJECTS)
+])
+
+AC_DEFUN([CMU_THREAD_UTIL], [
+  AC_REQUIRE([CMU_UTIL])
+  THREADED_UTIL_OBJECTS="refcache.o rselock.o"
+])
diff --git a/cmulocal/zephyr.m4 b/cmulocal/zephyr.m4
new file mode 100644 (file)
index 0000000..c4dfd12
--- /dev/null
@@ -0,0 +1,155 @@
+dnl zephyr.m4--Zephyr libraries and includes
+dnl based on kafs.m4, by
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: zephyr.m4,v 1.2 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_ZEPHYR_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE(
+[#include <zephyr/zephyr.h>],
+[ZNotice_t foo;],
+ac_cv_found_zephyr_inc=yes,
+ac_cv_found_zephyr_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_ZEPHYR_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for zephyr headers in $i)
+      CMU_ZEPHYR_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, zephyr/zephyr)
+      if test "$ac_cv_found_zephyr_inc" = "yes"; then
+        ac_cv_zephyr_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_ZEPHYR_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lzephyr $KRB_LIB_FLAGS"
+AC_TRY_LINK(,
+[ZInitialize();],
+[ac_cv_found_zephyr_lib=yes],
+ac_cv_found_zephyr_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_ZEPHYR_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for zephyr libraries in $i)
+      CMU_ZEPHYR_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, zephyr)
+      if test "$ac_cv_found_zephyr_lib" = "yes" ; then
+        ac_cv_zephyr_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_ZEPHYR], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_KRB4])
+AC_ARG_WITH(zephyr,
+        [  --with-zephyr=PREFIX      Compile with Zephyr support],
+        [if test "X$with_zephyr" = "X"; then
+                with_zephyr=yes
+        fi])
+AC_ARG_WITH(zephyr-lib,
+        [  --with-zephyr-lib=dir     use zephyr libraries in dir],
+        [if test "$withval" = "yes" -o "$withval" = "no"; then
+                AC_MSG_ERROR([No argument for --with-zephyr-lib])
+        fi])
+AC_ARG_WITH(zephyr-include,
+        [  --with-zephyr-include=dir use zephyr headers in dir],
+        [if test "$withval" = "yes" -o "$withval" = "no"; then
+                AC_MSG_ERROR([No argument for --with-zephyr-include])
+        fi])
+
+        if test "X$with_zephyr" != "X"; then
+          if test "$with_zephyr" != "yes" -a "$with_zephyr" != no; then
+            ac_cv_zephyr_where_lib=$with_zephyr/$CMU_LIB_SUBDIR
+            ac_cv_zephyr_where_inc=$with_zephyr/include
+          fi
+        fi
+
+        if test "$with_zephyr" != "no"; then 
+          if test "X$with_zephyr_lib" != "X"; then
+            ac_cv_zephyr_where_lib=$with_zephyr_lib
+          fi
+          if test "X$ac_cv_zephyr_where_lib" = "X"; then
+            CMU_ZEPHYR_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+          fi
+
+          if test "X$with_zephyr_include" != "X"; then
+            ac_cv_zephyr_where_inc=$with_zephyr_include
+          fi
+          if test "X$ac_cv_zephyr_where_inc" = "X"; then
+            CMU_ZEPHYR_INC_WHERE(/usr/athena/include /usr/local/include /usr/include)
+          fi
+        fi
+
+        AC_MSG_CHECKING(whether to include zephyr)
+        if test "X$ac_cv_zephyr_where_lib" = "X" -a "X$ac_cv_zephyr_where_inc" = "X"; then
+          ac_cv_found_zephyr=no
+          AC_MSG_RESULT(no)
+        else
+          ac_cv_found_zephyr=yes
+          AC_MSG_RESULT(yes)
+          ZEPHYR_INC_DIR=$ac_cv_zephyr_where_inc
+          ZEPHYR_LIB_DIR=$ac_cv_zephyr_where_lib
+          ZEPHYR_INC_FLAGS="-I${ZEPHYR_INC_DIR}"
+          ZEPHYR_LIB_FLAGS="-L${ZEPHYR_LIB_DIR} -lzephyr"
+         AC_SUBST(ZEPHYT_INC_FLAGS)
+         AC_SUBST(ZEPHYR_LIB_FLAGS)
+          if test "X$RPATH" = "X"; then
+                RPATH=""
+          fi
+          case "${host}" in
+            *-*-linux*)
+              if test "X$RPATH" = "X"; then
+                RPATH="-Wl,-rpath,${ZEPHYR_LIB_DIR}"
+              else 
+                RPATH="${RPATH}:${ZEPHYR_LIB_DIR}"
+              fi
+              ;;
+            *-*-hpux*)
+              if test "X$RPATH" = "X"; then
+                RPATH="-Wl,+b${ZEPHYR_LIB_DIR}"
+              else 
+                RPATH="${RPATH}:${ZEPHYR_LIB_DIR}"
+              fi
+              ;;
+            *-*-irix*)
+              if test "X$RPATH" = "X"; then
+                RPATH="-Wl,-rpath,${ZEPHYR_LIB_DIR}"
+              else 
+                RPATH="${RPATH}:${ZEPHYR_LIB_DIR}"
+              fi
+              ;;
+            *-*-solaris2*)
+              if test "$ac_cv_prog_gcc" = yes; then
+                if test "X$RPATH" = "X"; then
+                  RPATH="-Wl,-R${ZEPHYR_LIB_DIR}"
+                else 
+                  RPATH="${RPATH}:${ZEPHYR_LIB_DIR}"
+                fi
+              else
+                RPATH="${RPATH} -R${ZEPHYR_LIB_DIR}"
+              fi
+              ;;
+          esac
+          AC_SUBST(RPATH)
+        fi
+        ])
+
diff --git a/config.h.in b/config.h.in
new file mode 100644 (file)
index 0000000..5429115
--- /dev/null
@@ -0,0 +1,580 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+
+/* acconfig.h - autoheader configuration input */
+/* 
+ * 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
+
+
+/* Runtime config file location */
+#undef CONFIGDIR
+
+/* Do we need a leading _ for dlsym? */
+#undef DLSYM_NEEDS_UNDERSCORE
+
+/* Should we build a shared plugin (via dlopen) library? */
+#undef DO_DLOPEN
+
+/* should we support sasl_checkapop? */
+#undef DO_SASL_CHECKAPOP
+
+/* should we support setpass() for SRP? */
+#undef DO_SRP_SETPASS
+
+/* should we mutex-wrap calls into the GSS library? */
+#undef GSS_USE_MUTEXES
+
+/* Enable 'alwaystrue' password verifier? */
+#undef HAVE_ALWAYSTRUE
+
+/* Include support for Courier's authdaemond? */
+#undef HAVE_AUTHDAEMON
+
+/* Define to 1 if you have the <des.h> header file. */
+#undef HAVE_DES_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dns_lookup' function. */
+#undef HAVE_DNS_LOOKUP
+
+/* Define to 1 if you have the `dn_expand' function. */
+#undef HAVE_DN_EXPAND
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Do we have a getaddrinfo? */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `getdomainname' function. */
+#undef HAVE_GETDOMAINNAME
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Do we have a getnameinfo() function? */
+#undef HAVE_GETNAMEINFO
+
+/* Define to 1 if you have the `getpwnam' function. */
+#undef HAVE_GETPWNAM
+
+/* Define to 1 if you have the `getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* do we have getsubopt()? */
+#undef HAVE_GETSUBOPT
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define if you have the gssapi.h header file */
+#undef HAVE_GSSAPI_H
+
+/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function.
+   */
+#undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
+
+/* Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE */
+#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE
+
+/* Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME */
+#undef HAVE_GSS_C_NT_USER_NAME
+
+/* Define to 1 if you have the `inet_aton' function. */
+#undef HAVE_INET_ATON
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `jrand48' function. */
+#undef HAVE_JRAND48
+
+/* Do we have Kerberos 4 Support? */
+#undef HAVE_KRB
+
+/* Define to 1 if you have the `krb_get_err_text' function. */
+#undef HAVE_KRB_GET_ERR_TEXT
+
+/* Define to 1 if you have the <lber.h> header file. */
+#undef HAVE_LBER_H
+
+/* Define to 1 if you have the <ldap.h> header file. */
+#undef HAVE_LDAP_H
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Do we have mysql support? */
+#undef HAVE_MYSQL
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Do we have OpenSSL? */
+#undef HAVE_OPENSSL
+
+/* Use OPIE for server-side OTP? */
+#undef HAVE_OPIE
+
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+#undef HAVE_PAM_PAM_APPL_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Do we have Postgres support? */
+#undef HAVE_PGSQL
+
+/* Include Support for pwcheck daemon? */
+#undef HAVE_PWCHECK
+
+/* Include support for saslauthd? */
+#undef HAVE_SASLAUTHD
+
+/* Define to 1 if you have the <security/pam_appl.h> header file. */
+#undef HAVE_SECURITY_PAM_APPL_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Does the system have snprintf()? */
+#undef HAVE_SNPRINTF
+
+/* Does sockaddr have an sa_len? */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Do we have a socklen_t? */
+#undef HAVE_SOCKLEN_T
+
+/* Do we have SQLite support? */
+#undef HAVE_SQLITE
+
+/* Is there an ss_family in sockaddr_storage? */
+#undef HAVE_SS_FAMILY
+
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strspn' function. */
+#undef HAVE_STRSPN
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Do we have struct sockaddr_stroage? */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if you have the <sysexits.h> header file. */
+#undef HAVE_SYSEXITS_H
+
+/* Define to 1 if you have the `syslog' function. */
+#undef HAVE_SYSLOG
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <varargs.h> header file. */
+#undef HAVE_VARARGS_H
+
+/* Does the system have vsnprintf()? */
+#undef HAVE_VSNPRINTF
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Should we keep handle to Berkeley DB open in SASLDB plugin? */
+#undef KEEP_DB_OPEN
+
+/* Ignore IP Address in Kerberos 4 tickets? */
+#undef KRB4_IGNORE_IP_ADDRESS
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Where do we look for Courier authdaemond's socket? */
+#undef PATH_AUTHDAEMON_SOCKET
+
+/* Where do we look for saslauthd's socket? */
+#undef PATH_SASLAUTHD_RUNDIR
+
+/* Runtime plugin location */
+#undef PLUGINDIR
+
+/* Force a preferred mechanism */
+#undef PREFER_MECH
+
+/* Location of pwcheck socket */
+#undef PWCHECKDIR
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Use BerkeleyDB for SASLdb */
+#undef SASL_BERKELEYDB
+
+/* Path to default SASLdb database */
+#undef SASL_DB_PATH
+
+/* File to use for source of randomness */
+#undef SASL_DEV_RANDOM
+
+/* Use GDBM for SASLdb */
+#undef SASL_GDBM
+
+/* Use NDBM for SASLdb */
+#undef SASL_NDBM
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* Link ANONYMOUS Staticly */
+#undef STATIC_ANONYMOUS
+
+/* Link CRAM-MD5 Staticly */
+#undef STATIC_CRAMMD5
+
+/* Link DIGEST-MD5 Staticly */
+#undef STATIC_DIGESTMD5
+
+/* Link GSSAPI Staticly */
+#undef STATIC_GSSAPIV2
+
+/* User KERBEROS_V4 Staticly */
+#undef STATIC_KERBEROS4
+
+/* Link ldapdb plugin Staticly */
+#undef STATIC_LDAPDB
+
+/* Link LOGIN Staticly */
+#undef STATIC_LOGIN
+
+/* Link NTLM Staticly */
+#undef STATIC_NTLM
+
+/* Link OTP Staticly */
+#undef STATIC_OTP
+
+/* Link PASSDSS Staticly */
+#undef STATIC_PASSDSS
+
+/* Link PLAIN Staticly */
+#undef STATIC_PLAIN
+
+/* Link SASLdb Staticly */
+#undef STATIC_SASLDB
+
+/* Link SQL plugin staticly */
+#undef STATIC_SQL
+
+/* Link SRP Staticly */
+#undef STATIC_SRP
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Should we try to dlopen() plugins while staticly compiled? */
+#undef TRY_DLOPEN_WHEN_STATIC
+
+/* use the doors IPC API for saslauthd? */
+#undef USE_DOORS
+
+/* Version number of package */
+#undef VERSION
+
+/* Use DES */
+#undef WITH_DES
+
+/* Linking against dmalloc? */
+#undef WITH_DMALLOC
+
+/* Use internal RC4 implementation? */
+#undef WITH_RC4
+
+/* Use OpenSSL DES Implementation */
+#undef WITH_SSL_DES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define as `__inline' if that's what the C compiler calls it, or to nothing
+   if it is not supported. */
+#undef inline
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef mode_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+
+
+
+/* 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/types.h>
+#include <sys/uio.h>
+#endif
+
+/* location of the random number generator */
+#ifdef DEV_RANDOM
+#undef DEV_RANDOM
+#endif
+#define DEV_RANDOM SASL_DEV_RANDOM
+
+/* 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"
+#define SASL_CONF_PATH_ENV_VAR "SASL_CONF_PATH"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef WIN32
+# include <netdb.h>
+# ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+# endif
+#else /* WIN32 */
+# include <winsock2.h>
+#endif /* WIN32 */
+#include <string.h>
+
+#include <netinet/in.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#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        gai_strerror    sasl_gai_strerror
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+#define        getnameinfo     sasl_getnameinfo
+#endif
+
+#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO)
+#include "gai.h"
+#endif
+
+#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
+#define AI_NUMERICHOST  4
+#define NI_NUMERICHOST  2
+#define NI_NAMEREQD     4
+#define NI_NUMERICSERV  8
+#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
+
+/* 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
+
+#ifndef HIER_DELIMITER
+#define HIER_DELIMITER '/'
+#endif
+
+#endif /* CONFIG_H */
+
diff --git a/config/.cvsignore b/config/.cvsignore
new file mode 100644 (file)
index 0000000..13bb78d
--- /dev/null
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+.deps
+.libs
+*.l[ao]
diff --git a/config/Info.plist b/config/Info.plist
new file mode 100644 (file)
index 0000000..f4c7bcd
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<!-- $Id: Info.plist,v 1.2 2001/12/04 02:05:09 rjs3 Exp $ -->
+<plist version="0.9">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>SASL2</string>
+       <key>CFBundleGetInfoString</key>
+       <string>Cyrus SASL v2 Library</string>
+       <key>CFBundleIdentifier</key>
+       <string>edu.cmu.andrew.SASL2framework</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>1.1.0</string>
+       <key>CFBundleName</key>
+       <string>SASL v2 Framework</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>9</string>
+</dict>
+</plist>
diff --git a/config/config.guess b/config/config.guess
new file mode 100755 (executable)
index 0000000..6012b39
--- /dev/null
@@ -0,0 +1,1298 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-07-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+       for c in cc gcc c89 ; do
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+         if test $? = 0 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # Netbsd (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       # Determine the machine/vendor (is the vendor relevant).
+       case "${UNAME_MACHINE}" in
+           amiga) machine=m68k-unknown ;;
+           arm32) machine=arm-unknown ;;
+           atari*) machine=m68k-atari ;;
+           sun3*) machine=m68k-sun ;;
+           mac68k) machine=m68k-apple ;;
+           macppc) machine=powerpc-apple ;;
+           hp3[0-9][05]) machine=m68k-hp ;;
+           ibmrt|romp-ibm) machine=romp-ibm ;;
+           *) machine=${UNAME_MACHINE}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE}" in
+           i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               eval $set_cc_for_build
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       eval $set_cc_for_build
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+       rm -f $dummy.c $dummy
+       fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+         big)    echo mips-unknown-linux-gnu && exit 0 ;;
+         little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+       esac
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev67 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_supported_targets=`cd /; ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       if test "${UNAME_MACHINE}" = "x86pc"; then
+               UNAME_MACHINE=pc
+       fi
+       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/config.sub b/config/config.sub
new file mode 100755 (executable)
index 0000000..578b302
--- /dev/null
@@ -0,0 +1,1375 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-06-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+               | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+               | pyramid | mn10200 | mn10300 | tron | a29k \
+               | 580 | i960 | h8300 \
+               | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+               | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+               | hppa64 \
+               | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+               | alphaev6[78] \
+               | we32k | ns16k | clipper | i370 | sh | sh[34] \
+               | powerpc | powerpcle \
+               | 1750a | dsp16xx | pdp10 | pdp11 \
+               | mips16 | mips64 | mipsel | mips64el \
+               | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+               | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+               | mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
+               | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+               | v850 | c4x \
+               | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+               | pj | pjl | h8500 | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       # FIXME: clean up the formatting here.
+       vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+             | arm-*  | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+             | xmp-* | ymp-* \
+             | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+             | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+             | hppa2.0n-* | hppa64-* \
+             | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+             | alphaev6[78]-* \
+             | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+             | clipper-* | orion-* \
+             | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+             | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+             | mips16-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-* \
+             | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+             | mipstx39-* | mipstx39el-* | mcore-* \
+             | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+             | [cjt]90-* \
+             | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+             | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+             | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [cjt]90)
+               basic_machine=${basic_machine}-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       pdp10-*)
+               os=-tops20
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config/depcomp b/config/depcomp
new file mode 100755 (executable)
index 0000000..807b991
--- /dev/null
@@ -0,0 +1,423 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+   dir=`echo "$object" | sed 's,/.*$,/,'`
+   if test "$dir" = "$object"; then
+      dir=
+   fi
+   # FIXME: should be _deps on DOS.
+   depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  This file always lives in the current directory.
+  # Also, the AIX compiler puts `$object:' at the start of each line;
+  # $object doesn't have directory information.
+  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  outname="$stripped.o"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   else
+      tmpdepfile="$tmpdepfile2"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a space and a tab in the [].
+      sed -e 's,^.*\.[a-z]*:[  ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.  We will use -o /dev/null later,
+  # however we can't do the remplacement now because
+  # `-o $object' might simply not be used
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[      ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    -*)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
diff --git a/config/install-sh b/config/install-sh
new file mode 100755 (executable)
index 0000000..36f96f3
--- /dev/null
@@ -0,0 +1,276 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd=$cpprog
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd=$stripprog
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "$0: no input file specified" >&2
+       exit 1
+else
+       :
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+
+       if [ -d "$dst" ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=$mkdirprog
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f "$src" ] || [ -d "$src" ]
+       then
+               :
+       else
+               echo "$0: $src does not exist" >&2
+               exit 1
+       fi
+
+       if [ x"$dst" = x ]
+       then
+               echo "$0: no destination specified" >&2
+               exit 1
+       else
+               :
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d "$dst" ]
+       then
+               dst=$dst/`basename "$src"`
+       else
+               :
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+       '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp=$pathcomp$1
+       shift
+
+       if [ ! -d "$pathcomp" ] ;
+        then
+               $mkdirprog "$pathcomp"
+       else
+               :
+       fi
+
+       pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd "$dst" &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               dstfile=`basename "$dst" $transformbasename |
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               :
+       fi
+
+# Make a couple of temp file names in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+       rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+       trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+       trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+       if [ -f "$dstdir/$dstfile" ]
+       then
+               $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+               $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+               {
+                 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+                 (exit 1); exit
+               }
+       else
+               :
+       fi
+} &&
+
+# Now rename the file to the real destination.
+
+       $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+       (exit 0); exit
+}
diff --git a/config/kerberos_v4.m4 b/config/kerberos_v4.m4
new file mode 100644 (file)
index 0000000..a4d84e1
--- /dev/null
@@ -0,0 +1,153 @@
+dnl checking for kerberos 4 libraries (and DES)
+
+AC_DEFUN([SASL_DES_CHK], [
+AC_ARG_WITH(des, [  --with-des=DIR          with DES (look in DIR) [yes] ],
+       with_des=$withval,
+       with_des=yes)
+
+LIB_DES=""
+if test "$with_des" != no; then
+  if test -d $with_des; then
+    CPPFLAGS="$CPPFLAGS -I${with_des}/include"
+    LDFLAGS="$LDFLAGS -L${with_des}/lib"
+  fi
+
+  if test "$with_openssl" != no; then
+    dnl check for openssl installing -lcrypto, then make vanilla check
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+
+    dnl same test again, different symbol name
+    if test "$with_des" = no; then
+      AC_CHECK_LIB(crypto, DES_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+    fi
+  fi
+
+  if test "$with_des" = no; then
+    AC_CHECK_LIB(des, des_cbc_encrypt, [LIB_DES="-ldes";
+                                        with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des425, des_cbc_encrypt, [LIB_DES="-ldes425";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des524, des_cbc_encrypt, [LIB_DES="-ldes524";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+    dnl if openssl is around, we might be able to use that for des
+
+    dnl if openssl has been compiled with the rsaref2 libraries,
+    dnl we need to include the rsaref libraries in the crypto check
+    LIB_RSAREF=""
+    AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                 LIB_RSAREF="-lRSAglue -lrsaref"; cmu_have_rsaref=yes,
+                 cmu_have_rsaref=no)
+
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+       AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)], 
+        with_des=no, $LIB_RSAREF)
+  fi
+fi
+
+if test "$with_des" != no; then
+  AC_DEFINE(WITH_DES,[],[Use DES])
+fi
+
+AC_SUBST(LIB_DES)
+])
+
+AC_DEFUN([SASL_KERBEROS_V4_CHK], [
+  AC_REQUIRE([SASL_DES_CHK])
+
+  AC_ARG_ENABLE(krb4, [  --enable-krb4           enable KERBEROS_V4 authentication [[no]] ],
+    krb4=$enableval,
+    krb4=no)
+
+  if test "$krb4" != no; then
+    dnl In order to compile kerberos4, we need libkrb and libdes.
+    dnl (We've already gotten libdes from SASL_DES_CHK)
+    dnl we might need -lresolv for kerberos
+    AC_CHECK_LIB(resolv,res_search)
+
+    dnl if we were ambitious, we would look more aggressively for the
+    dnl krb4 install
+    if test -d ${krb4}; then
+       AC_CACHE_CHECK(for Kerberos includes, cyrus_krbinclude, [
+         for krbhloc in include/kerberosIV include/kerberos include
+         do
+           if test -f ${krb4}/${krbhloc}/krb.h ; then
+             cyrus_krbinclude=${krb4}/${krbhloc}
+             break
+           fi
+         done
+         ])
+
+       if test -n "${cyrus_krbinclude}"; then
+         CPPFLAGS="$CPPFLAGS -I${cyrus_krbinclude}"
+       fi
+       LDFLAGS="$LDFLAGS -L$krb4/lib"
+    fi
+
+    if test "$with_des" != no; then
+      AC_CHECK_HEADER(krb.h, [
+        AC_CHECK_LIB(com_err, com_err, [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR="-lcom_err"; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES -lcom_err)], [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES)])], krb4="no")
+
+      if test "$krb4" != "no" -a "$krb4lib" = "no"; then
+       AC_CHECK_LIB(krb4, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb4"; krb4=yes],
+                     krb4=no, $LIB_DES)
+      fi
+      if test "$krb4" = no; then
+          AC_WARN(No Kerberos V4 found)
+      fi
+    else
+      AC_WARN(No DES library found for Kerberos V4 support)
+      krb4=no
+    fi
+  fi
+
+  if test "$krb4" != no; then
+    cmu_save_LIBS="$LIBS"
+    LIBS="$LIBS $SASL_KRB_LIB"
+    AC_CHECK_FUNCS(krb_get_err_text)
+    LIBS="$cmu_save_LIBS"
+  fi
+
+  AC_MSG_CHECKING(KERBEROS_V4)
+  if test "$krb4" != no; then
+    AC_MSG_RESULT(enabled)
+    SASL_MECHS="$SASL_MECHS libkerberos4.la"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/kerberos4.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS kerberos4.o"
+    AC_DEFINE(STATIC_KERBEROS4,[],[User KERBEROS_V4 Staticly])
+    AC_DEFINE(HAVE_KRB,[],[Do we have Kerberos 4 Support?])
+    SASL_KRB_LIB="$SASL_KRB_LIB $LIB_DES $COM_ERR"
+  else
+    AC_MSG_RESULT(disabled)
+  fi
+  AC_SUBST(SASL_KRB_LIB)
+])
+
diff --git a/config/libtool.m4 b/config/libtool.m4
new file mode 100644 (file)
index 0000000..f134d1d
--- /dev/null
@@ -0,0 +1,430 @@
+## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*-
+## Copyright (C) 1996-1999 Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_SHARED], [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_STATIC], [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL], [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN([AM_PROG_LIBTOOL], [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN([AM_ENABLE_SHARED], [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN([AM_ENABLE_STATIC], [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN([AM_DISABLE_SHARED], [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN([AM_DISABLE_STATIC], [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN([AM_PROG_LD], [indir([AC_PROG_LD])])dnl
+AC_DEFUN([AM_PROG_NM], [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
diff --git a/config/ltconfig b/config/ltconfig
new file mode 100755 (executable)
index 0000000..5b61f70
--- /dev/null
@@ -0,0 +1,3150 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}"   = Xset; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  darwin* | rhapsody*)
+    # PIC is the default on this platform
+    # Common symbols not allowed in MH_DYLIB files
+    pic_flag='-fno-common'
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4* | osf5*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:781: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:834: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:835: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:867: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:868: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:919: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:963: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:996: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1020: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1023: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left by newer dlltools.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols'
+
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      cat $export_symbols | while read symbol; do
+        set dummy \$symbol;
+        case \$# in
+          2) echo "    \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;;
+          *) echo "     \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;;
+        esac;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+        whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+        whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  darwin[15]* | rhapsody*)
+    allow_undefined_flag='-undefined error'
+    archive_cmds='$CC $(test x$module = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts -install_name $rpath/$soname $(test -n "$verstring" -a x$verstring != x0.0 && echo $verstring)'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols $lib'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  # Mac OS X v10.2 uses bash for /bin/sh instead of zsh, and the quoting syntax is incompatible
+  darwin*)
+    allow_undefined_flag='-undefined error'
+    archive_cmds='$CC $(test x$module = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts $(test x$module != xyes && echo -install_name $rpath/$soname $tmp_verstring)'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols $lib'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)  # As osf3* with the addition of the -msym flag
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+                                       
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o 
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $linkopts'
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  unixware7*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1662: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1663: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1666: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.[012])
+    file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+    ;;
+  *) # Darwin 1.3 on
+    file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  library_names_spec='${libname}${release}${versuffix}.$(test x$module = xyes && echo so || echo dylib) ${libname}${release}${major}.$(test x$module = xyes && echo so || echo dylib) ${libname}.$(test x$module = xyes && echo so || echo dylib)'
+  soname_spec='${libname}${release}${major}.$(test x$module = xyes && echo so || echo dylib)'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  case "$host_os" in
+  hpux10.20*)
+    # TODO:  Does this work for hpux-11 too?
+    deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    file_magic_cmd=/usr/bin/file
+    file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method=pass_all
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    sequent)
+      file_magic_cmd='/bin/file'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+      ;;
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+# Propagate what we've learned...
+ac_cv_can_build_shared="$can_build_shared"
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2270: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2278 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2310: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2315 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2357: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2365 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2397: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2402 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2445: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2453 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2510: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2515 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2548: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2556 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2621: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2629 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/config/ltmain.sh b/config/ltmain.sh
new file mode 100644 (file)
index 0000000..710f192
--- /dev/null
@@ -0,0 +1,4058 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo '' | od -x` in
+*15*) # EBCDIC based system
+  SP2NL='tr \100 \025'
+  NL2SP='tr \025 \100'
+  ;;
+*) # Assume ASCII based system
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+       case "$arg" in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+       if test "$user_target" != "no"; then
+         $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+         exit 1
+       fi
+       user_target=next
+       ;;
+
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+      esac
+
+      case "$user_target" in
+      next)
+       # The next one is the -o target name
+       user_target=yes
+       continue
+       ;;
+      yes)
+       # We got the output file
+       user_target=set
+       libobj="$arg"
+       continue
+       ;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case "$user_target" in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until ln "$0" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      command="$base_compile $srcfile $pic_flag -DPIC"
+      if test "$build_old_libs" = yes; then
+       lo_libobj="$libobj"
+       dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$dir" = "X$libobj"; then
+         dir="$objdir"
+       else
+         dir="$dir/$objdir"
+       fi
+       libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+       if test -d "$dir"; then
+         $show "$rm $libobj"
+         $run $rm $libobj
+       else
+         $show "$mkdir $dir"
+         $run $mkdir $dir
+         status=$?
+         if test $status -ne 0 && test ! -d $dir; then
+           exit $status
+         fi
+       fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+       output_obj="$libobj"
+       command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+       output_obj="$obj"
+       command="$command -o $output_obj"
+      fi
+
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+       $show "$mv $output_obj $libobj"
+       if $run $mv $output_obj $libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+       # Rename the .lo from within objdir to obj
+       if test -f $obj; then
+         $show $rm $obj
+         $run $rm $obj
+       fi
+
+       $show "$mv $libobj $obj"
+       if $run $mv $libobj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+
+       xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$obj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+       libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+       # Now arrange that obj and lo_libobj become the same file
+       $show "(cd $xdir && $LN_S $baseobj $libobj)"
+       if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+         exit 0
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      command="$base_compile $srcfile"
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+       output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > \$libobj" || exit $?
+      else
+       # Move the .lo from within objdir
+       $show "$mv $libobj $lo_libobj"
+       if $run $mv $libobj $lo_libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    case "$host" in
+    *-*-cygwin* | *-*-mingw* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+      # This is a source program that is used to create import libraries
+      # on Windows for dlls which lack them. Don't remove nor modify the
+      # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999 Free Software Foundation, Inc.
+# 
+#  This file is part of GNU libtool.
+# 
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+# 
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+# 
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+# 
+#  #include <stdio.h>          /* for printf() */
+#  #include <unistd.h>         /* for open(), lseek(), read() */
+#  #include <fcntl.h>          /* for O_RDONLY, O_BINARY */
+#  #include <string.h>         /* for strdup() */
+# 
+#  static unsigned int
+#  pe_get16 (fd, offset)
+#       int fd;
+#       int offset;
+#  {
+#    unsigned char b[2];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 2);
+#    return b[0] + (b[1]<<8);
+#  }
+# 
+#  static unsigned int
+#  pe_get32 (fd, offset)
+#      int fd;
+#      int offset;
+#  {
+#    unsigned char b[4];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 4);
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  static unsigned int
+#  pe_as32 (ptr)
+#       void *ptr;
+#  {
+#    unsigned char *b = ptr;
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  int
+#  main (argc, argv)
+#      int argc;
+#      char *argv[];
+#  {
+#      int dll;
+#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#      unsigned long export_rva, export_size, nsections, secptr, expptr;
+#      unsigned long name_rvas, nexp;
+#      unsigned char *expdata, *erva;
+#      char *filename, *dll_name;
+# 
+#      filename = argv[1];
+# 
+#      dll = open(filename, O_RDONLY|O_BINARY);
+#      if (!dll)
+#      return 1;
+# 
+#      dll_name = filename;
+#    
+#      for (i=0; filename[i]; i++)
+#      if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#          dll_name = filename + i +1;
+# 
+#      pe_header_offset = pe_get32 (dll, 0x3c);
+#      opthdr_ofs = pe_header_offset + 4 + 20;
+#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
+# 
+#      if (num_entries < 1) /* no exports */
+#      return 1;
+# 
+#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#      export_size = pe_get32 (dll, opthdr_ofs + 100);
+#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#      secptr = (pe_header_offset + 4 + 20 +
+#            pe_get16 (dll, pe_header_offset + 4 + 16));
+# 
+#      expptr = 0;
+#      for (i = 0; i < nsections; i++)
+#      {
+#      char sname[8];
+#      unsigned long secptr1 = secptr + 40 * i;
+#      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#      lseek(dll, secptr1, SEEK_SET);
+#      read(dll, sname, 8);
+#      if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#      {
+#          expptr = fptr + (export_rva - vaddr);
+#          if (export_rva + export_size > vaddr + vsize)
+#              export_size = vsize - (export_rva - vaddr);
+#          break;
+#      }
+#      }
+# 
+#      expdata = (unsigned char*)malloc(export_size);
+#      lseek (dll, expptr, SEEK_SET);
+#      read (dll, expdata, export_size);
+#      erva = expdata - export_rva;
+# 
+#      nexp = pe_as32 (expdata+24);
+#      name_rvas = pe_as32 (expdata+32);
+# 
+#      printf ("EXPORTS\n");
+#      for (i = 0; i<nexp; i++)
+#      {
+#      unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#      printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#      }
+# 
+#      return 0;
+#  }
+# /* impgen.c ends here */
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    linkopts=
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      lib_search_path=
+    fi
+    # now prepend the system-specific ones
+    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+    
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    module=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       prefer_static_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case "$prev" in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case "$prev" in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case "$arg" in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit 1
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case "$arg" in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit 1
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: not more than one -exported-symbols argument allowed"
+         exit 1
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           absdir="$dir"
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case " $deplibs " in
+       *" $arg "*) ;;
+       *) deplibs="$deplibs $arg";;
+       esac
+       case " $lib_search_path " in
+       *" $dir "*) ;;
+       *) lib_search_path="$lib_search_path $dir";;
+       esac
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2*)
+         dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+         case ":$dllsearchpath:" in
+         ::) dllsearchpath="$dllsearchdir";;
+         *":$dllsearchdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+         esac
+         ;;
+       esac
+       ;;
+
+      -l*)
+       if test "$arg" = "-lc"; then
+         case "$host" in
+         *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+           # These systems don't actually have c library (as such)
+           continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         esac
+       elif test "$arg" = "-lm"; then
+         case "$host" in
+         *-*-cygwin* | *-*-beos*)
+           # These systems don't actually have math library (as such)
+           continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody math library is in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         esac
+       fi
+       deplibs="$deplibs $arg"
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit 1
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.o | *.obj | *.a | *.lib)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       dlname=
+       libdir=
+       library_names=
+       old_library=
+
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+         exit 1
+       fi
+
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variable installed.
+       installed=yes
+
+       # Read the .la file
+       # If there is no directory component, then add one.
+       case "$arg" in
+       */* | *\\*) . $arg ;;
+       *) . ./$arg ;;
+       esac
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+         exit 1
+       fi
+
+       # Find the relevant object directory and library name.
+       name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+       if test "X$installed" = Xyes; then
+         dir="$libdir"
+       else
+         dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$dir" = "X$arg"; then
+           dir="$objdir"
+         else
+           dir="$dir/$objdir"
+         fi
+       fi
+
+       if test -n "$dependency_libs"; then
+         # Extract -R and -L from dependency_libs
+         temp_deplibs=
+         for deplib in $dependency_libs; do
+           case "$deplib" in
+           -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+                case " $rpath $xrpath " in
+                *" $temp_xrpath "*) ;;
+                *) xrpath="$xrpath $temp_xrpath";;
+                esac;;
+           -L*) case "$compile_command $temp_deplibs " in
+                *" $deplib "*) ;;
+                *) temp_deplibs="$temp_deplibs $deplib";;
+                esac
+                temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+                case " $lib_search_path " in
+                *" $temp_dir "*) ;;
+                *) lib_search_path="$lib_search_path $temp_dir";;
+                esac
+                ;;
+           *) temp_deplibs="$temp_deplibs $deplib";;
+           esac
+         done
+         dependency_libs="$temp_deplibs"
+       fi
+
+       if test -z "$libdir"; then
+         # It is a libtool convenience library, so add in its objects.
+         convenience="$convenience $dir/$old_library"
+         old_convenience="$old_convenience $dir/$old_library"
+         deplibs="$deplibs$dependency_libs"
+         compile_command="$compile_command $dir/$old_library$dependency_libs"
+         finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+         continue
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking statically,
+           # we need to preload.
+           prev=dlprefiles
+         else
+           # We should not create a dependency on this library, but we
+           # may need any libraries it requires.
+           compile_command="$compile_command$dependency_libs"
+           finalize_command="$finalize_command$dependency_libs"
+           prev=
+           continue
+         fi
+       fi
+
+       # The library was specified with -dlpreopen.
+       if test "$prev" = dlprefiles; then
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           dlprefiles="$dlprefiles $dir/$old_library"
+         else
+           dlprefiles="$dlprefiles $dir/$linklib"
+         fi
+         prev=
+       fi
+
+       if test -n "$library_names" &&
+          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+         link_against_libtool_libs="$link_against_libtool_libs $arg"
+         if test -n "$shlibpath_var"; then
+           # Make sure the rpath contains only unique directories.
+           case "$temp_rpath " in
+           *" $dir "*) ;;
+           *) temp_rpath="$temp_rpath $dir" ;;
+           esac
+         fi
+
+         # We need an absolute path.
+         case "$dir" in
+         [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+         *)
+           absdir=`cd "$dir" && pwd`
+           if test -z "$absdir"; then
+             $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+             $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+             absdir="$dir"
+           fi
+           ;;
+         esac
+         
+         # This is the magic to use -rpath.
+         # Skip directories that are in the system default run-time
+         # search path, unless they have been requested with -R.
+         case " $sys_lib_dlsearch_path " in
+         *" $absdir "*) ;;
+         *)
+           case "$compile_rpath " in
+           *" $absdir "*) ;;
+           *) compile_rpath="$compile_rpath $absdir" 
+           esac
+           ;;
+         esac
+
+         case " $sys_lib_dlsearch_path " in
+         *" $libdir "*) ;;
+         *)
+           case "$finalize_rpath " in
+           *" $libdir "*) ;;
+           *) finalize_rpath="$finalize_rpath $libdir"
+           esac
+           ;;
+         esac
+
+         lib_linked=yes
+         case "$hardcode_action" in
+         immediate | unsupported)
+           if test "$hardcode_direct" = no; then
+             compile_command="$compile_command $dir/$linklib"
+             deplibs="$deplibs $dir/$linklib"
+             case "$host" in
+             *-*-cygwin* | *-*-mingw* | *-*-os2*)
+               dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+               if test -n "$dllsearchpath"; then
+                 dllsearchpath="$dllsearchpath:$dllsearchdir"
+               else
+                 dllsearchpath="$dllsearchdir"
+               fi
+               ;;
+             esac
+           elif test "$hardcode_minus_L" = no; then
+             case "$host" in
+             *-*-sunos*)
+               compile_shlibpath="$compile_shlibpath$dir:"
+               ;;
+             esac
+             case "$compile_command " in
+             *" -L$dir "*) ;;
+             *) compile_command="$compile_command -L$dir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$dir -l$name"
+           elif test "$hardcode_shlibpath_var" = no; then
+             case ":$compile_shlibpath:" in
+             *":$dir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$dir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         relink)
+           if test "$hardcode_direct" = yes; then
+             compile_command="$compile_command $absdir/$linklib"
+             deplibs="$deplibs $absdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             case "$compile_command " in
+             *" -L$absdir "*) ;;
+             *) compile_command="$compile_command -L$absdir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$absdir -l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case ":$compile_shlibpath:" in
+             *":$absdir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$absdir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         *)
+           lib_linked=no
+           ;;
+         esac
+
+         if test "$lib_linked" != yes; then
+           $echo "$modename: configuration error: unsupported hardcode properties"
+           exit 1
+         fi
+
+         # Finalize command for both is simple: just hardcode it.
+         if test "$hardcode_direct" = yes; then
+           finalize_command="$finalize_command $libdir/$linklib"
+         elif test "$hardcode_minus_L" = yes; then
+           case "$finalize_command " in
+           *" -L$libdir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         elif test "$hardcode_shlibpath_var" = yes; then
+           case ":$finalize_shlibpath:" in
+           *":$libdir:"*) ;;
+           *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         else
+           # We cannot seem to hardcode it, guess we'll fake it.
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       else
+         # Transform directly to old archives if we don't build new libraries.
+         if test -n "$pic_flag" && test -z "$old_library"; then
+           $echo "$modename: cannot find static library for \`$arg'" 1>&2
+           exit 1
+         fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           case "$compile_command " in
+           *" -L$dir "*) ;;
+           *) compile_command="$compile_command -L$dir";;
+           esac
+           compile_command="$compile_command -l$name"
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$dir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       fi
+
+       # Add in any libraries that this one depends upon.
+       compile_command="$compile_command$dependency_libs"
+       finalize_command="$finalize_command$dependency_libs"
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    *.a | *.lib)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$outputname" in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      if test -n "$objs"; then
+       $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+       exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+        exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         libext=al
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+       dependency_libs="$deplibs"
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       current="$2"
+       revision="$3"
+       age="$4"
+
+       # Check that each of the things are valid numbers.
+       case "$current" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$revision" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$age" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       if test $age -gt $current; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case "$version_type" in
+       none) ;;
+
+       irix)
+         major=`expr $current - $age + 1`
+         versuffix="$major.$revision"
+         verstring="sgi$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test $loop != 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="sgi$major.$iface:$verstring"
+         done
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test $loop != 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       windows)
+         # Like Linux, but with '-' rather than '.', since we only
+         # want one extension on Windows 95.
+         major=`expr $current - $age`
+         versuffix="-$major-$age-$revision"
+         ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         minor_current=`expr $current + 1`
+         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         verstring="0.0"
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+       
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+
+       dependency_libs="$deplibs"
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+         # these systems don't actually have a c library (as such)!
+         ;;
+        *-*-rhapsody* | *-*-darwin1.[012])
+         # Rhapsody C library is in the System framework
+         deplibs="$deplibs -framework System"
+         ;;
+       *)
+         # Add libc to deplibs on all other systems.
+         deplibs="$deplibs -lc"
+         ;;
+       esac
+      fi
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $output_objdir; then
+       $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+       $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      else
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case "$deplibs_check_method" in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behaviour.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $CC -o conftest conftest.c $deplibs
+         if test $? -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name="`expr X$i : 'X-l\(.*\)'`"
+             # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               deplib_matches=`eval \\$echo \"$library_names_spec\"`
+               set dummy $deplib_matches
+               deplib_match=$2
+               if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                 newdeplibs="$newdeplibs $i"
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning: This library needs some functionality provided by $i."
+                 echo "*** I have the capability to make that library automatically link in when"
+                 echo "*** you link to this library.  But I can only do this if you have a"
+                 echo "*** shared version of the library, which you do not appear to have."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occured in the first compile.  Let's try to salvage the situation:
+           # Compile a seperate program for each library.
+           for i in $deplibs; do
+             name="`expr X$i : 'X-l\(.*\)'`"
+            # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               $rm conftest
+               $CC -o conftest conftest.c $i
+               # Did it work?
+               if test $? -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   echo
+                   echo "*** Warning: This library needs some functionality provided by $i."
+                   echo "*** I have the capability to make that library automatically link in when"
+                   echo "*** you link to this library.  But I can only do this if you have a"
+                   echo "*** shared version of the library, which you do not appear to have."
+                 fi
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 echo "***  make it link in!  You will probably need to install it or some"
+                 echo "*** library that it depends on before this library will be fully"
+                 echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+         for a_deplib in $deplibs; do
+           name="`expr X$a_deplib : 'X-l\(.*\)'`"
+           # If $name is empty we are operating on a -L argument.
+           if test "$name" != "" ; then
+             libname=`eval \\$echo \"$libname_spec\"`
+             for i in $lib_search_path; do
+                   potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                   for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue 
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+                       case "$potliblink" in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | sed 10q \
+                        | egrep "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                   done
+             done
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               echo
+               echo "*** Warning: This library needs some functionality provided by $a_deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have."
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+              -e 's/ -[LR][^ ]*//g' -e 's/[    ]//g' |
+            grep . >/dev/null; then
+           echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           echo
+           echo "*** Warning: libtool could not satisfy all declared inter-library"
+           echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           echo "*** a static module, that should work as long as the dlopening"
+           echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             echo
+             echo "*** However, this would only work if libtool was able to extract symbol"
+             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             echo "*** not find such a program.  So, this module is probably useless."
+             echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           echo "*** The inter-library dependencies that have been dropped here will be"
+           echo "*** automatically added whenever a program is linked with this library"
+           echo "*** or is declared to -dlopen it."
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       # Get the real and link names of the library.
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+
+       lib="$output_objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Ensure that we have .o objects for linkers which dislike .lo
+       # (e.g. aix) in case we are running --disable-static
+       for obj in $libobjs; do
+         xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$obj"; then
+           xdir="."
+         else
+           xdir="$xdir"
+         fi
+         baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+         oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+         if test ! -f $xdir/$oldobj; then
+           $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+           $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+         fi
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           eval cmds=\"$export_symbols_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd" || exit $?
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "mkdir $gentop"
+           $run mkdir "$gentop"
+           status=$?
+           if test $status -ne 0 && test ! -d "$gentop"; then
+             exit $status
+           fi
+           generated="$generated $gentop"
+
+           for xlib in $convenience; do
+             # Extract the objects.
+             case "$xlib" in
+             [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+             *) xabs=`pwd`"/$xlib" ;;
+             esac
+             xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+             xdir="$gentop/$xlib"
+
+             $show "${rm}r $xdir"
+             $run ${rm}r "$xdir"
+             $show "mkdir $xdir"
+             $run mkdir "$xdir"
+             status=$?
+             if test $status -ne 0 && test ! -d "$xdir"; then
+               exit $status
+             fi
+             $show "(cd $xdir && $AR x $xabs)"
+             $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+             libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+           done
+         fi
+       fi
+
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linkopts="$linkopts $flag"
+       fi
+
+       # Do each of the archive commands.
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval cmds=\"$archive_expsym_cmds\"
+       else
+         if test "x$verstring" = "x0.0"; then
+           tmp_verstring=
+         else
+           tmp_verstring="$verstring"
+         fi
+         eval cmds=\"$archive_cmds\"
+       fi
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    *.lo | *.o | *.obj)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+       if test -n "$objs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit 1
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl= 
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         $show "${rm}r $gentop"
+         $run ${rm}r "$gentop"
+         $show "mkdir $gentop"
+         $run mkdir "$gentop"
+         status=$?
+         if test $status -ne 0 && test ! -d "$gentop"; then
+           exit $status
+         fi
+         generated="$generated $gentop"
+
+         for xlib in $convenience; do
+           # Extract the objects.
+           case "$xlib" in
+           [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+           *) xabs=`pwd`"/$xlib" ;;
+           esac
+           xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+           xdir="$gentop/$xlib"
+
+           $show "${rm}r $xdir"
+           $run ${rm}r "$xdir"
+           $show "mkdir $xdir"
+           $run mkdir "$xdir"
+           status=$?
+           if test $status -ne 0 && test ! -d "$xdir"; then
+             exit $status
+           fi
+           $show "(cd $xdir && $AR x $xabs)"
+           $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+           reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+         done
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > $libobj" || exit $?
+       exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       eval cmds=\"$reload_cmds\"
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      else
+       # Just create a symlink.
+       $show $rm $libobj
+       $run $rm $libobj
+       xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$libobj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+       oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+       $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+       $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    # Anything else should be a program.
+    *)
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi 
+      fi
+    
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$compile_rpath " in
+         *" $libdir "*) ;;
+         *) compile_rpath="$compile_rpath $libdir" ;;
+         esac
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      # Create the binary in the object directory, then wrap it.
+      if test ! -d $output_objdir; then
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case "$dlsyms" in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+           
+           if test -n "$export_symbols_regex"; then
+             $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$output.exp"
+             $run $rm $export_symbols
+             $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+           else
+             $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+             $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`echo "$arg" | sed -e 's%^.*/%%'`
+           $run eval 'echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
+               -e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
+                 < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case "$host" in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+         compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit 1
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       status=$?
+       
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case "$dir" in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+       
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+       case "$0" in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+       esac
+       $rm $output
+       trap "$rm $output; exit 1" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  link_against_libtool_libs='$link_against_libtool_libs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         echo >> $output "\
+  program=lt-'$outputname'
+  progdir=\"\$thisdir/$objdir\"
+  
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if (cd \"\$thisdir\" && eval \$relink_command); then :
+      else
+       $rm \"\$progdir/\$file\"
+       exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+       case $host in
+         # win32 systems need to use the prog path for dll
+         # lookup to work
+       *-*-cygwin*)
+         $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+         ;;
+
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       $show "${rm}r $gentop"
+       $run ${rm}r "$gentop"
+       $show "mkdir $gentop"
+       $run mkdir "$gentop"
+       status=$?
+       if test $status -ne 0 && test ! -d "$gentop"; then
+         exit $status
+       fi
+       generated="$generated $gentop"
+         
+       # Add in members from convenience archives.
+       for xlib in $addlibs; do
+         # Extract the objects.
+         case "$xlib" in
+         [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+         *) xabs=`pwd`"/$xlib" ;;
+         esac
+         xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+         xdir="$gentop/$xlib"
+
+         $show "${rm}r $xdir"
+         $run ${rm}r "$xdir"
+         $show "mkdir $xdir"
+         $run mkdir "$xdir"
+         status=$?
+         if test $status -ne 0 && test ! -d "$xdir"; then
+           exit $status
+         fi
+         $show "(cd $xdir && $AR x $xabs)"
+         $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+         oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+       done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       eval cmds=\"$old_archive_from_new_cmds\"
+      else
+       # Ensure that we have .o objects in place in case we decided
+       # not to build a shared library, and have fallen back to building
+       # static libs even though --disable-static was passed!
+       for oldobj in $oldobjs; do
+         if test ! -f $oldobj; then
+           xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$oldobj"; then
+             xdir="."
+           else
+             xdir="$xdir"
+           fi
+           baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+           obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+           $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+           $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+         fi
+       done
+
+       eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      if test -n "$xrpath"; then
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+       done
+       dependency_libs="$temp_xrpath $dependency_libs"
+      fi
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+         fi
+         $rm $output
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest="$arg"
+       continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*) ;;
+
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest="$arg"
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+    fi
+    case "$destdir" in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case "$file" in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a | *.lib)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       library_names=
+       old_library=
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$realname $destdir/$realname"
+         $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+         if test $# -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         eval cmds=\"$postinstall_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case "$destfile" in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.o | *.obj)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit 0
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         link_against_libtool_libs=
+         relink_command=
+
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$link_against_libtool_libs"; then
+           $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+           exit 1
+         fi
+
+         finalize=yes
+         for lib in $link_against_libtool_libs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case "$lib" in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir="/tmp"
+             test -n "$TMPDIR" && tmpdir="$TMPDIR"
+             tmpdir="$tmpdir/libtool-$$"
+             if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+             else
+               $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+               continue
+             fi
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         eval cmds=\"$finish_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+        # Export the shlibpath_var.
+        eval "export $shlibpath_var"
+      fi
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+        eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+        $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $dir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+         $show "$rm $rmfiles"
+         $run $rm $rmfiles
+
+         if test -n "$library_names"; then
+           # Do each command in the postuninstall commands.
+           eval cmds=\"$postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         if test -n "$old_library"; then
+           # Do each command in the old_postuninstall commands.
+           eval cmds=\"$old_postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         # FIXME: should reinstall the best remaining shared library.
+       fi
+       ;;
+
+      *.lo)
+       if test "$build_old_libs" = yes; then
+         oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+         rmfiles="$rmfiles $dir/$oldobj"
+       fi
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+
+      *)
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/config/missing b/config/missing
new file mode 100755 (executable)
index 0000000..6a37006
--- /dev/null
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case "$firstarg" in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case "$firstarg" in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/config/mkinstalldirs b/config/mkinstalldirs
new file mode 100755 (executable)
index 0000000..d2d5f21
--- /dev/null
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage" 1>&2
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+case $dirmode in
+  '')
+    if mkdir -p -- . 2>/dev/null; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+      else
+       if test ! -z "$dirmode"; then
+         echo "chmod $dirmode $pathcomp"
+         lasterr=""
+         chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+         if test ! -z "$lasterr"; then
+           errstatus=$lasterr
+         fi
+       fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/config/plain.m4 b/config/plain.m4
new file mode 100644 (file)
index 0000000..fd1fdd3
--- /dev/null
@@ -0,0 +1,32 @@
+dnl Check for PLAIN (and therefore crypt)
+
+AC_DEFUN([SASL_PLAIN_CHK],[
+AC_REQUIRE([SASL2_CRYPT_CHK])
+
+dnl PLAIN
+ AC_ARG_ENABLE(plain, [  --enable-plain          enable PLAIN authentication [yes] ],
+  plain=$enableval,
+  plain=yes)
+
+ PLAIN_LIBS=""
+ if test "$plain" != no; then
+  dnl In order to compile plain, we need crypt.
+  if test "$cmu_have_crypt" = yes; then
+    PLAIN_LIBS=$LIB_CRYPT
+  fi
+ fi
+ AC_SUBST(PLAIN_LIBS)
+
+ AC_MSG_CHECKING(PLAIN)
+ if test "$plain" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libplain.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS plain.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/plain.c"
+    AC_DEFINE(STATIC_PLAIN,[],[Link PLAIN Staticly])
+  fi
+ else
+  AC_MSG_RESULT(disabled)
+ fi
+])
diff --git a/config/sasl.spec b/config/sasl.spec
new file mode 100644 (file)
index 0000000..4a59ea2
--- /dev/null
@@ -0,0 +1,130 @@
+Summary: SASL API implementation
+Name: sasl
+Version: 2.0.1
+Release: 1
+Copyright: CMU
+Group: Libraries
+Source: ftp.andrew.cmu.edu:/pub/cyrus-mail/cyrus-sasl-2.0.1-ALPHA.tar.gz
+Packager: Rob Earhart <earhart@cmu.edu>
+Requires: gdbm
+
+%description
+This is an implemention of the SASL API, useful for adding
+authentication, authorization, and security to network protocols.  The
+SASL protocol itself is documented in rfc2222; the API standard is a
+work in progress.
+
+%package devel
+%summary: SASL development headers and examples
+
+%description devel
+This includes the header files and documentation needed to develop
+applications which use SASL.
+
+%package plug-anonymous
+%summary: SASL ANONYMOUS mechanism plugin
+
+%description plug-anonymous
+This plugin implements the SASL ANONYMOUS mechanism,
+used for anonymous authentication.
+
+%package plug-crammd5
+%summary: SASL CRAM-MD5 mechanism plugin
+
+%description plug-crammd5
+This plugin implements the SASL CRAM-MD5 mechanism.
+CRAM-MD5 is the mandatory-to-implement authentication mechanism for a
+number of protocols; it uses MD5 with a challenge/response system to
+authenticate the user.
+
+%package plug-digestmd5
+%summary: SASL DIGEST-MD5 mechanism plugin
+
+%description plug-digestmd5
+This plugin implements the latest draft of the SASL DIGEST-MD5
+mechanism.  Although not yet finalized, this is likely to become the
+new mandatory-to-implement authentication system in all new protocols.
+It's based on the digest md5 authentication system designed for HTTP.
+
+%package plug-kerberos4
+%summary: SASL KERBEROS_V4 mechanism plugin
+
+%description plug-kerberos4
+This plugin implements the SASL KERBEROS_V4 mechanism, allowing
+authentication via kerberos version four.
+
+%package plug-plain
+%summary: SASL PLAIN mechanism plugin
+
+%description plug-plain
+This plugin implements the SASL PLAIN mechanism.  Although insecure,
+PLAIN is useful for transitioning to new security mechanisms, as this
+is the only mechanism which gives the server a copy of the user's
+password.
+
+%package plug-scrammd5
+%summary: SASL SCRAM-MD5 mechanism plugin
+
+%description plug-scrammd5
+This plugin implements the SASL SCRAM-MD5 mechanism.  Although
+deprecated (this will be replaced by DIGEST-MD5 at some point), it may
+be useful for the time being.
+
+%prep
+%setup
+
+%build
+./configure --prefix=/usr --disable-java
+make
+
+%install
+make install
+
+%post
+if test $RPM_INSTALL_PREFIX/lib/sasl != /usr/lib/sasl; then
+  ln -s $RPM_INSTALL_PREFIX/lib/sasl /usr/lib/sasl
+fi
+
+%postun
+if test -L /usr/lib/sasl; then
+  rm /usr/lib/sasl
+fi
+
+%files
+%doc README COPYING ChangeLog NEWS AUTHORS
+/usr/lib/libsasl.so.5.0.0
+/usr/sbin/saslpasswd
+/usr/man/man8/saslpasswd.8
+
+%files devel
+%doc doc/rfc2222.txt sample/sample-client.c sample/sample-server.c testing.txt
+/usr/lib/libsasl.la
+/usr/include/sasl.h
+/usr/include/saslplug.h
+/usr/include/saslutil.h
+/usr/include/md5global.h
+/usr/include/md5.h
+/usr/include/hmac-md5.h
+
+%files plug-anonymous
+%doc doc/draft-newman-sasl-anon-00.txt
+/usr/lib/sasl/libanonymous.so.1.0.2
+/usr/lib/sasl/libanonymous.so
+
+%files plug-crammd5
+%doc doc/rfc1321.txt doc/rfc2095.txt doc/rfc2104.txt
+/usr/lib/sasl/libcrammd5.so.1.0.1
+/usr/lib/sasl/libcrammd5.so
+
+%files plug-digestmd5
+%doc doc/draft-leach-digest-sasl-01.txt 
+/usr/lib/sasl/libdigestmd5.so.0.0.1
+/usr/lib/sasl/libdigestmd5.so
+
+%files plug-kerberos4
+/usr/lib/sasl/libkerberos4.so.1.0.2
+/usr/lib/sasl/libkerberos4.so
+
+%files plug-plain
+/usr/lib/sasl/libplain.so.1.0.1
+/usr/lib/sasl/libplain.so
diff --git a/config/sasldb.m4 b/config/sasldb.m4
new file mode 100644 (file)
index 0000000..2a812f5
--- /dev/null
@@ -0,0 +1,156 @@
+dnl Functions to check what database to use for libsasldb
+
+dnl Berkeley DB specific checks first..
+
+dnl Figure out what database type we're using
+AC_DEFUN([SASL_DB_CHECK], [
+cmu_save_LIBS="$LIBS"
+AC_ARG_WITH(dblib, [  --with-dblib=DBLIB      set the DB library to use [berkeley] ],
+  dblib=$withval,
+  dblib=auto_detect)
+
+CYRUS_BERKELEY_DB_OPTS()
+
+SASL_DB_LIB=""
+
+case "$dblib" in
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named.  arg.
+  berkeley)
+       CYRUS_BERKELEY_DB_CHK()
+       CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+       SASL_DB_INC=$BDB_INCADD
+       SASL_DB_LIB="${BDB_LIBADD}"
+       ;;
+  gdbm)
+       AC_ARG_WITH(gdbm,[  --with-gdbm=PATH        use gdbm from PATH],
+                    with_gdbm="${withval}")
+
+        case "$with_gdbm" in
+           ""|yes)
+               AC_CHECK_HEADER(gdbm.h, [
+                       AC_CHECK_LIB(gdbm, gdbm_open, SASL_DB_LIB="-lgdbm",
+                                           dblib="no")],
+                       dblib="no")
+               ;;
+           *)
+               if test -d $with_gdbm; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_gdbm}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_gdbm}/lib"
+                 SASL_DB_LIB="-lgdbm" 
+               else
+                 with_gdbm="no"
+               fi
+       esac
+       ;;
+  ndbm)
+       dnl We want to attempt to use -lndbm if we can, just in case
+       dnl there's some version of it installed and overriding libc
+       AC_CHECK_HEADER(ndbm.h, [
+                       AC_CHECK_LIB(ndbm, dbm_open, SASL_DB_LIB="-lndbm", [
+                               AC_CHECK_FUNC(dbm_open,,dblib="no")])],
+                               dblib="no")
+       ;;
+  auto_detect)
+        dnl How about berkeley db?
+       CYRUS_BERKELEY_DB_CHK()
+       if test "$dblib" = no; then
+         dnl How about ndbm?
+         AC_CHECK_HEADER(ndbm.h, [
+               AC_CHECK_LIB(ndbm, dbm_open,
+                            dblib="ndbm"; SASL_DB_LIB="-lndbm",
+                            dblib="weird")],
+                  dblib="no")
+         if test "$dblib" = "weird"; then
+           dnl Is ndbm in the standard library?
+            AC_CHECK_FUNC(dbm_open, dblib="ndbm", dblib="no")
+         fi
+
+         if test "$dblib" = no; then
+            dnl Can we use gdbm?
+           AC_CHECK_HEADER(gdbm.h, [
+               AC_CHECK_LIB(gdbm, gdbm_open, dblib="gdbm";
+                                            SASL_DB_LIB="-lgdbm", dblib="no")],
+                            dblib="no")
+         fi
+       else
+         dnl we took Berkeley
+         CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+         SASL_DB_INC=$BDB_INCADD
+          SASL_DB_LIB="${BDB_LIBADD}"
+       fi
+       ;;
+  none)
+       ;;
+  no)
+       ;;
+  *)
+       AC_MSG_WARN([Bad DB library implementation specified;])
+       AC_ERROR([Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"])
+       dblib=no
+       ;;
+esac
+LIBS="$cmu_save_LIBS"
+
+AC_MSG_CHECKING(DB library to use)
+AC_MSG_RESULT($dblib)
+
+SASL_DB_BACKEND="db_${dblib}.lo"
+SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
+SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_${dblib}.c ../sasldb/allockey.c"
+SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
+
+case "$dblib" in
+  gdbm) 
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_GDBM,[],[Use GDBM for SASLdb])
+    ;;
+  ndbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_NDBM,[],[Use NDBM for SASLdb])
+    ;;
+  berkeley)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_BERKELEYDB,[],[Use BerkeleyDB for SASLdb])
+    ;;
+  *)
+    AC_MSG_WARN([Disabling SASL authentication database support])
+    dnl note that we do not add libsasldb.la to SASL_MECHS, since it
+    dnl will just fail to load anyway.
+    SASL_DB_BACKEND="db_none.lo"
+    SASL_DB_BACKEND_STATIC="db_none.o"
+    SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_none.c"
+    SASL_DB_UTILS=""
+    SASL_DB_MANS=""
+    SASL_DB_LIB=""
+    ;;
+esac
+
+if test "$enable_static" = yes; then
+    if test "$dblib" != "none"; then
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sasldb.c $SASL_DB_BACKEND_STATIC_SRCS"
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS sasldb.o $SASL_DB_BACKEND_STATIC"
+      AC_DEFINE(STATIC_SASLDB,[],[Link SASLdb Staticly])
+    else
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS $SASL_DB_BACKEND_STATIC"
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS $SASL_DB_BACKEND_STATIC_SRCS"
+    fi
+fi
+
+AC_SUBST(SASL_DB_UTILS)
+AC_SUBST(SASL_DB_MANS)
+AC_SUBST(SASL_DB_BACKEND)
+AC_SUBST(SASL_DB_BACKEND_STATIC)
+AC_SUBST(SASL_DB_INC)
+AC_SUBST(SASL_DB_LIB)
+])
+
+dnl Figure out what database path we're using
+AC_DEFUN([SASL_DB_PATH_CHECK], [
+AC_ARG_WITH(dbpath, [  --with-dbpath=PATH      set the DB path to use [/etc/sasldb2] ],
+  dbpath=$withval,
+  dbpath=/etc/sasldb2)
+AC_MSG_CHECKING(DB path to use)
+AC_MSG_RESULT($dbpath)
+AC_DEFINE_UNQUOTED(SASL_DB_PATH, "$dbpath", [Path to default SASLdb database])])
diff --git a/configure b/configure
new file mode 100755 (executable)
index 0000000..d6107e9
--- /dev/null
+++ b/configure
@@ -0,0 +1,17019 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="lib/saslint.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subdirs_all="$ac_subdirs_all saslauthd"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP LN_S RANLIB ac_ct_RANLIB LIBTOOL PURECOV PURIFY JAVAC JAVAH JAVADOC JAVA_TRUE JAVA_FALSE JAVA_INCLUDES JAVAROOT SAMPLE_TRUE SAMPLE_FALSE LIB_SOCKET EGREP SASL_DB_UTILS SASL_DB_MANS SASL_DB_BACKEND SASL_DB_BACKEND_STATIC SASL_DB_INC SASL_DB_LIB NO_SASL_DB_MANS_TRUE NO_SASL_DB_MANS_FALSE SASL_DL_LIB NM SASLAUTHD_TRUE SASLAUTHD_FALSE PWCHECKMETH PWCHECK_TRUE PWCHECK_FALSE IPCTYPE LIB_DOOR CMU_LIB_SUBDIR LIB_DES OTP_LIBS SRP_LIBS SASL_KRB_LIB LIB_CRYPT GSSAPI_LIBS GSSAPIBASE_LIBS PLAIN_LIBS NTLM_LIBS PASSDSS_LIBS LIB_MYSQL LIB_PGSQL LIB_SQLITE LIB_LDAP SASL_MECHS SASL_STATIC_SRCS SASL_STATIC_OBJS SASL_STATIC_LIBS plugindir configdir MACOSX_TRUE MACOSX_FALSE DMALLOC_LIBS SFIO_INC_FLAGS SFIO_LIB_FLAGS SMTPTEST_PROGRAM SASL_UTIL_LIBS_EXTRA SASL_UTIL_HEADERS_EXTRA LIBOBJS GETSUBOPT SNPRINTFOBJS LTSNPRINTFOBJS GETADDRINFOOBJS LTGETADDRINFOOBJS GETNAMEINFOOBJS LTGETNAMEINFOOBJS LTLIBOBJS DIRS subdirs'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+  --target=TARGET   configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-cmulocal       enable local mods for CMU [[no]]
+  --enable-sample         compile sample code [[yes]]
+  --disable-dependency-tracking Speeds up one-time builds
+  --enable-dependency-tracking  Do not reject slow dependency extractors
+  --enable-static=PKGS  build static libraries default=no
+  --enable-shared=PKGS  build shared libraries default=yes
+  --enable-fast-install=PKGS  optimize for fast installation default=yes
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-staticdlopen   try dynamic plugins when we are a static libsasl [no]
+  --enable-java           compile Java support [no]
+  --enable-keep-db-open   keep handle to Berkeley DB open for improved performance [no]
+  --enable-alwaystrue     enable the alwaystrue password verifier (discouraged)
+  --enable-checkapop      enable use of sasl_checkapop [yes]
+  --enable-cram           enable CRAM-MD5 authentication [yes]
+  --enable-digest         enable DIGEST-MD5 authentication [yes]
+  --enable-otp            enable OTP authentication [yes]
+  --enable-srp            enable SRP authentication [no]
+  --enable-srp-setpass    enable setting SRP secrets with saslpasswd [no]
+  --enable-krb4           enable KERBEROS_V4 authentication [no]
+  --enable-gssapi=<DIR>   enable GSSAPI authentication [yes]
+  --enable-gss_mutexes     use mutexes around calls to the GSS library
+  --enable-plain          enable PLAIN authentication yes
+  --enable-anon           enable ANONYMOUS authentication [yes]
+  --enable-login          enable unsupported LOGIN authentication [no]
+  --enable-ntlm           enable unsupported NTLM authentication [no]
+  --enable-passdss        enable PASSDSS authentication (experimental) [no]
+  --enable-sql            enable SQL auxprop [no]
+  --enable-ldapdb         enable LDAPDB plugin no
+  --disable-macos-framework       disable building and installing replacement SASL2 Framework for MacOS X-provided SASL Framework [no]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+
+  --with-gnu-ld           assume the C compiler uses GNU ld default=no
+  --with-purecov          link with purecov
+  --with-purify           link with purify
+  --with-javabase=PATH    set path to find jni.h in /usr/java/include
+  --with-dbpath=PATH      set the DB path to use /etc/sasldb2
+  --with-dblib=DBLIB      set the DB library to use berkeley
+  --with-bdb-libdir=DIR   Berkeley DB lib files are in DIR
+  --with-bdb-incdir=DIR   Berkeley DB include files are in DIR
+  --with-gdbm=PATH        use gdbm from PATH
+  --with-devrandom=PATH   set the path to /dev/random [/dev/random]
+  --with-pam=DIR          use PAM (rooted in DIR) [yes]
+  --with-saslauthd=DIR    enable use of the saslauth daemon using state dir DIR
+  --with-authdaemond=PATH enable use of authdaemon with default socket=PATH [yes]
+  --with-pwcheck=DIR     enable deprecated pwcheck daemon using statedir DIR
+  --with-ipctype={unix,doors}    use ipctype [unix]
+  --with-lib-subdir=DIR   Find libraries in DIR instead of lib
+  --with-openssl=PATH     use OpenSSL from PATH
+  --with-des=DIR          with DES (look in DIR) yes
+  --with-opie=PATH        use OPIE (One Time Passwords in Everything) from PATH
+  --with-gss_impl={heimdal|mit|cybersafe|seam|auto}
+                          choose specific GSSAPI implementation [[auto]]
+  --with-ldap=DIR         use LDAP (in DIR) for saslauthd no
+  --with-mysql=PATH       use MySQL from PATH
+  --with-pgsql=PATH       use PostgreSQL from PATH
+  --with-sqlite=PATH       use SQLite from PATH
+  --with-plugindir=DIR    set the directory where plugins will
+                          be found [/usr/lib/sasl2]
+   --with-configdir=DIR    set the directory where config files will
+                          be found /usr/lib/sasl2
+  --with-rc4              use internal rc4 routines [yes]
+  --with-dmalloc=DIR      with DMALLOC support (for test applications) [no]
+  --with-sfio=DIR         with SFIO support (for smtptest/libsfsasl) [no]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+        ac_must_keep_next=false # Got value, back to normal.
+      else
+        case $ac_arg in
+          *=* | --config-cache | -C | -disable-* | --disable-* \
+          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+          | -with-* | --with-* | -without-* | --without-* | --x)
+            case "$ac_configure_args0 " in
+              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+            esac
+            ;;
+          -* ) ac_must_keep_next=true ;;
+        esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+        echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test $cache_file = "/dev/null"; then
+cache_file="./config.cache"
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+fi
+
+ac_aux_dir=
+for ac_dir in config $srcdir/config; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking target system type" >&5
+echo $ECHO_N "checking target system type... $ECHO_C" >&6
+if test "${ac_cv_target+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_target_alias=$target_alias
+test "x$ac_cv_target_alias" = "x" &&
+  ac_cv_target_alias=$ac_cv_host_alias
+ac_cv_target=`$ac_config_sub $ac_cv_target_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_target_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_target_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_target" >&5
+echo "${ECHO_T}$ac_cv_target" >&6
+target=$ac_cv_target
+target_cpu=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $ac_cv_target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+am__api_version="1.7"
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+ # test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=cyrus-sasl
+ VERSION=2.1.23
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+
+
+
+
+
+       ACLOCAL="$ACLOCAL -I \$(top_srcdir)/cmulocal"
+
+
+# and include our config dir scripts
+ACLOCAL="$ACLOCAL -I \$(top_srcdir)/config"
+
+DIRS=""
+
+# Check whether --enable-cmulocal or --disable-cmulocal was given.
+if test "${enable_cmulocal+set}" = set; then
+  enableval="$enable_cmulocal"
+
+else
+  enable_cmulocal=no
+fi;
+
+# Check whether --enable-sample or --disable-sample was given.
+if test "${enable_sample+set}" = set; then
+  enableval="$enable_sample"
+  enable_sample=yes
+fi;
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+        ;;
+    conftest.$ac_ext )
+        # This is the source file.
+        ;;
+    [ab].out )
+        # We found the default executable, but exeext='' is most
+        # certainly right.
+        break;;
+    *.* )
+        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+        # FIXME: I believe we export ac_cv_exeext for Libtool,
+        # but it would be cool to find out if it's true.  Does anybody
+        # maintain Libtool? --akim.
+        export ac_cv_exeext
+        break;;
+    * )
+        break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+          ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      : > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+
+echo "$as_me:$LINENO: checking for __attribute__" >&5
+echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6
+if test "${ac_cv___attribute__+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+
+int
+main ()
+{
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+  exit(1);
+}
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv___attribute__=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv___attribute__=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "$ac_cv___attribute__" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___ATTRIBUTE__ 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv___attribute__" >&5
+echo "${ECHO_T}$ac_cv___attribute__" >&6
+
+
+
+   # CMU GUESS RUNPATH SWITCH
+  echo "$as_me:$LINENO: checking for runpath switch" >&5
+echo $ECHO_N "checking for runpath switch... $ECHO_C" >&6
+if test "${andrew_runpath_switch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    # first, try -R
+    SAVE_LDFLAGS="${LDFLAGS}"
+    LDFLAGS="-R /usr/lib"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  andrew_runpath_switch="-R"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+       LDFLAGS="-Wl,-rpath,/usr/lib"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  andrew_runpath_switch="-Wl,-rpath,"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+andrew_runpath_switch="none"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS="${SAVE_LDFLAGS}"
+
+fi
+echo "$as_me:$LINENO: result: $andrew_runpath_switch" >&5
+echo "${ECHO_T}$andrew_runpath_switch" >&6
+
+
+# Check whether --with-staticsasl or --without-staticsasl was given.
+if test "${with_staticsasl+set}" = set; then
+  withval="$with_staticsasl"
+
+fi;
+if test "$with_staticsasl" = yes; then
+       enable_shared=yes
+       enable_static=yes
+fi
+
+save_target=$target
+if test -z "$target"; then
+       target="NONE"
+fi
+
+# new libtool
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=no
+fi;
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi;
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi;
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$ac_cv_c_compiler_gnu" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by GCC" >&5
+echo $ECHO_N "checking for ld used by GCC... $ECHO_C" >&6
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${ac_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${ac_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$ac_cv_prog_gnu_ld" >&6
+
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${ac_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6
+
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_c_compiler_gnu" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 3769 "configure"' > conftest.$ac_ext
+  if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { { echo "$as_me:$LINENO: error: libtool configure failed" >&5
+echo "$as_me: error: libtool configure failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+target=$save_target
+
+if test "$enable_static" = yes; then
+       SASL_STATIC_LIBS=libsasl2.a
+else
+       SASL_STATIC_LIBS=
+fi
+
+# Check whether --enable-staticdlopen or --disable-staticdlopen was given.
+if test "${enable_staticdlopen+set}" = set; then
+  enableval="$enable_staticdlopen"
+  enable_staticdlopen=$enableval
+else
+  enable_staticdlopen=no
+fi;
+
+if test "$enable_staticdlopen" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TRY_DLOPEN_WHEN_STATIC
+_ACEOF
+
+fi
+
+if test "$ac_cv_c_compiler_gnu" = yes; then
+  CFLAGS="-Wall -W ${CFLAGS}"
+fi
+
+
+# Check whether --with-purecov or --without-purecov was given.
+if test "${with_purecov+set}" = set; then
+  withval="$with_purecov"
+
+fi;
+if test "$with_purecov" = yes; then
+  for ac_prog in purecov
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_PURECOV+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$PURECOV"; then
+  ac_cv_prog_PURECOV="$PURECOV" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PURECOV="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+PURECOV=$ac_cv_prog_PURECOV
+if test -n "$PURECOV"; then
+  echo "$as_me:$LINENO: result: $PURECOV" >&5
+echo "${ECHO_T}$PURECOV" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$PURECOV" && break
+done
+
+fi
+
+# Check whether --with-purify or --without-purify was given.
+if test "${with_purify+set}" = set; then
+  withval="$with_purify"
+
+fi;
+if test "$with_purify" = yes; then
+  for ac_prog in purify
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_PURIFY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$PURIFY"; then
+  ac_cv_prog_PURIFY="$PURIFY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PURIFY="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+PURIFY=$ac_cv_prog_PURIFY
+if test -n "$PURIFY"; then
+  echo "$as_me:$LINENO: result: $PURIFY" >&5
+echo "${ECHO_T}$PURIFY" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$PURIFY" && break
+done
+
+fi
+
+# Check whether --enable-java or --disable-java was given.
+if test "${enable_java+set}" = set; then
+  enableval="$enable_java"
+  enable_java=$enableval
+else
+  enable_java=no
+fi;
+if test "$enable_java" = yes; then
+  # Extract the first word of "javac", so it can be a program name with args.
+set dummy javac; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAVAC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $JAVAC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_JAVAC="$JAVAC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_JAVAC="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_JAVAC" && ac_cv_path_JAVAC="no"
+  ;;
+esac
+fi
+JAVAC=$ac_cv_path_JAVAC
+
+if test -n "$JAVAC"; then
+  echo "$as_me:$LINENO: result: $JAVAC" >&5
+echo "${ECHO_T}$JAVAC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  for ac_prog in javah kaffeh
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_JAVAH+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $JAVAH in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_JAVAH="$JAVAH" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_JAVAH="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+JAVAH=$ac_cv_path_JAVAH
+
+if test -n "$JAVAH"; then
+  echo "$as_me:$LINENO: result: $JAVAH" >&5
+echo "${ECHO_T}$JAVAH" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$JAVAH" && break
+done
+test -n "$JAVAH" || JAVAH="no"
+
+  for ac_prog in javadoc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_JAVADOC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$JAVADOC"; then
+  ac_cv_prog_JAVADOC="$JAVADOC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_JAVADOC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+JAVADOC=$ac_cv_prog_JAVADOC
+if test -n "$JAVADOC"; then
+  echo "$as_me:$LINENO: result: $JAVADOC" >&5
+echo "${ECHO_T}$JAVADOC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$JAVADOC" && break
+done
+test -n "$JAVADOC" || JAVADOC=":"
+
+  if test "$JAVAC" = "no" -o "$JAVAH" = "no"; then
+    { echo "$as_me:$LINENO: WARNING: Disabling Java support" >&5
+echo "$as_me: WARNING: Disabling Java support" >&2;}
+    enable_java=no
+  fi
+else
+# Make distcheck work
+  JAVAC="true"
+  JAVAH="true"
+  JAVADOC="true"
+fi
+
+
+if test "$enable_java" = yes; then
+  JAVA_TRUE=
+  JAVA_FALSE='#'
+else
+  JAVA_TRUE='#'
+  JAVA_FALSE=
+fi
+
+
+if test "$enable_java" = yes; then
+  echo "$as_me:$LINENO: checking JNI cpp flags" >&5
+echo $ECHO_N "checking JNI cpp flags... $ECHO_C" >&6
+  if test "${sasl_cv_java_includes+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+  if test `echo $JAVAH | sed 's,.*/,,'` = "kaffeh"; then
+    sasl_cv_java_includes=-I`echo $JAVAH | sed -e 's,/bin.*,/include/kaffe,'`
+  else
+    java_base=`echo $JAVAC | sed 's,/bin.*,'','`
+
+
+# Check whether --with-javabase or --without-javabase was given.
+if test "${with_javabase+set}" = set; then
+  withval="$with_javabase"
+  java_base=$withval
+fi;
+
+
+    sasl_cv_java_includes=''
+    for dir in `find ${java_base}/include -follow -type d -print | grep -v green_threads`; do
+      sasl_cv_java_includes="${sasl_cv_java_includes} -I$dir"
+    done
+  fi
+
+  sasl_cv_java_includes="${sasl_cv_java_includes} -I$javapath/include"
+fi
+
+
+  JAVA_INCLUDES=$sasl_cv_java_includes
+
+  echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+
+  JAVAROOT=".."
+
+  JAVAC=`echo "$JAVAC" | sed 's,.*/,,'`
+  JAVAH=`echo "$JAVAH" | sed 's,.*/,,'`
+fi
+
+
+
+if test "$enable_sample" = yes; then
+  SAMPLE_TRUE=
+  SAMPLE_FALSE='#'
+else
+  SAMPLE_TRUE='#'
+  SAMPLE_FALSE=
+fi
+
+
+
+       save_LIBS="$LIBS"
+       LIB_SOCKET=""
+       echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIB_SOCKET="-lnsl $LIB_SOCKET"
+fi
+
+               echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+int
+main ()
+{
+connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_connect=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+if test $ac_cv_lib_socket_connect = yes; then
+  LIB_SOCKET="-lsocket $LIB_SOCKET"
+fi
+
+
+fi
+
+       LIBS="$LIB_SOCKET $save_LIBS"
+       echo "$as_me:$LINENO: checking for res_search" >&5
+echo $ECHO_N "checking for res_search... $ECHO_C" >&6
+if test "${ac_cv_func_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char res_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_res_search) || defined (__stub___res_search)
+choke me
+#else
+char (*f) () = res_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != res_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_res_search" >&5
+echo "${ECHO_T}$ac_cv_func_res_search" >&6
+if test $ac_cv_func_res_search = yes; then
+  :
+else
+  LIBS="-lresolv $LIB_SOCKET $save_LIBS"
+               cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>
+int
+main ()
+{
+
+const char host[12]="openafs.org";
+u_char ans[1024];
+res_search( host, C_IN, T_MX, (u_char *)&ans, sizeof(ans));
+return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIB_SOCKET="-lresolv $LIB_SOCKET"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+       LIBS="$LIB_SOCKET $save_LIBS"
+
+
+for ac_func in dn_expand dns_lookup
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       LIBS="$save_LIBS"
+
+
+
+
+
+# Check whether --with-dbpath or --without-dbpath was given.
+if test "${with_dbpath+set}" = set; then
+  withval="$with_dbpath"
+  dbpath=$withval
+else
+  dbpath=/etc/sasldb2
+fi;
+echo "$as_me:$LINENO: checking DB path to use" >&5
+echo $ECHO_N "checking DB path to use... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $dbpath" >&5
+echo "${ECHO_T}$dbpath" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SASL_DB_PATH "$dbpath"
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+cmu_save_LIBS="$LIBS"
+
+# Check whether --with-dblib or --without-dblib was given.
+if test "${with_dblib+set}" = set; then
+  withval="$with_dblib"
+  dblib=$withval
+else
+  dblib=auto_detect
+fi;
+
+
+
+# Check whether --with-bdb-libdir or --without-bdb-libdir was given.
+if test "${with_bdb_libdir+set}" = set; then
+  withval="$with_bdb_libdir"
+  with_bdb_lib=$withval
+else
+   test "${with_bdb_lib+set}" = set || with_bdb_lib=none
+fi;
+
+# Check whether --with-bdb-incdir or --without-bdb-incdir was given.
+if test "${with_bdb_incdir+set}" = set; then
+  withval="$with_bdb_incdir"
+  with_bdb_inc=$withval
+else
+   test "${with_bdb_inc+set}" = set || with_bdb_inc=none
+fi;
+
+
+SASL_DB_LIB=""
+
+case "$dblib" in
+  berkeley)
+
+
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+                       if test "${ac_cv_header_db_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking db.h usability" >&5
+echo $ECHO_N "checking db.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <db.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking db.h presence" >&5
+echo $ECHO_N "checking db.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: db.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: db.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: db.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_db_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+
+fi
+if test $ac_cv_header_db_h = yes; then
+
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD}"
+  else
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_create(NULL, NULL, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_open(NULL, 0, 0, 0, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+
+else
+  dblib="no"
+fi
+
+
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+
+       CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+       SASL_DB_INC=$BDB_INCADD
+       SASL_DB_LIB="${BDB_LIBADD}"
+       ;;
+  gdbm)
+
+# Check whether --with-gdbm or --without-gdbm was given.
+if test "${with_gdbm+set}" = set; then
+  withval="$with_gdbm"
+  with_gdbm="${withval}"
+fi;
+
+        case "$with_gdbm" in
+           ""|yes)
+               if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gdbm.h usability" >&5
+echo $ECHO_N "checking gdbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gdbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gdbm.h presence" >&5
+echo $ECHO_N "checking gdbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gdbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gdbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gdbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gdbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+
+fi
+if test $ac_cv_header_gdbm_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for gdbm_open in -lgdbm" >&5
+echo $ECHO_N "checking for gdbm_open in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_gdbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdbm_open ();
+int
+main ()
+{
+gdbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gdbm_gdbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_gdbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gdbm_gdbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_gdbm_open" >&6
+if test $ac_cv_lib_gdbm_gdbm_open = yes; then
+  SASL_DB_LIB="-lgdbm"
+else
+  dblib="no"
+fi
+
+else
+  dblib="no"
+fi
+
+
+               ;;
+           *)
+               if test -d $with_gdbm; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_gdbm}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_gdbm}/lib"
+                 SASL_DB_LIB="-lgdbm"
+               else
+                 with_gdbm="no"
+               fi
+       esac
+       ;;
+  ndbm)
+                       if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking ndbm.h usability" >&5
+echo $ECHO_N "checking ndbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <ndbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking ndbm.h presence" >&5
+echo $ECHO_N "checking ndbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ndbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: ndbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: ndbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_ndbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+
+fi
+if test $ac_cv_header_ndbm_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
+echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ndbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
+if test $ac_cv_lib_ndbm_dbm_open = yes; then
+  SASL_DB_LIB="-lndbm"
+else
+
+                               echo "$as_me:$LINENO: checking for dbm_open" >&5
+echo $ECHO_N "checking for dbm_open... $ECHO_C" >&6
+if test "${ac_cv_func_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dbm_open (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
+choke me
+#else
+char (*f) () = dbm_open;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dbm_open;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_func_dbm_open" >&6
+if test $ac_cv_func_dbm_open = yes; then
+  :
+else
+  dblib="no"
+fi
+
+fi
+
+else
+  dblib="no"
+fi
+
+
+       ;;
+  auto_detect)
+
+
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+                       if test "${ac_cv_header_db_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking db.h usability" >&5
+echo $ECHO_N "checking db.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <db.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking db.h presence" >&5
+echo $ECHO_N "checking db.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: db.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: db.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: db.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_db_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+
+fi
+if test $ac_cv_header_db_h = yes; then
+
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD}"
+  else
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_create(NULL, NULL, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_open(NULL, 0, 0, 0, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+
+else
+  dblib="no"
+fi
+
+
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+
+       if test "$dblib" = no; then
+                 if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking ndbm.h usability" >&5
+echo $ECHO_N "checking ndbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <ndbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking ndbm.h presence" >&5
+echo $ECHO_N "checking ndbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ndbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: ndbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: ndbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_ndbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+
+fi
+if test $ac_cv_header_ndbm_h = yes; then
+
+               echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
+echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ndbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
+if test $ac_cv_lib_ndbm_dbm_open = yes; then
+  dblib="ndbm"; SASL_DB_LIB="-lndbm"
+else
+  dblib="weird"
+fi
+
+else
+  dblib="no"
+fi
+
+
+         if test "$dblib" = "weird"; then
+                       echo "$as_me:$LINENO: checking for dbm_open" >&5
+echo $ECHO_N "checking for dbm_open... $ECHO_C" >&6
+if test "${ac_cv_func_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dbm_open (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
+choke me
+#else
+char (*f) () = dbm_open;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dbm_open;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_func_dbm_open" >&6
+if test $ac_cv_func_dbm_open = yes; then
+  dblib="ndbm"
+else
+  dblib="no"
+fi
+
+         fi
+
+         if test "$dblib" = no; then
+                           if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gdbm.h usability" >&5
+echo $ECHO_N "checking gdbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gdbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gdbm.h presence" >&5
+echo $ECHO_N "checking gdbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gdbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gdbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gdbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gdbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+
+fi
+if test $ac_cv_header_gdbm_h = yes; then
+
+               echo "$as_me:$LINENO: checking for gdbm_open in -lgdbm" >&5
+echo $ECHO_N "checking for gdbm_open in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_gdbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdbm_open ();
+int
+main ()
+{
+gdbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gdbm_gdbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_gdbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gdbm_gdbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_gdbm_open" >&6
+if test $ac_cv_lib_gdbm_gdbm_open = yes; then
+  dblib="gdbm";
+                                            SASL_DB_LIB="-lgdbm"
+else
+  dblib="no"
+fi
+
+else
+  dblib="no"
+fi
+
+
+         fi
+       else
+                 CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+         SASL_DB_INC=$BDB_INCADD
+          SASL_DB_LIB="${BDB_LIBADD}"
+       fi
+       ;;
+  none)
+       ;;
+  no)
+       ;;
+  *)
+       { echo "$as_me:$LINENO: WARNING: Bad DB library implementation specified;" >&5
+echo "$as_me: WARNING: Bad DB library implementation specified;" >&2;}
+       { { echo "$as_me:$LINENO: error: Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"" >&5
+echo "$as_me: error: Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"" >&2;}
+   { (exit 1); exit 1; }; }
+       dblib=no
+       ;;
+esac
+LIBS="$cmu_save_LIBS"
+
+echo "$as_me:$LINENO: checking DB library to use" >&5
+echo $ECHO_N "checking DB library to use... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $dblib" >&5
+echo "${ECHO_T}$dblib" >&6
+
+SASL_DB_BACKEND="db_${dblib}.lo"
+SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
+SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_${dblib}.c ../sasldb/allockey.c"
+SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
+
+case "$dblib" in
+  gdbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_GDBM
+_ACEOF
+
+    ;;
+  ndbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_NDBM
+_ACEOF
+
+    ;;
+  berkeley)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_BERKELEYDB
+_ACEOF
+
+    ;;
+  *)
+    { echo "$as_me:$LINENO: WARNING: Disabling SASL authentication database support" >&5
+echo "$as_me: WARNING: Disabling SASL authentication database support" >&2;}
+            SASL_DB_BACKEND="db_none.lo"
+    SASL_DB_BACKEND_STATIC="db_none.o"
+    SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_none.c"
+    SASL_DB_UTILS=""
+    SASL_DB_MANS=""
+    SASL_DB_LIB=""
+    ;;
+esac
+
+if test "$enable_static" = yes; then
+    if test "$dblib" != "none"; then
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sasldb.c $SASL_DB_BACKEND_STATIC_SRCS"
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS sasldb.o $SASL_DB_BACKEND_STATIC"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_SASLDB
+_ACEOF
+
+    else
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS $SASL_DB_BACKEND_STATIC"
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS $SASL_DB_BACKEND_STATIC_SRCS"
+    fi
+fi
+
+
+
+
+
+
+
+
+
+# Do we not install the SASL DB man pages?
+
+
+if test "x$SASL_DB_MANS" = "x"; then
+  NO_SASL_DB_MANS_TRUE=
+  NO_SASL_DB_MANS_FALSE='#'
+else
+  NO_SASL_DB_MANS_TRUE='#'
+  NO_SASL_DB_MANS_FALSE=
+fi
+
+
+# Check whether --enable-keep_db_open or --disable-keep_db_open was given.
+if test "${enable_keep_db_open+set}" = set; then
+  enableval="$enable_keep_db_open"
+  keep_db_open=$enableval
+else
+  keep_db_open=no
+fi;
+
+# Disable if Berkeley DB is not used
+if test "$dblib" != berkeley; then
+  keep_db_open=no
+fi
+
+if test "$keep_db_open" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define KEEP_DB_OPEN
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: checking if Berkeley DB handle is kept open in SASLDB" >&5
+echo $ECHO_N "checking if Berkeley DB handle is kept open in SASLDB... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $keep_db_open" >&5
+echo "${ECHO_T}$keep_db_open" >&6
+
+echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  SASL_DL_LIB="-ldl"
+else
+  SASL_DL_LIB=""
+fi
+
+
+
+
+
+# Check whether --with-devrandom or --without-devrandom was given.
+if test "${with_devrandom+set}" = set; then
+  withval="$with_devrandom"
+  devrandom=$withval
+else
+  devrandom=/dev/random
+fi;
+echo "$as_me:$LINENO: checking /dev/random to use" >&5
+echo $ECHO_N "checking /dev/random to use... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $devrandom" >&5
+echo "${ECHO_T}$devrandom" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SASL_DEV_RANDOM "$devrandom"
+_ACEOF
+
+
+
+for ac_prog in nm
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  ac_cv_prog_NM="$NM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NM="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+NM=$ac_cv_prog_NM
+if test -n "$NM"; then
+  echo "$as_me:$LINENO: result: $NM" >&5
+echo "${ECHO_T}$NM" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$NM" && break
+done
+
+
+echo "$as_me:$LINENO: checking for underscore before symbols" >&5
+echo $ECHO_N "checking for underscore before symbols... $ECHO_C" >&6
+if test "${sasl_cv_uscore+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    echo "main(){int i=1;}
+    foo(){int i=6;}" > conftest.c
+    ${CC} -o a.out conftest.c > /dev/null
+    if (${NM} a.out | grep _foo) > /dev/null; then
+      sasl_cv_uscore=yes
+    else
+      sasl_cv_uscore=no
+    fi
+fi
+
+echo "$as_me:$LINENO: result: $sasl_cv_uscore" >&5
+echo "${ECHO_T}$sasl_cv_uscore" >&6
+rm -f conftest.c a.out
+
+if test $sasl_cv_uscore = yes; then
+  if test $ac_cv_lib_dl_dlopen = yes ; then
+       echo "$as_me:$LINENO: checking whether dlsym adds the underscore for us" >&5
+echo $ECHO_N "checking whether dlsym adds the underscore for us... $ECHO_C" >&6
+       cmu_save_LIBS="$LIBS"
+       LIBS="$LIBS $SASL_DL_LIB"
+       if test "${sasl_cv_dlsym_adds_uscore+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  { echo "$as_me:$LINENO: WARNING: cross-compiler" >&5
+echo "$as_me: WARNING: cross-compiler" >&2;}
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+foo() { int i=0;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY);
+    if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo");
+    if(ptr1 && !ptr2) exit(0); } exit(1); }
+
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  sasl_cv_dlsym_adds_uscore=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+sasl_cv_dlsym_adds_uscore=no
+
+cat >>confdefs.h <<\_ACEOF
+#define DLSYM_NEEDS_UNDERSCORE
+_ACEOF
+
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+
+       LIBS="$cmu_save_LIBS"
+      echo "$as_me:$LINENO: result: $sasl_cv_dlsym_adds_uscore" >&5
+echo "${ECHO_T}$sasl_cv_dlsym_adds_uscore" >&6
+  fi
+fi
+
+
+for ac_func in syslog
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+# Check whether --with-pam or --without-pam was given.
+if test "${with_pam+set}" = set; then
+  withval="$with_pam"
+  with_pam=$withval
+else
+  with_pam=yes
+fi;
+if test "$with_pam" != no; then
+  if test -d $with_pam; then
+    CPPFLAGS="$CPPFLAGS -I${with_pam}/include"
+    LDFLAGS="$LDFLAGS -L${with_pam}/lib"
+  fi
+
+
+for ac_header in security/pam_appl.h pam/pam_appl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+  cmu_save_LIBS="$LIBS"
+  echo "$as_me:$LINENO: checking for pam_start" >&5
+echo $ECHO_N "checking for pam_start... $ECHO_C" >&6
+if test "${ac_cv_func_pam_start+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char pam_start (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pam_start ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_pam_start) || defined (__stub___pam_start)
+choke me
+#else
+char (*f) () = pam_start;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != pam_start;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_pam_start=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_pam_start=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_pam_start" >&5
+echo "${ECHO_T}$ac_cv_func_pam_start" >&6
+if test $ac_cv_func_pam_start = yes; then
+  :
+else
+  LIBS="-lpam $LIBS"
+       cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#ifdef HAVE_PAM_PAM_APPL_H
+#include <pam/pam_appl.h>
+#endif
+#ifdef HAVE_SECURITY_PAM_H
+#include <security/pam_appl.h>
+#endif
+int
+main ()
+{
+
+const char *service="foo";
+const char *user="bar";
+pam_handle_t *pamh;
+struct pam_conv *conv;
+int baz;
+baz = pam_start(service, user, conv, &pamh);
+return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIBPAM="-lpam"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+  LIBS="$cmu_save_LIBS $LIBPAM"
+fi
+
+
+# Check whether --with-saslauthd or --without-saslauthd was given.
+if test "${with_saslauthd+set}" = set; then
+  withval="$with_saslauthd"
+  with_saslauthd=$withval
+else
+  with_saslauthd=yes
+fi;
+if test "$with_saslauthd" != no; then
+  if test "$with_saslauthd" = yes; then
+    with_saslauthd="/var/state/saslauthd"
+  fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SASLAUTHD
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PATH_SASLAUTHD_RUNDIR "$with_saslauthd"
+_ACEOF
+
+fi
+
+
+if test "$with_saslauthd" != no; then
+  SASLAUTHD_TRUE=
+  SASLAUTHD_FALSE='#'
+else
+  SASLAUTHD_TRUE='#'
+  SASLAUTHD_FALSE=
+fi
+
+echo "$as_me:$LINENO: checking if I should include saslauthd" >&5
+echo $ECHO_N "checking if I should include saslauthd... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_saslauthd" >&5
+echo "${ECHO_T}$with_saslauthd" >&6
+
+
+# Check whether --with-authdaemond or --without-authdaemond was given.
+if test "${with_authdaemond+set}" = set; then
+  withval="$with_authdaemond"
+  with_authdaemon=$withval
+else
+  with_authdaemon=yes
+fi;
+if test "$with_authdaemon" != no; then
+  if test "$with_authdaemon" = yes; then
+    with_authdaemon="/dev/null"
+  fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_AUTHDAEMON
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PATH_AUTHDAEMON_SOCKET "$with_authdaemon"
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: checking to include Courier authdaemond support" >&5
+echo $ECHO_N "checking to include Courier authdaemond support... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_authdaemon" >&5
+echo "${ECHO_T}$with_authdaemon" >&6
+
+
+# Check whether --with-pwcheck or --without-pwcheck was given.
+if test "${with_pwcheck+set}" = set; then
+  withval="$with_pwcheck"
+  with_pwcheck=$withval
+else
+  with_pwcheck=no
+fi;
+if test "$with_pwcheck" != no; then
+   if test "$with_pwcheck" = yes; then
+     with_pwcheck=/var/pwcheck
+   fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PWCHECK
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PWCHECKDIR "$with_pwcheck"
+_ACEOF
+
+   echo "$as_me:$LINENO: checking for getspnam" >&5
+echo $ECHO_N "checking for getspnam... $ECHO_C" >&6
+if test "${ac_cv_func_getspnam+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getspnam (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getspnam ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getspnam) || defined (__stub___getspnam)
+choke me
+#else
+char (*f) () = getspnam;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getspnam;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getspnam=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getspnam=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getspnam" >&5
+echo "${ECHO_T}$ac_cv_func_getspnam" >&6
+if test $ac_cv_func_getspnam = yes; then
+  PWCHECKMETH="getspnam"
+else
+  PWCHECKMETH="getpwnam"
+fi
+
+
+fi
+
+
+if test "$with_pwcheck" != no; then
+  PWCHECK_TRUE=
+  PWCHECK_FALSE='#'
+else
+  PWCHECK_TRUE='#'
+  PWCHECK_FALSE=
+fi
+
+echo "$as_me:$LINENO: checking if I should include pwcheck" >&5
+echo $ECHO_N "checking if I should include pwcheck... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_pwcheck" >&5
+echo "${ECHO_T}$with_pwcheck" >&6
+
+
+# Check whether --with-ipctype or --without-ipctype was given.
+if test "${with_ipctype+set}" = set; then
+  withval="$with_ipctype"
+  with_ipctype=$withval
+else
+  with_ipctype="unix"
+fi;
+IPCTYPE=$with_ipctype
+
+LIB_DOOR=
+if test "$with_ipctype" = "doors"; then
+   LIB_DOOR="-ldoor"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DOORS
+_ACEOF
+
+fi
+
+
+# Check whether --enable-alwaystrue or --disable-alwaystrue was given.
+if test "${enable_alwaystrue+set}" = set; then
+  enableval="$enable_alwaystrue"
+  enable_alwaystrue=$enableval
+else
+  enable_alwaystrue=no
+fi;
+if test "$enable_alwaystrue" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ALWAYSTRUE
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: checking if I should include the alwaystrue verifier" >&5
+echo $ECHO_N "checking if I should include the alwaystrue verifier... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $enable_alwaystrue" >&5
+echo "${ECHO_T}$enable_alwaystrue" >&6
+
+# Check whether --enable-checkapop or --disable-checkapop was given.
+if test "${enable_checkapop+set}" = set; then
+  enableval="$enable_checkapop"
+  checkapop=$enableval
+else
+  checkapop=yes
+fi;
+
+echo "$as_me:$LINENO: checking if we should enable sasl_checkapop" >&5
+echo $ECHO_N "checking if we should enable sasl_checkapop... $ECHO_C" >&6
+if test "$checkapop" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define DO_SASL_CHECKAPOP
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-cram or --disable-cram was given.
+if test "${enable_cram+set}" = set; then
+  enableval="$enable_cram"
+  cram=$enableval
+else
+  cram=yes
+fi;
+
+echo "$as_me:$LINENO: checking CRAM-MD5" >&5
+echo $ECHO_N "checking CRAM-MD5... $ECHO_C" >&6
+if test "$cram" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS libcrammd5.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS cram.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/cram.c"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_CRAMMD5
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+# Check whether --with-lib-subdir or --without-lib-subdir was given.
+if test "${with_lib_subdir+set}" = set; then
+  withval="$with_lib_subdir"
+
+fi;
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                    if test $ac_lo -le $ac_mid; then
+                      ac_lo= ac_hi=
+                      break
+                    fi
+                    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                       if test $ac_mid -le $ac_hi; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking what directory libraries are found in" >&5
+echo $ECHO_N "checking what directory libraries are found in... $ECHO_C" >&6
+if test "${ac_cv_cmu_lib_subdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  test "X$with_lib_subdir" = "Xyes" && with_lib_subdir=
+test "X$with_lib_subdir" = "Xno" && with_lib_subdir=
+if test "X$with_lib_subdir" = "X" ; then
+  ac_cv_cmu_lib_subdir=lib
+  if test $ac_cv_sizeof_long -eq 4 ; then
+    test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32
+  fi
+  if test $ac_cv_sizeof_long -eq 8 ; then
+    test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64
+  fi
+else
+  ac_cv_cmu_lib_subdir=$with_lib_subdir
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cmu_lib_subdir" >&5
+echo "${ECHO_T}$ac_cv_cmu_lib_subdir" >&6
+CMU_LIB_SUBDIR=$ac_cv_cmu_lib_subdir
+
+
+
+
+
+# Check whether --with-openssl or --without-openssl was given.
+if test "${with_openssl+set}" = set; then
+  withval="$with_openssl"
+  with_openssl=$withval
+else
+  with_openssl="yes"
+fi;
+
+       save_CPPFLAGS=$CPPFLAGS
+       save_LDFLAGS=$LDFLAGS
+
+       if test -d $with_openssl; then
+         CPPFLAGS="${CPPFLAGS} -I${with_openssl}/include"
+
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L${with_openssl}/$CMU_LIB_SUBDIR ${LDFLAGS}"
+  else
+       LDFLAGS="-L${with_openssl}/$CMU_LIB_SUBDIR $andrew_runpath_switch${with_openssl}/$CMU_LIB_SUBDIR ${LDFLAGS}"
+  fi
+
+       fi
+
+case "$with_openssl" in
+       no)
+         with_openssl="no";;
+       *)
+                                 LIB_RSAREF=""
+               echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lrsaref" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lrsaref... $ECHO_C" >&6
+if test "${ac_cv_lib_rsaref_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrsaref  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_rsaref_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rsaref_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rsaref_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_rsaref_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_rsaref_RSAPublicEncrypt = yes; then
+  cmu_have_rsaref=yes;
+                       echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lRSAglue" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lRSAglue... $ECHO_C" >&6
+if test "${ac_cv_lib_RSAglue_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lRSAglue  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_RSAglue_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_RSAglue_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_RSAglue_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_RSAglue_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_RSAglue_RSAPublicEncrypt = yes; then
+  LIB_RSAREF="-lRSAglue -lrsaref"
+else
+  LIB_RSAREF="-lrsaref"
+fi
+
+else
+  cmu_have_rsaref=no
+fi
+
+
+               if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/evp.h usability" >&5
+echo $ECHO_N "checking openssl/evp.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/evp.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/evp.h presence" >&5
+echo $ECHO_N "checking openssl/evp.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/evp.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/evp.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_evp_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+
+fi
+if test $ac_cv_header_openssl_evp_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for EVP_DigestInit in -lcrypto" >&5
+echo $ECHO_N "checking for EVP_DigestInit in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_EVP_DigestInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char EVP_DigestInit ();
+int
+main ()
+{
+EVP_DigestInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_EVP_DigestInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_EVP_DigestInit=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_EVP_DigestInit" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_EVP_DigestInit" >&6
+if test $ac_cv_lib_crypto_EVP_DigestInit = yes; then
+  with_openssl="yes"
+else
+  with_openssl="no"
+fi
+
+else
+  with_openssl=no
+fi
+
+
+               ;;
+esac
+
+       if test "$with_openssl" != "no"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_OPENSSL
+_ACEOF
+
+       else
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+       fi
+
+echo "$as_me:$LINENO: checking for OpenSSL" >&5
+echo $ECHO_N "checking for OpenSSL... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_openssl" >&5
+echo "${ECHO_T}$with_openssl" >&6
+
+
+
+# Check whether --with-des or --without-des was given.
+if test "${with_des+set}" = set; then
+  withval="$with_des"
+  with_des=$withval
+else
+  with_des=yes
+fi;
+
+LIB_DES=""
+if test "$with_des" != no; then
+  if test -d $with_des; then
+    CPPFLAGS="$CPPFLAGS -I${with_des}/include"
+    LDFLAGS="$LDFLAGS -L${with_des}/lib"
+  fi
+
+  if test "$with_openssl" != no; then
+        echo "$as_me:$LINENO: checking for des_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_des_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_des_cbc_encrypt = yes; then
+
+        if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+
+        if test "$with_des" = no; then
+      echo "$as_me:$LINENO: checking for DES_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for DES_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_DES_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char DES_cbc_encrypt ();
+int
+main ()
+{
+DES_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_DES_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_DES_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_DES_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_DES_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_DES_cbc_encrypt = yes; then
+
+        if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+    fi
+  fi
+
+  if test "$with_des" = no; then
+    echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes... $ECHO_C" >&6
+if test "${ac_cv_lib_des_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes";
+                                        with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+     echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes425" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes425... $ECHO_C" >&6
+if test "${ac_cv_lib_des425_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes425  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des425_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des425_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des425_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des425_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des425_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes425";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+     echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes524" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes524... $ECHO_C" >&6
+if test "${ac_cv_lib_des524_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes524  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des524_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des524_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des524_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des524_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des524_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes524";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+
+            LIB_RSAREF=""
+    echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lrsaref" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lrsaref... $ECHO_C" >&6
+if test "${ac_cv_lib_rsaref_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrsaref  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_rsaref_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rsaref_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rsaref_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_rsaref_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_rsaref_RSAPublicEncrypt = yes; then
+  LIB_RSAREF="-lRSAglue -lrsaref"; cmu_have_rsaref=yes
+else
+  cmu_have_rsaref=no
+fi
+
+
+    echo "$as_me:$LINENO: checking for des_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_des_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_des_cbc_encrypt = yes; then
+
+       if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+  fi
+fi
+
+if test "$with_des" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_DES
+_ACEOF
+
+fi
+
+
+
+
+# Check whether --enable-digest or --disable-digest was given.
+if test "${enable_digest+set}" = set; then
+  enableval="$enable_digest"
+  digest=$enableval
+else
+  digest=yes
+fi;
+
+if test "$digest" != no; then
+    if test -d $digest; then
+    CPPFLAGS="$CPPFLAGS -I$digest/include"
+    LDFLAGS="$LDFLAGS -L$digest/lib"
+  fi
+  if test "$with_des" = no; then
+    { echo "$as_me:$LINENO: WARNING: No DES support for DIGEST-MD5" >&5
+echo "$as_me: WARNING: No DES support for DIGEST-MD5" >&2;}
+  fi
+fi
+
+echo "$as_me:$LINENO: checking DIGEST-MD5" >&5
+echo $ECHO_N "checking DIGEST-MD5... $ECHO_C" >&6
+if test "$digest" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS libdigestmd5.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/digestmd5.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS digestmd5.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_DIGESTMD5
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-otp or --disable-otp was given.
+if test "${enable_otp+set}" = set; then
+  enableval="$enable_otp"
+  otp=$enableval
+else
+  otp=yes
+fi;
+
+if test "$with_openssl" = no; then
+  { echo "$as_me:$LINENO: WARNING: OpenSSL not found -- OTP will be disabled" >&5
+echo "$as_me: WARNING: OpenSSL not found -- OTP will be disabled" >&2;}
+  otp=no
+fi
+
+echo "$as_me:$LINENO: checking OTP" >&5
+echo $ECHO_N "checking OTP... $ECHO_C" >&6
+if test "$otp" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  OTP_LIBS="-lcrypto $LIB_RSAREF"
+
+  SASL_MECHS="$SASL_MECHS libotp.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/otp.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS otp.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_OTP
+_ACEOF
+
+  fi
+
+
+# Check whether --with-with-opie or --without-with-opie was given.
+if test "${with_with_opie+set}" = set; then
+  withval="$with_with_opie"
+  with_opie="${withval}"
+fi;
+
+  case "$with_opie" in
+       ""|yes)
+               echo "$as_me:$LINENO: checking for opiechallenge in -lopie" >&5
+echo $ECHO_N "checking for opiechallenge in -lopie... $ECHO_C" >&6
+if test "${ac_cv_lib_opie_opiechallenge+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lopie  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opiechallenge ();
+int
+main ()
+{
+opiechallenge ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_opie_opiechallenge=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_opie_opiechallenge=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_opie_opiechallenge" >&5
+echo "${ECHO_T}$ac_cv_lib_opie_opiechallenge" >&6
+if test $ac_cv_lib_opie_opiechallenge = yes; then
+
+                       if test "${ac_cv_header_opie_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for opie.h" >&5
+echo $ECHO_N "checking for opie.h... $ECHO_C" >&6
+if test "${ac_cv_header_opie_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_opie_h" >&5
+echo "${ECHO_T}$ac_cv_header_opie_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking opie.h usability" >&5
+echo $ECHO_N "checking opie.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <opie.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking opie.h presence" >&5
+echo $ECHO_N "checking opie.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <opie.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: opie.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: opie.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: opie.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: opie.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: opie.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: opie.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: opie.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: opie.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: opie.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: opie.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for opie.h" >&5
+echo $ECHO_N "checking for opie.h... $ECHO_C" >&6
+if test "${ac_cv_header_opie_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_opie_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_opie_h" >&5
+echo "${ECHO_T}$ac_cv_header_opie_h" >&6
+
+fi
+if test $ac_cv_header_opie_h = yes; then
+  with_opie="yes"
+else
+  with_opie="no"
+fi
+
+
+else
+  with_opie="no"
+fi
+
+               ;;
+       *)
+               if test -d $with_opie; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_opie}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_opie}/lib"
+               else
+                 with_opie="no"
+               fi
+               ;;
+  esac
+
+  echo "$as_me:$LINENO: checking for OPIE" >&5
+echo $ECHO_N "checking for OPIE... $ECHO_C" >&6
+  echo "$as_me:$LINENO: result: $with_opie" >&5
+echo "${ECHO_T}$with_opie" >&6
+
+  if test "$with_opie" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_OPIE
+_ACEOF
+
+    OTP_LIBS="$OTP_LIBS -lopie"
+  fi
+
+
+
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-srp or --disable-srp was given.
+if test "${enable_srp+set}" = set; then
+  enableval="$enable_srp"
+  srp=$enableval
+else
+  srp=no
+fi;
+
+if test "$with_openssl" = no; then
+  { echo "$as_me:$LINENO: WARNING: OpenSSL not found -- SRP will be disabled" >&5
+echo "$as_me: WARNING: OpenSSL not found -- SRP will be disabled" >&2;}
+  srp=no
+fi
+
+echo "$as_me:$LINENO: checking SRP" >&5
+echo $ECHO_N "checking SRP... $ECHO_C" >&6
+if test "$srp" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SRP_LIBS="-lcrypto $LIB_RSAREF"
+
+  SASL_MECHS="$SASL_MECHS libsrp.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/srp.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS srp.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_SRP
+_ACEOF
+
+  fi
+
+  # Check whether --enable-srp_setpass or --disable-srp_setpass was given.
+if test "${enable_srp_setpass+set}" = set; then
+  enableval="$enable_srp_setpass"
+  srp_setpass=$enableval
+else
+  srp_setpass=no
+fi;
+
+  echo "$as_me:$LINENO: checking if we should enable setting SRP secrets with saslpasswd" >&5
+echo $ECHO_N "checking if we should enable setting SRP secrets with saslpasswd... $ECHO_C" >&6
+  if test "$srp_setpass" != no; then
+    echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define DO_SRP_SETPASS
+_ACEOF
+
+  else
+    echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+  fi
+
+
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+
+
+  # Check whether --enable-krb4 or --disable-krb4 was given.
+if test "${enable_krb4+set}" = set; then
+  enableval="$enable_krb4"
+  krb4=$enableval
+else
+  krb4=no
+fi;
+
+  if test "$krb4" != no; then
+
+echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+
+            if test -d ${krb4}; then
+       echo "$as_me:$LINENO: checking for Kerberos includes" >&5
+echo $ECHO_N "checking for Kerberos includes... $ECHO_C" >&6
+if test "${cyrus_krbinclude+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+         for krbhloc in include/kerberosIV include/kerberos include
+         do
+           if test -f ${krb4}/${krbhloc}/krb.h ; then
+             cyrus_krbinclude=${krb4}/${krbhloc}
+             break
+           fi
+         done
+
+fi
+echo "$as_me:$LINENO: result: $cyrus_krbinclude" >&5
+echo "${ECHO_T}$cyrus_krbinclude" >&6
+
+       if test -n "${cyrus_krbinclude}"; then
+         CPPFLAGS="$CPPFLAGS -I${cyrus_krbinclude}"
+       fi
+       LDFLAGS="$LDFLAGS -L$krb4/lib"
+    fi
+
+    if test "$with_des" != no; then
+      if test "${ac_cv_header_krb_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for krb.h" >&5
+echo $ECHO_N "checking for krb.h... $ECHO_C" >&6
+if test "${ac_cv_header_krb_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5
+echo "${ECHO_T}$ac_cv_header_krb_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking krb.h usability" >&5
+echo $ECHO_N "checking krb.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <krb.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking krb.h presence" >&5
+echo $ECHO_N "checking krb.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <krb.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: krb.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: krb.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: krb.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for krb.h" >&5
+echo $ECHO_N "checking for krb.h... $ECHO_C" >&6
+if test "${ac_cv_header_krb_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_krb_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5
+echo "${ECHO_T}$ac_cv_header_krb_h" >&6
+
+fi
+if test $ac_cv_header_krb_h = yes; then
+
+        echo "$as_me:$LINENO: checking for com_err in -lcom_err" >&5
+echo $ECHO_N "checking for com_err in -lcom_err... $ECHO_C" >&6
+if test "${ac_cv_lib_com_err_com_err+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char com_err ();
+int
+main ()
+{
+com_err ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_com_err_com_err=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_com_err_com_err=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_com_err_com_err" >&5
+echo "${ECHO_T}$ac_cv_lib_com_err_com_err" >&6
+if test $ac_cv_lib_com_err_com_err = yes; then
+
+         echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb... $ECHO_C" >&6
+if test "${ac_cv_lib_krb_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb $LIB_DES -lcom_err $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb_krb_mk_priv" >&6
+if test $ac_cv_lib_krb_krb_mk_priv = yes; then
+  COM_ERR="-lcom_err"; SASL_KRB_LIB="-lkrb"; krb4lib="yes"
+else
+  krb4lib=no
+fi
+
+else
+
+         echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb... $ECHO_C" >&6
+if test "${ac_cv_lib_krb_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb $LIB_DES $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb_krb_mk_priv" >&6
+if test $ac_cv_lib_krb_krb_mk_priv = yes; then
+  COM_ERR=""; SASL_KRB_LIB="-lkrb"; krb4lib="yes"
+else
+  krb4lib=no
+fi
+
+fi
+
+else
+  krb4="no"
+fi
+
+
+
+      if test "$krb4" != "no" -a "$krb4lib" = "no"; then
+       echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb4" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb4... $ECHO_C" >&6
+if test "${ac_cv_lib_krb4_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb4 $LIB_DES $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb4_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb4_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb4_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb4_krb_mk_priv" >&6
+if test $ac_cv_lib_krb4_krb_mk_priv = yes; then
+  COM_ERR=""; SASL_KRB_LIB="-lkrb4"; krb4=yes
+else
+  krb4=no
+fi
+
+      fi
+      if test "$krb4" = no; then
+          { echo "$as_me:$LINENO: WARNING: No Kerberos V4 found" >&5
+echo "$as_me: WARNING: No Kerberos V4 found" >&2;}
+      fi
+    else
+      { echo "$as_me:$LINENO: WARNING: No DES library found for Kerberos V4 support" >&5
+echo "$as_me: WARNING: No DES library found for Kerberos V4 support" >&2;}
+      krb4=no
+    fi
+  fi
+
+  if test "$krb4" != no; then
+    cmu_save_LIBS="$LIBS"
+    LIBS="$LIBS $SASL_KRB_LIB"
+
+for ac_func in krb_get_err_text
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    LIBS="$cmu_save_LIBS"
+  fi
+
+  echo "$as_me:$LINENO: checking KERBEROS_V4" >&5
+echo $ECHO_N "checking KERBEROS_V4... $ECHO_C" >&6
+  if test "$krb4" != no; then
+    echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+    SASL_MECHS="$SASL_MECHS libkerberos4.la"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/kerberos4.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS kerberos4.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_KERBEROS4
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_KRB
+_ACEOF
+
+    SASL_KRB_LIB="$SASL_KRB_LIB $LIB_DES $COM_ERR"
+  else
+    echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+  fi
+
+
+echo "$as_me:$LINENO: checking for crypt" >&5
+echo $ECHO_N "checking for crypt... $ECHO_C" >&6
+if test "${ac_cv_func_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char crypt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_crypt) || defined (__stub___crypt)
+choke me
+#else
+char (*f) () = crypt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != crypt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5
+echo "${ECHO_T}$ac_cv_func_crypt" >&6
+if test $ac_cv_func_crypt = yes; then
+  cmu_have_crypt=yes
+else
+  echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6
+if test $ac_cv_lib_crypt_crypt = yes; then
+  LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes
+else
+  cmu_have_crypt=no
+fi
+
+fi
+
+
+
+
+
+# Check whether --enable-gssapi or --disable-gssapi was given.
+if test "${enable_gssapi+set}" = set; then
+  enableval="$enable_gssapi"
+  gssapi=$enableval
+else
+  gssapi=yes
+fi;
+
+# Check whether --with-gss_impl or --without-gss_impl was given.
+if test "${with_gss_impl+set}" = set; then
+  withval="$with_gss_impl"
+  gss_impl=$withval
+else
+  gss_impl=auto
+fi;
+
+if test "$gssapi" != no; then
+  platform=
+  case "${host}" in
+    *-*-linux*)
+      platform=__linux
+      ;;
+    *-*-hpux*)
+      platform=__hpux
+      ;;
+    *-*-irix*)
+      platform=__irix
+      ;;
+    *-*-solaris2*)
+# When should we use __sunos?
+      platform=__solaris
+      ;;
+    *-*-aix*)
+      platform=__aix
+      ;;
+    *)
+      { echo "$as_me:$LINENO: WARNING: The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script" >&5
+echo "$as_me: WARNING: The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script" >&2;}
+      if test "$gss_impl" = "cybersafe"; then
+        { { echo "$as_me:$LINENO: error: CyberSafe was forced, cannot continue as platform is not supported" >&5
+echo "$as_me: error: CyberSafe was forced, cannot continue as platform is not supported" >&2;}
+   { (exit 1); exit 1; }; }
+      fi
+      ;;
+  esac
+
+  cmu_saved_CPPFLAGS=$CPPFLAGS
+
+  if test -d ${gssapi}; then
+    CPPFLAGS="$CPPFLAGS -I$gssapi/include"
+# We want to keep -I in our CPPFLAGS, but only if we succeed
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    LDFLAGS="$LDFLAGS -L$gssapi/lib"
+
+    if test -n "$platform"; then
+      if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+        CPPFLAGS="$CPPFLAGS -D$platform"
+        if test -d "${gssapi}/appsec-sdk/include"; then
+          CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+        fi
+      fi
+    fi
+  fi
+  if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gssapi.h" >&5
+echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gssapi.h usability" >&5
+echo $ECHO_N "checking gssapi.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gssapi.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gssapi.h presence" >&5
+echo $ECHO_N "checking gssapi.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gssapi.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gssapi.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gssapi.h" >&5
+echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gssapi_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6
+
+fi
+if test $ac_cv_header_gssapi_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSSAPI_H
+_ACEOF
+
+else
+  if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gssapi/gssapi.h" >&5
+echo $ECHO_N "checking for gssapi/gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_gssapi_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gssapi/gssapi.h usability" >&5
+echo $ECHO_N "checking gssapi/gssapi.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gssapi/gssapi.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gssapi/gssapi.h presence" >&5
+echo $ECHO_N "checking gssapi/gssapi.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gssapi/gssapi.h" >&5
+echo $ECHO_N "checking for gssapi/gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gssapi_gssapi_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_gssapi_h" >&6
+
+fi
+if test $ac_cv_header_gssapi_gssapi_h = yes; then
+  :
+else
+  { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - no include files found" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - no include files found" >&2;}; gssapi=no
+fi
+
+
+fi
+
+
+
+  CPPFLAGS=$cmu_saved_CPPFLAGS
+
+fi
+
+if test "$gssapi" != no; then
+  # We need to find out which gssapi implementation we are
+  # using. Supported alternatives are: MIT Kerberos 5,
+  # Heimdal Kerberos 5 (http://www.pdc.kth.se/heimdal),
+  # CyberSafe Kerberos 5 (http://www.cybersafe.com/)
+  # and Sun SEAM (http://wwws.sun.com/software/security/kerberos/)
+  #
+  # The choice is reflected in GSSAPIBASE_LIBS
+
+
+echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+  if test -d ${gssapi}; then
+     gssapi_dir="${gssapi}/lib"
+     GSSAPIBASE_LIBS="-L$gssapi_dir"
+     GSSAPIBASE_STATIC_LIBS="-L$gssapi_dir"
+  else
+     # FIXME: This is only used for building cyrus, and then only as
+     # a real hack.  it needs to be fixed.
+     gssapi_dir="/usr/local/lib"
+  fi
+
+  # Check a full link against the Heimdal libraries.
+  # If this fails, check a full link against the MIT libraries.
+  # If this fails, check a full link against the CyberSafe libraries.
+  # If this fails, check a full link against the Solaris 8 and up libgss.
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "heimdal"; then
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgssapi" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgssapi... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi ${GSSAPIBASE_LIBS} -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gssapi_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gssapi_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_gss_unwrap" >&6
+if test $ac_cv_lib_gssapi_gss_unwrap = yes; then
+  gss_impl="heimdal"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "mit"; then
+    # check for libkrb5support first
+    echo "$as_me:$LINENO: checking for krb5int_getspecific in -lkrb5support" >&5
+echo $ECHO_N "checking for krb5int_getspecific in -lkrb5support... $ECHO_C" >&6
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb5int_getspecific ();
+int
+main ()
+{
+krb5int_getspecific ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb5support_krb5int_getspecific=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb5support_krb5int_getspecific" >&5
+echo "${ECHO_T}$ac_cv_lib_krb5support_krb5int_getspecific" >&6
+if test $ac_cv_lib_krb5support_krb5int_getspecific = yes; then
+  K5SUP=-lkrb5support K5SUPSTATIC=$gssapi_dir/libkrb5support.a
+fi
+
+
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgssapi_krb5" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgssapi_krb5... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_krb5_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 ${GSSAPIBASE_LIBS} -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP} ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gssapi_krb5_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gssapi_krb5_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_unwrap" >&6
+if test $ac_cv_lib_gssapi_krb5_gss_unwrap = yes; then
+  gss_impl="mit"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  # For Cybersafe one has to set a platform define in order to make compilation work
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    cmu_saved_GSSAPIBASE_LIBS=$GSSAPIBASE_LIBS
+# FIXME - Note that the libraries are in .../lib64 for 64bit kernels
+    if test -d "${gssapi}/appsec-rt/lib"; then
+      GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -L${gssapi}/appsec-rt/lib"
+    fi
+    CPPFLAGS="$CPPFLAGS -D$platform"
+    if test -d "${gssapi}/appsec-sdk/include"; then
+      CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+    fi
+
+    gss_failed=0
+
+# Check for CyberSafe with two libraries first, than fall back to a single
+# library (older CyberSafe)
+
+    unset ac_cv_lib_gss_csf_gss_acq_user
+    echo "$as_me:$LINENO: checking for csf_gss_acq_user in -lgss" >&5
+echo $ECHO_N "checking for csf_gss_acq_user in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_csf_gss_acq_user+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss ${GSSAPIBASE_LIBS} -lgss -lcstbk5 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char csf_gss_acq_user ();
+int
+main ()
+{
+csf_gss_acq_user ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_csf_gss_acq_user=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_csf_gss_acq_user=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_csf_gss_acq_user" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_csf_gss_acq_user" >&6
+if test $ac_cv_lib_gss_csf_gss_acq_user = yes; then
+  gss_impl="cybersafe03"
+else
+  unset ac_cv_lib_gss_csf_gss_acq_user;
+                  echo "$as_me:$LINENO: checking for csf_gss_acq_user in -lgss" >&5
+echo $ECHO_N "checking for csf_gss_acq_user in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_csf_gss_acq_user+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss $GSSAPIBASE_LIBS -lgss $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char csf_gss_acq_user ();
+int
+main ()
+{
+csf_gss_acq_user ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_csf_gss_acq_user=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_csf_gss_acq_user=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_csf_gss_acq_user" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_csf_gss_acq_user" >&6
+if test $ac_cv_lib_gss_csf_gss_acq_user = yes; then
+  gss_impl="cybersafe"
+else
+  gss_failed=1
+fi
+
+fi
+
+
+    if test "$gss_failed" = "1"; then
+# Restore variables
+      GSSAPIBASE_LIBS=$cmu_saved_GSSAPIBASE_LIBS
+      CPPFLAGS=$cmu_saved_CPPFLAGS
+
+      if test "$gss_impl" != "auto"; then
+        gss_impl="failed"
+      fi
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "seam"; then
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgss" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss -lgss $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_gss_unwrap" >&6
+if test $ac_cv_lib_gss_gss_unwrap = yes; then
+  gss_impl="seam"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "mit"; then
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}"
+  elif test "$gss_impl" = "heimdal"; then
+    CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}"
+  elif test "$gss_impl" = "cybersafe03"; then
+# Version of CyberSafe with two libraries
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss -lcstbk5"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "cybersafe"; then
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "seam"; then
+    GSSAPIBASE_LIBS=-lgss
+    # there is no static libgss on Solaris 8 and up
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "failed"; then
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - specified library not found" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - specified library not found" >&2;}
+  else
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - no library" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - no library" >&2;}
+  fi
+fi
+
+#
+# Cybersafe defines both GSS_C_NT_HOSTBASED_SERVICE and GSS_C_NT_USER_NAME
+# in gssapi\rfckrb5.h
+#
+if test "$gssapi" != "no"; then
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_HOSTBASED_SERVICE
+                    hostbased_service_gss_nt_yes
+                  #endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "hostbased_service_gss_nt_yes" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: Cybersafe define not found" >&5
+echo "$as_me: WARNING: Cybersafe define not found" >&2;}
+fi
+rm -f conftest*
+
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+fi
+rm -f conftest*
+
+  fi
+
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_USER_NAME
+                   user_name_yes_gss_nt
+                  #endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "user_name_yes_gss_nt" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: Cybersafe define not found" >&5
+echo "$as_me: WARNING: Cybersafe define not found" >&2;}
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_USER_NAME" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_USER_NAME" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+fi
+rm -f conftest*
+
+  fi
+fi
+
+GSSAPI_LIBS=""
+echo "$as_me:$LINENO: checking GSSAPI" >&5
+echo $ECHO_N "checking GSSAPI... $ECHO_C" >&6
+if test "$gssapi" != no; then
+  echo "$as_me:$LINENO: result: with implementation ${gss_impl}" >&5
+echo "${ECHO_T}with implementation ${gss_impl}" >&6
+  echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lresolv"
+fi
+
+  SASL_MECHS="$SASL_MECHS libgssapiv2.la"
+  SASL_STATIC_OBJS="$SASL_STATIC_OBJS gssapi.o"
+  SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/gssapi.c"
+
+  cmu_save_LIBS="$LIBS"
+  LIBS="$LIBS $GSSAPIBASE_LIBS"
+
+for ac_func in gsskrb5_register_acceptor_identity
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+  LIBS="$cmu_save_LIBS"
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+
+
+if test "$gssapi" != "no"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_GSSAPIV2
+_ACEOF
+
+  mutex_default="no"
+  if test "$gss_impl" = "mit"; then
+     mutex_default="yes"
+  fi
+  echo "$as_me:$LINENO: checking to use mutexes aroung GSS calls" >&5
+echo $ECHO_N "checking to use mutexes aroung GSS calls... $ECHO_C" >&6
+  # Check whether --enable-gss_mutexes or --disable-gss_mutexes was given.
+if test "${enable_gss_mutexes+set}" = set; then
+  enableval="$enable_gss_mutexes"
+  use_gss_mutexes=$enableval
+else
+  use_gss_mutexes=$mutex_default
+fi;
+  if test $use_gss_mutexes = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define GSS_USE_MUTEXES
+_ACEOF
+
+  fi
+  echo "$as_me:$LINENO: result: $use_gss_mutexes" >&5
+echo "${ECHO_T}$use_gss_mutexes" >&6
+fi
+
+
+
+
+ # Check whether --enable-plain or --disable-plain was given.
+if test "${enable_plain+set}" = set; then
+  enableval="$enable_plain"
+  plain=$enableval
+else
+  plain=yes
+fi;
+
+ PLAIN_LIBS=""
+ if test "$plain" != no; then
+    if test "$cmu_have_crypt" = yes; then
+    PLAIN_LIBS=$LIB_CRYPT
+  fi
+ fi
+
+
+ echo "$as_me:$LINENO: checking PLAIN" >&5
+echo $ECHO_N "checking PLAIN... $ECHO_C" >&6
+ if test "$plain" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS libplain.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS plain.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/plain.c"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_PLAIN
+_ACEOF
+
+  fi
+ else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+ fi
+
+
+# Check whether --enable-anon or --disable-anon was given.
+if test "${enable_anon+set}" = set; then
+  enableval="$enable_anon"
+  anon=$enableval
+else
+  anon=yes
+fi;
+
+echo "$as_me:$LINENO: checking ANONYMOUS" >&5
+echo $ECHO_N "checking ANONYMOUS... $ECHO_C" >&6
+if test "$anon" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS libanonymous.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS anonymous.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/anonymous.c"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_ANONYMOUS
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-login or --disable-login was given.
+if test "${enable_login+set}" = set; then
+  enableval="$enable_login"
+  login=$enableval
+else
+  login=no
+fi;
+
+echo "$as_me:$LINENO: checking LOGIN" >&5
+echo $ECHO_N "checking LOGIN... $ECHO_C" >&6
+if test "$login" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS liblogin.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/login.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS login.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_LOGIN
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-ntlm or --disable-ntlm was given.
+if test "${enable_ntlm+set}" = set; then
+  enableval="$enable_ntlm"
+  ntlm=$enableval
+else
+  ntlm=no
+fi;
+
+if test "$with_openssl" = no; then
+  { echo "$as_me:$LINENO: WARNING: OpenSSL not found -- NTLM will be disabled" >&5
+echo "$as_me: WARNING: OpenSSL not found -- NTLM will be disabled" >&2;}
+  ntlm=no
+fi
+
+echo "$as_me:$LINENO: checking NTLM" >&5
+echo $ECHO_N "checking NTLM... $ECHO_C" >&6
+if test "$ntlm" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  NTLM_LIBS="-lcrypto $LIB_RSAREF"
+
+
+  SASL_MECHS="$SASL_MECHS libntlm.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/ntlm.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS ntlm.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_NTLM
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+# Check whether --enable-passdss or --disable-passdss was given.
+if test "${enable_passdss+set}" = set; then
+  enableval="$enable_passdss"
+  passdss=$enableval
+else
+  passdss=no
+fi;
+
+if test "$with_openssl" = no; then
+  { echo "$as_me:$LINENO: WARNING: OpenSSL not found -- PASSDSS will be disabled" >&5
+echo "$as_me: WARNING: OpenSSL not found -- PASSDSS will be disabled" >&2;}
+  passdss=no
+fi
+
+echo "$as_me:$LINENO: checking PASSDSS" >&5
+echo $ECHO_N "checking PASSDSS... $ECHO_C" >&6
+if test "$passdss" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  PASSDSS_LIBS="-lcrypto $LIB_RSAREF"
+
+
+  SASL_MECHS="$SASL_MECHS libpassdss.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS passdss.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/passdss.c"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_PASSDSS
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+# make the option show up so people don't whine that it is only in the
+# saslauthd configure script --help
+
+# Check whether --with-ldap or --without-ldap was given.
+if test "${with_ldap+set}" = set; then
+  withval="$with_ldap"
+
+else
+  with_ldap=no
+fi;
+
+
+
+# Check whether --enable-sql or --disable-sql was given.
+if test "${enable_sql+set}" = set; then
+  enableval="$enable_sql"
+  sql=$enableval
+else
+  sql=no
+fi;
+
+echo "$as_me:$LINENO: checking SQL" >&5
+echo $ECHO_N "checking SQL... $ECHO_C" >&6
+if test "$sql" != no; then
+  echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+  SASL_MECHS="$SASL_MECHS libsql.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sql.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS sql.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_SQL
+_ACEOF
+
+  fi
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+# Check whether --with-mysql or --without-mysql was given.
+if test "${with_mysql+set}" = set; then
+  withval="$with_mysql"
+  with_mysql=$withval
+else
+  with_mysql=$sql
+fi;
+
+# find location of library
+# presuming if one given then correct
+if test "${with_mysql}" = "yes"; then
+  with_mysql=notfound
+  for mysqlloc in lib/mysql lib mysql/lib
+  do
+    if test -f ${prefix}/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="${prefix}"
+      break
+    elif test -f /usr/local/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="/usr/local"
+      break
+    elif test -f /usr/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_MYSQL=""
+
+case "$with_mysql" in
+    no) true;;
+    notfound) { echo "$as_me:$LINENO: WARNING: MySQL Library not found" >&5
+echo "$as_me: WARNING: MySQL Library not found" >&2;}; true;;
+    *)
+     if test -d ${with_mysql}/lib/mysql; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_MYSQL="-L${with_mysql}/lib/mysql ${LIB_MYSQL}"
+  else
+       LIB_MYSQL="-L${with_mysql}/lib/mysql ${LIB_MYSQL} $andrew_runpath_switch${with_mysql}/lib/mysql"
+  fi
+
+     elif test -d ${with_mysql}/mysql/lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_MYSQL="-L${with_mysql}/mysql/lib ${LIB_MYSQL}"
+  else
+       LIB_MYSQL="-L${with_mysql}/mysql/lib ${LIB_MYSQL} $andrew_runpath_switch${with_mysql}/mysql/lib"
+  fi
+
+     elif test -d ${with_mysql}/lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_MYSQL="-L${with_mysql}/lib ${LIB_MYSQL}"
+  else
+       LIB_MYSQL="-L${with_mysql}/lib ${LIB_MYSQL} $andrew_runpath_switch${with_mysql}/lib"
+  fi
+
+     else
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_MYSQL="-L${with_mysql} ${LIB_MYSQL}"
+  else
+       LIB_MYSQL="-L${with_mysql} ${LIB_MYSQL} $andrew_runpath_switch${with_mysql}"
+  fi
+
+     fi
+
+     LIB_MYSQL_DIR=$LIB_MYSQL
+     LIB_MYSQL="$LIB_MYSQL -lmysqlclient"
+
+     if test -d ${with_mysql}/include/mysql; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/include/mysql"
+     elif test -d ${with_mysql}/mysql/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/mysql/include"
+     elif test -d ${with_mysql}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}"
+     fi
+
+       save_LDFLAGS=$LDFLAGS
+       LDFLAGS="$LDFLAGS $LIB_MYSQL_DIR"
+       echo "$as_me:$LINENO: checking for mysql_select_db in -lmysqlclient" >&5
+echo $ECHO_N "checking for mysql_select_db in -lmysqlclient... $ECHO_C" >&6
+if test "${ac_cv_lib_mysqlclient_mysql_select_db+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmysqlclient  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char mysql_select_db ();
+int
+main ()
+{
+mysql_select_db ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_mysqlclient_mysql_select_db=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_mysqlclient_mysql_select_db=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_mysqlclient_mysql_select_db" >&5
+echo "${ECHO_T}$ac_cv_lib_mysqlclient_mysql_select_db" >&6
+if test $ac_cv_lib_mysqlclient_mysql_select_db = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MYSQL
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: MySQL library mysqlclient does not work" >&5
+echo "$as_me: WARNING: MySQL library mysqlclient does not work" >&2;}
+           with_mysql=no
+fi
+
+       LDFLAGS=$save_LDFLAGS;;
+
+esac
+
+
+
+# Check whether --with-pgsql or --without-pgsql was given.
+if test "${with_pgsql+set}" = set; then
+  withval="$with_pgsql"
+  with_pgsql=$withval
+else
+  with_pgsql=$sql
+fi;
+
+# find location of library
+# presuing if one given then correct
+if test "${with_pgsql}" = "yes"; then
+  with_pgsql=notfound
+  for pgsqlloc in lib/pgsql lib pgsql/lib
+  do
+    if test -f ${prefix}/${pgsqlloc}/libpq.a; then
+      with_pgsql="${prefix}"
+      break
+    elif test -f /usr/local/${pgsqlloc}/libpq.a; then
+      with_pgsql="/usr/local"
+      break
+    elif test -f /usr/${pgsqlloc}/libpq.a; then
+      with_pgsql="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_PGSQL=""
+
+case "$with_pgsql" in
+    no) true;;
+    notfound) { echo "$as_me:$LINENO: WARNING: PostgreSQL Library not found" >&5
+echo "$as_me: WARNING: PostgreSQL Library not found" >&2;}; true;;
+    *)
+     if test -d ${with_pgsql}/lib/pgsql; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_PGSQL="-L${with_pgsql}/lib/pgsql ${LIB_PGSQL}"
+  else
+       LIB_PGSQL="-L${with_pgsql}/lib/pgsql ${LIB_PGSQL} $andrew_runpath_switch${with_pgsql}/lib/pgsql"
+  fi
+
+     elif test -d ${with_pgsql}/pgsql/lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_PGSQL="-L${with_pgsql}/pgsql/lib ${LIB_PGSQL}"
+  else
+       LIB_PGSQL="-L${with_pgsql}/pgsql/lib ${LIB_PGSQL} $andrew_runpath_switch${with_pgsql}/pgsql/lib"
+  fi
+
+     elif test -d ${with_pgsql}/lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_PGSQL="-L${with_pgsql}/lib ${LIB_PGSQL}"
+  else
+       LIB_PGSQL="-L${with_pgsql}/lib ${LIB_PGSQL} $andrew_runpath_switch${with_pgsql}/lib"
+  fi
+
+     else
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LIB_PGSQL="-L${with_pgsql} ${LIB_PGSQL}"
+  else
+       LIB_PGSQL="-L${with_pgsql} ${LIB_PGSQL} $andrew_runpath_switch${with_pgsql}"
+  fi
+
+     fi
+
+     LIB_PGSQL_DIR=$LIB_PGSQL
+     LIB_PGSQL="$LIB_PGSQL -lpq"
+
+     if test -d ${with_pgsql}/include/pgsql; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/include/pgsql"
+     elif test -d ${with_pgsql}/pgsql/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/pgsql/include"
+     elif test -d ${with_pgsql}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}"
+     fi
+
+
+       save_LDFLAGS=$LDFLAGS
+       LDFLAGS="$LDFLAGS $LIB_PGSQL_DIR"
+       echo "$as_me:$LINENO: checking for PQsetdbLogin in -lpq" >&5
+echo $ECHO_N "checking for PQsetdbLogin in -lpq... $ECHO_C" >&6
+if test "${ac_cv_lib_pq_PQsetdbLogin+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpq  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char PQsetdbLogin ();
+int
+main ()
+{
+PQsetdbLogin ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pq_PQsetdbLogin=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pq_PQsetdbLogin=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pq_PQsetdbLogin" >&5
+echo "${ECHO_T}$ac_cv_lib_pq_PQsetdbLogin" >&6
+if test $ac_cv_lib_pq_PQsetdbLogin = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PGSQL
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: PostgreSQL Library pq does not work" >&5
+echo "$as_me: WARNING: PostgreSQL Library pq does not work" >&2;}
+           with_pgsql=no
+fi
+
+       LDFLAGS=$save_LDFLAGS;;
+
+esac
+
+
+
+# Check whether --with-sqlite or --without-sqlite was given.
+if test "${with_sqlite+set}" = set; then
+  withval="$with_sqlite"
+  with_sqlite=$withval
+else
+  with_sqlite=$sql
+fi;
+
+# find location of library
+# presuing if one given then correct
+if test "${with_sqlite}" = "yes"; then
+  with_sqlite=notfound
+  for sqliteloc in lib
+  do
+    if test -f ${prefix}/${sqliteloc}/libsqlite.a; then
+      with_sqlite="${prefix}"
+      break
+    elif test -f /usr/local/${sqliteloc}/libsqlite.a; then
+      with_sqlite="/usr/local"
+      break
+    elif test -f /usr/${sqliteloc}/libsqlite.a; then
+      with_sqlite="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_SQLITE=""
+
+case "$with_sqlite" in
+    no) true;;
+    notfound) { echo "$as_me:$LINENO: WARNING: SQLite Library not found" >&5
+echo "$as_me: WARNING: SQLite Library not found" >&2;}; true;;
+    *)
+     if test -d ${with_sqlite}/lib; then
+         LIB_SQLITE="-L${with_sqlite}/lib -R${with_sqlite}/lib"
+     else
+         LIB_SQLITE="-L${with_sqlite} -R${with_sqlite}"
+     fi
+
+     LIB_SQLITE_DIR=$LIB_SQLITE
+     LIB_SQLITE="$LIB_SQLITE -lsqlite"
+
+     if test -d ${with_sqlite}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_sqlite}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_sqlite}"
+     fi
+       echo "$as_me:$LINENO: checking for sqlite_open in -lsqlite" >&5
+echo $ECHO_N "checking for sqlite_open in -lsqlite... $ECHO_C" >&6
+if test "${ac_cv_lib_sqlite_sqlite_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsqlite $LIB_SQLITE_DIR $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char sqlite_open ();
+int
+main ()
+{
+sqlite_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_sqlite_sqlite_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_sqlite_sqlite_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_sqlite_sqlite_open" >&5
+echo "${ECHO_T}$ac_cv_lib_sqlite_sqlite_open" >&6
+if test $ac_cv_lib_sqlite_sqlite_open = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SQLITE
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: SQLite Library sqlite does not work" >&5
+echo "$as_me: WARNING: SQLite Library sqlite does not work" >&2;}
+           with_sqlite=no
+fi
+;;
+
+esac
+
+
+if test "$sql" = yes -a "$with_pgsql" = no -a "$with_mysql" = no -a "$with_sqlite" = no; then
+    { { echo "$as_me:$LINENO: error: --enable-sql chosen but neither Postgres nor MySQL nor SQLite found" >&5
+echo "$as_me: error: --enable-sql chosen but neither Postgres nor MySQL nor SQLite found" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+if test "$enable_shared" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define DO_DLOPEN
+_ACEOF
+
+fi
+
+# Check whether --enable-ldapdb or --disable-ldapdb was given.
+if test "${enable_ldapdb+set}" = set; then
+  enableval="$enable_ldapdb"
+  ldapdb=$enableval
+else
+  ldapdb=no
+fi;
+echo "$as_me:$LINENO: checking LDAPDB" >&5
+echo $ECHO_N "checking LDAPDB... $ECHO_C" >&6
+if test "$ldapdb" != no; then
+    echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+
+    if test "$with_ldap" = no; then
+        { { echo "$as_me:$LINENO: error: Cannot enable LDAPDB plugin: You need to specify --with-ldap" >&5
+echo "$as_me: error: Cannot enable LDAPDB plugin: You need to specify --with-ldap" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    save_CPPFLAGS=$CPPFLAGS
+    save_LDFLAGS=$LDFLAGS
+
+    if test -d $with_ldap; then
+        CPPFLAGS="${CPPFLAGS} -I${with_ldap}/include"
+
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L${with_ldap}/lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L${with_ldap}/lib $andrew_runpath_switch${with_ldap}/lib ${LDFLAGS}"
+  fi
+
+    fi
+
+
+
+for ac_header in ldap.h lber.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+    if test $ac_cv_header_ldap_h = yes -a $ac_cv_header_lber_h = yes; then
+        echo "$as_me:$LINENO: checking OpenLDAP api" >&5
+echo $ECHO_N "checking OpenLDAP api... $ECHO_C" >&6
+if test "${cmu_cv_openldap_api+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <ldap.h>
+
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+char *__openldap_api = LDAP_API_FEATURE_X_OPENLDAP;
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__openldap_api" >/dev/null 2>&1; then
+  cmu_cv_openldap_api=yes
+else
+  cmu_cv_openldap_api=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $cmu_cv_openldap_api" >&5
+echo "${ECHO_T}$cmu_cv_openldap_api" >&6
+
+
+        if test "$cmu_cv_openldap_api" = yes; then
+            echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5
+echo $ECHO_N "checking for ldap_initialize in -lldap... $ECHO_C" >&6
+if test "${ac_cv_lib_ldap_ldap_initialize+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap -llber $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ldap_initialize ();
+int
+main ()
+{
+ldap_initialize ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ldap_ldap_initialize=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ldap_ldap_initialize=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5
+echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6
+if test $ac_cv_lib_ldap_ldap_initialize = yes; then
+   cmu_link_openldap="-lldap -llber"
+else
+   cmu_link_openldap=no
+fi
+
+        fi
+    fi
+
+    if test "$cmu_cv_openldap_api" = no -o "$cmu_link_openldap" = no; then
+        { { echo "$as_me:$LINENO: error: Cannot enable LDAPDB plugin: Could not locate OpenLDAP" >&5
+echo "$as_me: error: Cannot enable LDAPDB plugin: Could not locate OpenLDAP" >&2;}
+   { (exit 1); exit 1; }; }
+    else
+        echo "$as_me:$LINENO: checking OpenLDAP version" >&5
+echo $ECHO_N "checking OpenLDAP version... $ECHO_C" >&6
+if test "${cmu_cv_openldap_compat+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <ldap.h>
+
+/* Require 2.1.27+ and 2.2.6+ */
+#if LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 1 && LDAP_VENDOR_VERSION_PATCH > 26
+char *__openldap_compat = "2.1.27 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR == 2 && LDAP_VENDOR_VERSION_PATCH > 5
+char *__openldap_compat = "2.2.6 or better okay";
+#elif LDAP_VENDOR_VERSION_MAJOR == 2  && LDAP_VENDOR_VERSION_MINOR > 2
+char *__openldap_compat = "2.3 or better okay"
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "__openldap_compat" >/dev/null 2>&1; then
+  cmu_cv_openldap_compat=yes
+else
+  cmu_cv_openldap_compat=no
+fi
+rm -f conftest*
+
+fi
+echo "$as_me:$LINENO: result: $cmu_cv_openldap_compat" >&5
+echo "${ECHO_T}$cmu_cv_openldap_compat" >&6
+
+
+        if test "$cmu_cv_openldap_compat" = no; then
+            { { echo "$as_me:$LINENO: error: Cannot enable LDAPDB plugin: OpenLDAP library located but incompatible" >&5
+echo "$as_me: error: Cannot enable LDAPDB plugin: OpenLDAP library located but incompatible" >&2;}
+   { (exit 1); exit 1; }; }
+        else
+            LIB_LDAP=$cmu_link_openldap
+
+
+            SASL_MECHS="$SASL_MECHS libldapdb.la"
+            if test "$enable_static" = yes; then
+                SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/ldapdb.c"
+                SASL_STATIC_OBJS="$SASL_STATIC_OBJS ldapdb.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_LDAPDB
+_ACEOF
+
+            fi
+        fi
+    fi
+
+    if test "$cmu_cv_openldap_compat" != yes; then
+        CPPFLAGS=$save_CPPFLAGS
+        LDFLAGS=$save_LDFLAGS
+    fi
+else
+    echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+
+
+
+
+
+# Check whether --with-plugindir or --without-plugindir was given.
+if test "${with_plugindir+set}" = set; then
+  withval="$with_plugindir"
+  plugindir=$withval
+else
+  plugindir=/usr/lib/sasl2
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define PLUGINDIR "$plugindir"
+_ACEOF
+
+
+
+
+# Check whether --with-configdir or --without-configdir was given.
+if test "${with_configdir+set}" = set; then
+  withval="$with_configdir"
+  configdir=$withval
+else
+  configdir=$plugindir:/etc/sasl2
+fi;
+
+cat >>confdefs.h <<_ACEOF
+#define CONFIGDIR "$configdir"
+_ACEOF
+
+
+
+
+# Check whether --with-rc4 or --without-rc4 was given.
+if test "${with_rc4+set}" = set; then
+  withval="$with_rc4"
+  with_rc4=$withval
+else
+  with_rc4=yes
+fi;
+
+if test "$with_rc4" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_RC4
+_ACEOF
+
+fi
+
+building_for_macosx=no
+case "$host_os" in
+        darwin*)
+# Check whether --enable-macos-framework or --disable-macos-framework was given.
+if test "${enable_macos_framework+set}" = set; then
+  enableval="$enable_macos_framework"
+  building_for_macosx=no
+else
+  building_for_macosx=yes
+fi;
+        ;;
+esac
+
+
+if test "$building_for_macosx" = yes; then
+  MACOSX_TRUE=
+  MACOSX_FALSE='#'
+else
+  MACOSX_TRUE='#'
+  MACOSX_FALSE=
+fi
+
+
+echo "$as_me:$LINENO: checking for dmalloc library" >&5
+echo $ECHO_N "checking for dmalloc library... $ECHO_C" >&6
+
+# Check whether --with-dmalloc or --without-dmalloc was given.
+if test "${with_dmalloc+set}" = set; then
+  withval="$with_dmalloc"
+  with_dmalloc=$withval
+else
+  with_dmalloc=no
+fi;
+
+DMALLOC_LIBS=""
+
+if test "$with_dmalloc" != "no"; then
+   if test "$with_dmalloc" = "yes"; then
+       with_dmalloc="/usr/local"
+   fi
+
+   if test -r "$with_dmalloc/libdmalloc.a"; then
+       DMALLOC_LIBS="$with_dmalloc/libdmalloc.a"
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+   elif test -r "$with_dmalloc/lib/libdmalloc.a"; then
+       DMALLOC_LIBS="$with_dmalloc/lib/libdmalloc.a"
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_DMALLOC
+_ACEOF
+
+       echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+   else
+       { { echo "$as_me:$LINENO: error: cannot find dmalloc library" >&5
+echo "$as_me: error: cannot find dmalloc library" >&2;}
+   { (exit please check your installation.); exit please check your installation.; }; }
+   fi
+else
+   echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+
+
+echo "$as_me:$LINENO: checking for sfio library" >&5
+echo $ECHO_N "checking for sfio library... $ECHO_C" >&6
+
+# Check whether --with-sfio or --without-sfio was given.
+if test "${with_sfio+set}" = set; then
+  withval="$with_sfio"
+  with_sfio=$withval
+else
+  with_sfio=no
+fi;
+
+if test "$with_sfio" != "no"; then
+   if test "$with_sfio" = "yes"; then
+       with_sfio="/usr/local"
+   fi
+
+
+
+
+
+   if test -r "$with_sfio/sfio.h"; then SFIO_DIR=$with_sfio;
+                                             SFIO_INC_DIR=$with_sfio
+   elif test -r "$with_sfio/include/sfio.h"; then SFIO_DIR=$with_sfio;
+                                             SFIO_INC_DIR=$with_sfio/include
+   elif test -r "$with_sfio/include/sfio/sfio.h"; then SFIO_DIR=$with_sfio;
+                                             SFIO_INC_DIR=$with_sfio/include/sfio
+   fi
+
+   if test -z "$SFIO_DIR"; then
+       { { echo "$as_me:$LINENO: error: Cannot find sfio.h" >&5
+echo "$as_me: error: Cannot find sfio.h" >&2;}
+   { (exit Please check your SFIO installation.); exit Please check your SFIO installation.; }; }
+   fi
+
+
+               str="$SFIO_DIR/lib/libsfio.*"
+               for i in `echo $str`; do
+                       if test -r $i; then
+                               SFIO_LIBDIR=$SFIO_DIR/lib
+                               break 2
+                       fi
+               done
+
+
+               str="$SFIO_DIR/lib/sfio/libsfio.*"
+               for i in `echo $str`; do
+                       if test -r $i; then
+                               SFIO_LIBDIR=$SFIO_DIR/lib/sfio
+                               break 2
+                       fi
+               done
+
+
+   if test -z "$SFIO_LIBDIR"; then
+       { { echo "$as_me:$LINENO: error: Cannot find sfio library" >&5
+echo "$as_me: error: Cannot find sfio library" >&2;}
+   { (exit Please check your SFIO installation.); exit Please check your SFIO installation.; }; }
+   fi
+
+   SFIO_INC_FLAGS="-I$SFIO_INC_DIR"
+   SFIO_LIB_FLAGS="-L$SFIO_LIBDIR -lsfio"
+   SMTPTEST_PROGRAM="smtptest"
+   SASL_UTIL_LIBS_EXTRA=libsfsasl2.la
+   SASL_UTIL_HEADERS_EXTRA=sfsasl.h
+
+   echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+   echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+   SFIO_INC_FLAGS=""
+   SFIO_LIB_FLAGS=""
+   SMTPTEST_PROGRAM=""
+   SASL_UTIL_LIBS_EXTRA=""
+   SASL_UTIL_HEADERS_EXTRA=""
+fi
+
+
+
+
+
+
+
+sasl_cv_getsubopt=no
+echo "$as_me:$LINENO: checking for getsubopt" >&5
+echo $ECHO_N "checking for getsubopt... $ECHO_C" >&6
+if test "${ac_cv_func_getsubopt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getsubopt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getsubopt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getsubopt) || defined (__stub___getsubopt)
+choke me
+#else
+char (*f) () = getsubopt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getsubopt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getsubopt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getsubopt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getsubopt" >&5
+echo "${ECHO_T}$ac_cv_func_getsubopt" >&6
+if test $ac_cv_func_getsubopt = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETSUBOPT
+_ACEOF
+
+else
+  sasl_cv_getsubopt=yes
+fi
+
+if test $sasl_cv_getsubopt = yes; then
+       LIBOBJS="$LIBOBJS getsubopt.$ac_objext"
+       GETSUBOPT="getsubopt.lo"
+fi
+
+
+sasl_cv_snprintf=no
+SNPRINTFOBJS=""
+echo "$as_me:$LINENO: checking for snprintf" >&5
+echo $ECHO_N "checking for snprintf... $ECHO_C" >&6
+if test "${ac_cv_func_snprintf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char snprintf (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char snprintf ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_snprintf) || defined (__stub___snprintf)
+choke me
+#else
+char (*f) () = snprintf;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != snprintf;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_snprintf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_snprintf=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_snprintf" >&5
+echo "${ECHO_T}$ac_cv_func_snprintf" >&6
+if test $ac_cv_func_snprintf = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SNPRINTF
+_ACEOF
+
+else
+  sasl_cv_snprintf=yes
+fi
+
+echo "$as_me:$LINENO: checking for vsnprintf" >&5
+echo $ECHO_N "checking for vsnprintf... $ECHO_C" >&6
+if test "${ac_cv_func_vsnprintf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char vsnprintf (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char vsnprintf ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_vsnprintf) || defined (__stub___vsnprintf)
+choke me
+#else
+char (*f) () = vsnprintf;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != vsnprintf;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_vsnprintf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_vsnprintf=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_vsnprintf" >&5
+echo "${ECHO_T}$ac_cv_func_vsnprintf" >&6
+if test $ac_cv_func_vsnprintf = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_VSNPRINTF
+_ACEOF
+
+else
+  sasl_cv_snprintf=yes
+fi
+
+if test $sasl_cv_snprintf = yes; then
+       LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+        SNPRINTFOBJS="snprintf.o"
+        LTSNPRINTFOBJS="snprintf.lo"
+fi
+
+
+
+
+echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5
+echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_aton ();
+int
+main ()
+{
+inet_aton ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_inet_aton=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_inet_aton=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_aton" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_inet_aton" >&6
+if test $ac_cv_lib_resolv_inet_aton = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+
+GETADDRINFOOBJS=""
+sasl_cv_getaddrinfo=yes
+
+echo "$as_me:$LINENO: checking for getaddrinfo" >&5
+echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6
+if test "${ac_cv_func_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getaddrinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getaddrinfo) || defined (__stub___getaddrinfo)
+choke me
+#else
+char (*f) () = getaddrinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getaddrinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6
+if test $ac_cv_func_getaddrinfo = yes; then
+    ac_cv_lib_socket_getaddrinfo=no
+  ac_cv_lib_inet6_getaddrinfo=no
+
+else
+    echo "$as_me:$LINENO: checking for getaddrinfo in -lsocket" >&5
+echo $ECHO_N "checking for getaddrinfo in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+int
+main ()
+{
+getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_getaddrinfo" >&6
+if test $ac_cv_lib_socket_getaddrinfo = yes; then
+      LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_getaddrinfo=no
+
+else
+      echo "$as_me:$LINENO: checking whether your system has IPv6 directory" >&5
+echo $ECHO_N "checking whether your system has IPv6 directory... $ECHO_C" >&6
+    if test "${ipv6_cv_dir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+        for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done
+fi
+    echo "$as_me:$LINENO: result: $ipv6_cv_dir" >&5
+echo "${ECHO_T}$ipv6_cv_dir" >&6
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_getaddrinfo=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      echo "$as_me:$LINENO: checking for getaddrinfo in -linet6" >&5
+echo $ECHO_N "checking for getaddrinfo in -linet6... $ECHO_C" >&6
+if test "${ac_cv_lib_inet6_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet6  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+int
+main ()
+{
+getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet6_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet6_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_inet6_getaddrinfo" >&6
+if test $ac_cv_lib_inet6_getaddrinfo = yes; then
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi
+fi
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi
+fi
+
+fi
+ipv6_cv_getaddrinfo=no
+if test $ac_cv_func_getaddrinfo = yes -o $ac_cv_lib_socket_getaddrinfo = yes \
+     -o $ac_cv_lib_inet6_getaddrinfo = yes
+then
+  ipv6_cv_getaddrinfo=yes
+fi
+if test $ipv6_cv_getaddrinfo = no; then
+  if test getaddrinfo = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ipv6_cv_pfx}getaddrinfo" >/dev/null 2>&1; then
+  as_ac_var=`echo "ac_cv_func_${ipv6_cv_pfx}getaddrinfo" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for ${ipv6_cv_pfx}getaddrinfo" >&5
+echo $ECHO_N "checking for ${ipv6_cv_pfx}getaddrinfo... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char ${ipv6_cv_pfx}getaddrinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ${ipv6_cv_pfx}getaddrinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_${ipv6_cv_pfx}getaddrinfo) || defined (__stub___${ipv6_cv_pfx}getaddrinfo)
+choke me
+#else
+char (*f) () = ${ipv6_cv_pfx}getaddrinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != ${ipv6_cv_pfx}getaddrinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+
+fi
+rm -f conftest*
+
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}getaddrinfo = Xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+        ipv6_cv_getaddrinfo=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_getaddrinfo = yes; then
+
+echo "$as_me:$LINENO: checking for gai_strerror" >&5
+echo $ECHO_N "checking for gai_strerror... $ECHO_C" >&6
+if test "${ac_cv_func_gai_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char gai_strerror (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gai_strerror ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_gai_strerror) || defined (__stub___gai_strerror)
+choke me
+#else
+char (*f) () = gai_strerror;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != gai_strerror;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_gai_strerror=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_gai_strerror=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_gai_strerror" >&5
+echo "${ECHO_T}$ac_cv_func_gai_strerror" >&6
+if test $ac_cv_func_gai_strerror = yes; then
+    ac_cv_lib_socket_gai_strerror=no
+  ac_cv_lib_inet6_gai_strerror=no
+
+else
+    echo "$as_me:$LINENO: checking for gai_strerror in -lsocket" >&5
+echo $ECHO_N "checking for gai_strerror in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_gai_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gai_strerror ();
+int
+main ()
+{
+gai_strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_gai_strerror=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_gai_strerror=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_gai_strerror" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_gai_strerror" >&6
+if test $ac_cv_lib_socket_gai_strerror = yes; then
+      LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_gai_strerror=no
+
+else
+      echo "$as_me:$LINENO: checking whether your system has IPv6 directory" >&5
+echo $ECHO_N "checking whether your system has IPv6 directory... $ECHO_C" >&6
+    if test "${ipv6_cv_dir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+        for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done
+fi
+    echo "$as_me:$LINENO: result: $ipv6_cv_dir" >&5
+echo "${ECHO_T}$ipv6_cv_dir" >&6
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_gai_strerror=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      echo "$as_me:$LINENO: checking for gai_strerror in -linet6" >&5
+echo $ECHO_N "checking for gai_strerror in -linet6... $ECHO_C" >&6
+if test "${ac_cv_lib_inet6_gai_strerror+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet6  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gai_strerror ();
+int
+main ()
+{
+gai_strerror ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet6_gai_strerror=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet6_gai_strerror=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_gai_strerror" >&5
+echo "${ECHO_T}$ac_cv_lib_inet6_gai_strerror" >&6
+if test $ac_cv_lib_inet6_gai_strerror = yes; then
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi
+fi
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi
+fi
+
+fi
+ipv6_cv_gai_strerror=no
+if test $ac_cv_func_gai_strerror = yes -o $ac_cv_lib_socket_gai_strerror = yes \
+     -o $ac_cv_lib_inet6_gai_strerror = yes
+then
+  ipv6_cv_gai_strerror=yes
+fi
+if test $ipv6_cv_gai_strerror = no; then
+  if test gai_strerror = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ipv6_cv_pfx}gai_strerror" >/dev/null 2>&1; then
+  as_ac_var=`echo "ac_cv_func_${ipv6_cv_pfx}gai_strerror" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for ${ipv6_cv_pfx}gai_strerror" >&5
+echo $ECHO_N "checking for ${ipv6_cv_pfx}gai_strerror... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char ${ipv6_cv_pfx}gai_strerror (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ${ipv6_cv_pfx}gai_strerror ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_${ipv6_cv_pfx}gai_strerror) || defined (__stub___${ipv6_cv_pfx}gai_strerror)
+choke me
+#else
+char (*f) () = ${ipv6_cv_pfx}gai_strerror;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != ${ipv6_cv_pfx}gai_strerror;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+
+fi
+rm -f conftest*
+
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}gai_strerror = Xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+        ipv6_cv_gai_strerror=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_gai_strerror = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+                sasl_cv_getaddrinfo=no
+else
+  :
+fi
+else
+  :
+fi
+if test $sasl_cv_getaddrinfo = yes; then
+    LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
+    GETADDRINFOOBJS="getaddrinfo.o"
+    LTGETADDRINFOOBJS="getaddrinfo.lo"
+fi
+
+
+
+GETNAMEINFOOBJS=""
+sasl_cv_getnameinfo=no
+
+echo "$as_me:$LINENO: checking for getnameinfo" >&5
+echo $ECHO_N "checking for getnameinfo... $ECHO_C" >&6
+if test "${ac_cv_func_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getnameinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getnameinfo) || defined (__stub___getnameinfo)
+choke me
+#else
+char (*f) () = getnameinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getnameinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getnameinfo" >&6
+if test $ac_cv_func_getnameinfo = yes; then
+    ac_cv_lib_socket_getnameinfo=no
+  ac_cv_lib_inet6_getnameinfo=no
+
+else
+    echo "$as_me:$LINENO: checking for getnameinfo in -lsocket" >&5
+echo $ECHO_N "checking for getnameinfo in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+int
+main ()
+{
+getnameinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_getnameinfo" >&6
+if test $ac_cv_lib_socket_getnameinfo = yes; then
+      LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_getnameinfo=no
+
+else
+      echo "$as_me:$LINENO: checking whether your system has IPv6 directory" >&5
+echo $ECHO_N "checking whether your system has IPv6 directory... $ECHO_C" >&6
+    if test "${ipv6_cv_dir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+        for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done
+fi
+    echo "$as_me:$LINENO: result: $ipv6_cv_dir" >&5
+echo "${ECHO_T}$ipv6_cv_dir" >&6
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_getnameinfo=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      echo "$as_me:$LINENO: checking for getnameinfo in -linet6" >&5
+echo $ECHO_N "checking for getnameinfo in -linet6... $ECHO_C" >&6
+if test "${ac_cv_lib_inet6_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet6  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+int
+main ()
+{
+getnameinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet6_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet6_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_inet6_getnameinfo" >&6
+if test $ac_cv_lib_inet6_getnameinfo = yes; then
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi
+fi
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi
+fi
+
+fi
+ipv6_cv_getnameinfo=no
+if test $ac_cv_func_getnameinfo = yes -o $ac_cv_lib_socket_getnameinfo = yes \
+     -o $ac_cv_lib_inet6_getnameinfo = yes
+then
+  ipv6_cv_getnameinfo=yes
+fi
+if test $ipv6_cv_getnameinfo = no; then
+  if test getnameinfo = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ipv6_cv_pfx}getnameinfo" >/dev/null 2>&1; then
+  as_ac_var=`echo "ac_cv_func_${ipv6_cv_pfx}getnameinfo" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for ${ipv6_cv_pfx}getnameinfo" >&5
+echo $ECHO_N "checking for ${ipv6_cv_pfx}getnameinfo... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char ${ipv6_cv_pfx}getnameinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ${ipv6_cv_pfx}getnameinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_${ipv6_cv_pfx}getnameinfo) || defined (__stub___${ipv6_cv_pfx}getnameinfo)
+choke me
+#else
+char (*f) () = ${ipv6_cv_pfx}getnameinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != ${ipv6_cv_pfx}getnameinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+
+fi
+rm -f conftest*
+
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}getnameinfo = Xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+        ipv6_cv_getnameinfo=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_getnameinfo = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETNAMEINFO
+_ACEOF
+
+else
+  sasl_cv_getnameinfo=yes
+fi
+if test $sasl_cv_getnameinfo = yes; then
+       LIBOBJS="$LIBOBJS getnameinfo.$ac_objext"
+        GETNAMEINFOOBJS="getnameinfo.o"
+        LTGETNAMEINFOOBJS="getnameinfo.lo"
+fi
+
+
+
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,'`
+
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for inline" >&5
+echo $ECHO_N "checking for inline... $ECHO_C" >&6
+if test "${ac_cv_c_inline+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_inline=$ac_kw; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
+echo "${ECHO_T}$ac_cv_c_inline" >&6
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  no)
+cat >>confdefs.h <<\_ACEOF
+#define inline
+_ACEOF
+ ;;
+  *)  cat >>confdefs.h <<_ACEOF
+#define inline $ac_cv_c_inline
+_ACEOF
+ ;;
+esac
+
+echo "$as_me:$LINENO: checking for mode_t" >&5
+echo $ECHO_N "checking for mode_t... $ECHO_C" >&6
+if test "${ac_cv_type_mode_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((mode_t *) 0)
+  return 0;
+if (sizeof (mode_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_mode_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_mode_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5
+echo "${ECHO_T}$ac_cv_type_mode_t" >&6
+if test $ac_cv_type_mode_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define mode_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+  return 0;
+if (sizeof (pid_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_pid_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_hdr that defines DIR" >&5
+echo $ECHO_N "checking for $ac_hdr that defines DIR... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in dir; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+else
+  echo "$as_me:$LINENO: checking for library containing opendir" >&5
+echo $ECHO_N "checking for library containing opendir... $ECHO_C" >&6
+if test "${ac_cv_search_opendir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+ac_cv_search_opendir=no
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="none required"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_opendir" = no; then
+  for ac_lib in x; do
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendir ();
+int
+main ()
+{
+opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_search_opendir="-l$ac_lib"
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+  done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_opendir" >&5
+echo "${ECHO_T}$ac_cv_search_opendir" >&6
+if test "$ac_cv_search_opendir" != no; then
+  test "$ac_cv_search_opendir" = "none required" || LIBS="$ac_cv_search_opendir $LIBS"
+
+fi
+
+fi
+
+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_sys_wait_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+if test $ac_cv_header_sys_wait_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_header in des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+echo "$as_me:$LINENO: checking whether you have ss_family in struct sockaddr_storage" >&5
+echo $ECHO_N "checking whether you have ss_family in struct sockaddr_storage... $ECHO_C" >&6
+if test "${ipv6_cv_ss_family+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+struct sockaddr_storage ss; int i = ss.ss_family;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_ss_family=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+if test $ipv6_cv_ss_family = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SS_FAMILY
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_ss_family" >&5
+echo "${ECHO_T}$ipv6_cv_ss_family" >&6
+
+echo "$as_me:$LINENO: checking whether you have sa_len in struct sockaddr" >&5
+echo $ECHO_N "checking whether you have sa_len in struct sockaddr... $ECHO_C" >&6
+if test "${ipv6_cv_sa_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+struct sockaddr sa; int i = sa.sa_len;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_sa_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_sa_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+if test $ipv6_cv_sa_len = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKADDR_SA_LEN
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_sa_len" >&5
+echo "${ECHO_T}$ipv6_cv_sa_len" >&6
+
+echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ipv6_cv_socklen_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+socklen_t len = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_socklen_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_socklen_t=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+if test $ipv6_cv_socklen_t = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKLEN_T
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_socklen_t" >&5
+echo "${ECHO_T}$ipv6_cv_socklen_t" >&6
+
+#AC_FUNC_MEMCMP
+#AC_FUNC_VPRINTF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in gethostname getdomainname getpwnam getspnam gettimeofday inet_aton memcpy mkdir select socket strchr strdup strerror strspn strstr strtol jrand48
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+if test $enable_cmulocal = yes; then
+    { echo "$as_me:$LINENO: WARNING: enabling CMU local kludges" >&5
+echo "$as_me: WARNING: enabling CMU local kludges" >&2;}
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB4_IGNORE_IP_ADDRESS
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PREFER_MECH "KERBEROS_V4"
+_ACEOF
+
+fi
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/socket.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "sockaddr_storage" >/dev/null 2>&1; then
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+
+
+
+
+subdirs="$subdirs saslauthd"
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+                                                                                                                                                                          ac_config_files="$ac_config_files Makefile include/Makefile sasldb/Makefile plugins/Makefile lib/Makefile utils/Makefile doc/Makefile sample/Makefile java/Makefile java/CyrusSasl/Makefile java/Test/Makefile java/javax/Makefile java/javax/security/Makefile java/javax/security/auth/Makefile java/javax/security/auth/callback/Makefile pwcheck/Makefile man/Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${JAVA_TRUE}" && test -z "${JAVA_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"JAVA\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"JAVA\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${SAMPLE_TRUE}" && test -z "${SAMPLE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"SAMPLE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"SAMPLE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${NO_SASL_DB_MANS_TRUE}" && test -z "${NO_SASL_DB_MANS_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"NO_SASL_DB_MANS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"NO_SASL_DB_MANS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${SASLAUTHD_TRUE}" && test -z "${SASLAUTHD_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"SASLAUTHD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"SASLAUTHD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${PWCHECK_TRUE}" && test -z "${PWCHECK_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"PWCHECK\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"PWCHECK\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${MACOSX_TRUE}" && test -z "${MACOSX_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"MACOSX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MACOSX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "include/Makefile" ) CONFIG_FILES="$CONFIG_FILES include/Makefile" ;;
+  "sasldb/Makefile" ) CONFIG_FILES="$CONFIG_FILES sasldb/Makefile" ;;
+  "plugins/Makefile" ) CONFIG_FILES="$CONFIG_FILES plugins/Makefile" ;;
+  "lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+  "utils/Makefile" ) CONFIG_FILES="$CONFIG_FILES utils/Makefile" ;;
+  "doc/Makefile" ) CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+  "sample/Makefile" ) CONFIG_FILES="$CONFIG_FILES sample/Makefile" ;;
+  "java/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/Makefile" ;;
+  "java/CyrusSasl/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/CyrusSasl/Makefile" ;;
+  "java/Test/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/Test/Makefile" ;;
+  "java/javax/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/javax/Makefile" ;;
+  "java/javax/security/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/javax/security/Makefile" ;;
+  "java/javax/security/auth/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/javax/security/auth/Makefile" ;;
+  "java/javax/security/auth/callback/Makefile" ) CONFIG_FILES="$CONFIG_FILES java/javax/security/auth/callback/Makefile" ;;
+  "pwcheck/Makefile" ) CONFIG_FILES="$CONFIG_FILES pwcheck/Makefile" ;;
+  "man/Makefile" ) CONFIG_FILES="$CONFIG_FILES man/Makefile" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@target@,$target,;t t
+s,@target_cpu@,$target_cpu,;t t
+s,@target_vendor@,$target_vendor,;t t
+s,@target_os@,$target_os,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@CPP@,$CPP,;t t
+s,@LN_S@,$LN_S,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@PURECOV@,$PURECOV,;t t
+s,@PURIFY@,$PURIFY,;t t
+s,@JAVAC@,$JAVAC,;t t
+s,@JAVAH@,$JAVAH,;t t
+s,@JAVADOC@,$JAVADOC,;t t
+s,@JAVA_TRUE@,$JAVA_TRUE,;t t
+s,@JAVA_FALSE@,$JAVA_FALSE,;t t
+s,@JAVA_INCLUDES@,$JAVA_INCLUDES,;t t
+s,@JAVAROOT@,$JAVAROOT,;t t
+s,@SAMPLE_TRUE@,$SAMPLE_TRUE,;t t
+s,@SAMPLE_FALSE@,$SAMPLE_FALSE,;t t
+s,@LIB_SOCKET@,$LIB_SOCKET,;t t
+s,@EGREP@,$EGREP,;t t
+s,@SASL_DB_UTILS@,$SASL_DB_UTILS,;t t
+s,@SASL_DB_MANS@,$SASL_DB_MANS,;t t
+s,@SASL_DB_BACKEND@,$SASL_DB_BACKEND,;t t
+s,@SASL_DB_BACKEND_STATIC@,$SASL_DB_BACKEND_STATIC,;t t
+s,@SASL_DB_INC@,$SASL_DB_INC,;t t
+s,@SASL_DB_LIB@,$SASL_DB_LIB,;t t
+s,@NO_SASL_DB_MANS_TRUE@,$NO_SASL_DB_MANS_TRUE,;t t
+s,@NO_SASL_DB_MANS_FALSE@,$NO_SASL_DB_MANS_FALSE,;t t
+s,@SASL_DL_LIB@,$SASL_DL_LIB,;t t
+s,@NM@,$NM,;t t
+s,@SASLAUTHD_TRUE@,$SASLAUTHD_TRUE,;t t
+s,@SASLAUTHD_FALSE@,$SASLAUTHD_FALSE,;t t
+s,@PWCHECKMETH@,$PWCHECKMETH,;t t
+s,@PWCHECK_TRUE@,$PWCHECK_TRUE,;t t
+s,@PWCHECK_FALSE@,$PWCHECK_FALSE,;t t
+s,@IPCTYPE@,$IPCTYPE,;t t
+s,@LIB_DOOR@,$LIB_DOOR,;t t
+s,@CMU_LIB_SUBDIR@,$CMU_LIB_SUBDIR,;t t
+s,@LIB_DES@,$LIB_DES,;t t
+s,@OTP_LIBS@,$OTP_LIBS,;t t
+s,@SRP_LIBS@,$SRP_LIBS,;t t
+s,@SASL_KRB_LIB@,$SASL_KRB_LIB,;t t
+s,@LIB_CRYPT@,$LIB_CRYPT,;t t
+s,@GSSAPI_LIBS@,$GSSAPI_LIBS,;t t
+s,@GSSAPIBASE_LIBS@,$GSSAPIBASE_LIBS,;t t
+s,@PLAIN_LIBS@,$PLAIN_LIBS,;t t
+s,@NTLM_LIBS@,$NTLM_LIBS,;t t
+s,@PASSDSS_LIBS@,$PASSDSS_LIBS,;t t
+s,@LIB_MYSQL@,$LIB_MYSQL,;t t
+s,@LIB_PGSQL@,$LIB_PGSQL,;t t
+s,@LIB_SQLITE@,$LIB_SQLITE,;t t
+s,@LIB_LDAP@,$LIB_LDAP,;t t
+s,@SASL_MECHS@,$SASL_MECHS,;t t
+s,@SASL_STATIC_SRCS@,$SASL_STATIC_SRCS,;t t
+s,@SASL_STATIC_OBJS@,$SASL_STATIC_OBJS,;t t
+s,@SASL_STATIC_LIBS@,$SASL_STATIC_LIBS,;t t
+s,@plugindir@,$plugindir,;t t
+s,@configdir@,$configdir,;t t
+s,@MACOSX_TRUE@,$MACOSX_TRUE,;t t
+s,@MACOSX_FALSE@,$MACOSX_FALSE,;t t
+s,@DMALLOC_LIBS@,$DMALLOC_LIBS,;t t
+s,@SFIO_INC_FLAGS@,$SFIO_INC_FLAGS,;t t
+s,@SFIO_LIB_FLAGS@,$SFIO_LIB_FLAGS,;t t
+s,@SMTPTEST_PROGRAM@,$SMTPTEST_PROGRAM,;t t
+s,@SASL_UTIL_LIBS_EXTRA@,$SASL_UTIL_LIBS_EXTRA,;t t
+s,@SASL_UTIL_HEADERS_EXTRA@,$SASL_UTIL_HEADERS_EXTRA,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@GETSUBOPT@,$GETSUBOPT,;t t
+s,@SNPRINTFOBJS@,$SNPRINTFOBJS,;t t
+s,@LTSNPRINTFOBJS@,$LTSNPRINTFOBJS,;t t
+s,@GETADDRINFOOBJS@,$GETADDRINFOOBJS,;t t
+s,@LTGETADDRINFOOBJS@,$LTGETADDRINFOOBJS,;t t
+s,@GETNAMEINFOOBJS@,$GETNAMEINFOOBJS,;t t
+s,@LTGETNAMEINFOOBJS@,$LTGETNAMEINFOOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+s,@DIRS@,$DIRS,;t t
+s,@subdirs@,$subdirs,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[     ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[    ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[    ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[    ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X$ac_file : 'X\(//\)[^/]' \| \
+         X$ac_file : 'X\(//\)$' \| \
+         X$ac_file : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_dest" : 'X\(//\)[^/]' \| \
+         X"$ac_dest" : 'X\(//\)$' \| \
+         X"$ac_dest" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$mf" : 'X\(//\)[^/]' \| \
+         X"$mf" : 'X\(//\)$' \| \
+         X"$mf" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n -e '/^U = / s///p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n -e '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$file" : 'X\(//\)[^/]' \| \
+         X"$file" : 'X\(//\)$' \| \
+         X"$file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_sub_configure_args="--prefix=$prefix $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d $srcdir/$ac_dir || continue
+
+    { echo "$as_me:$LINENO: configuring in $ac_dir" >&5
+echo "$as_me: configuring in $ac_dir" >&6;}
+    { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+    cd $ac_dir
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure.gnu'"
+    elif test -f $ac_srcdir/configure; then
+      ac_sub_configure="$SHELL '$ac_srcdir/configure'"
+    elif test -f $ac_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      { echo "$as_me:$LINENO: WARNING: no configuration information is in $ac_dir" >&5
+echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+        ac_sub_cache_file=$ac_top_builddir$cache_file ;;
+      esac
+
+      { echo "$as_me:$LINENO: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+echo "$as_me: running $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval $ac_sub_configure $ac_sub_configure_args \
+           --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir ||
+        { { echo "$as_me:$LINENO: error: $ac_sub_configure failed for $ac_dir" >&5
+echo "$as_me: error: $ac_sub_configure failed for $ac_dir" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
+
+echo Configuration Complete.  Type \'make\' to build.
diff --git a/configure.in b/configure.in
new file mode 100644 (file)
index 0000000..9cd9978
--- /dev/null
@@ -0,0 +1,1334 @@
+dnl configure.in for the SASL library
+dnl Rob Siemborski
+dnl Rob Earhart
+dnl $Id: configure.in,v 1.213.2.1 2009/04/27 17:58:25 murch Exp $
+dnl
+dnl Copyright (c) 2001 Carnegie Mellon University.  All rights reserved.
+dnl
+dnl Redistribution and use in source and binary forms, with or without
+dnl modification, are permitted provided that the following conditions
+dnl are met:
+dnl
+dnl 1. Redistributions of source code must retain the above copyright
+dnl    notice, this list of conditions and the following disclaimer. 
+dnl
+dnl 2. Redistributions in binary form must reproduce the above copyright
+dnl    notice, this list of conditions and the following disclaimer in
+dnl    the documentation and/or other materials provided with the
+dnl    distribution.
+dnl
+dnl 3. The name "Carnegie Mellon University" must not be used to
+dnl    endorse or promote products derived from this software without
+dnl    prior written permission. For permission or any other legal
+dnl    details, please contact  
+dnl      Office of Technology Transfer
+dnl      Carnegie Mellon University
+dnl      5000 Forbes Avenue
+dnl      Pittsburgh, PA  15213-3890
+dnl      (412) 268-4387, fax: (412) 268-7395
+dnl      tech-transfer@andrew.cmu.edu
+dnl
+dnl 4. Redistributions of any form whatsoever must retain the following
+dnl    acknowledgment:
+dnl    \"This product includes software developed by Computing Services
+dnl     at Carnegie Mellon University (http://www.cmu.edu/computing/).\"
+dnl
+dnl CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+dnl THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+dnl AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+dnl FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+dnl WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+dnl AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+dnl OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+dnl
+AC_INIT(lib/saslint.h)
+AC_PREREQ([2.54])
+
+dnl use ./config.cache as the default cache file.
+dnl we require a cache file to successfully configure our build.
+if test $cache_file = "/dev/null"; then
+cache_file="./config.cache"
+AC_CACHE_LOAD
+fi
+
+AC_CONFIG_AUX_DIR(config)
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+dnl
+dnl REMINDER: When changing the version number here, please also update
+dnl the values in win32/include/config.h and include/sasl.h as well.
+dnl
+AM_INIT_AUTOMAKE(cyrus-sasl, 2.1.23)
+CMU_INIT_AUTOMAKE
+
+# and include our config dir scripts
+ACLOCAL="$ACLOCAL -I \$(top_srcdir)/config"
+
+DIRS=""
+
+AC_ARG_ENABLE(cmulocal,
+              [AC_HELP_STRING([--enable-cmulocal],
+                              [enable local mods for CMU [[no]]])],
+              [],
+              enable_cmulocal=no)
+
+AC_ARG_ENABLE(sample,
+              [AC_HELP_STRING([--enable-sample],
+                              [compile sample code [[yes]]])],
+              enable_sample=yes)
+
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_AWK
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_INSTALL
+CMU_C___ATTRIBUTE__
+
+dnl check for -R, etc. switch
+CMU_GUESS_RUNPATH_SWITCH
+
+dnl xxx compatibility
+AC_ARG_WITH(staticsasl)
+if test "$with_staticsasl" = yes; then
+       enable_shared=yes
+       enable_static=yes
+fi
+
+save_target=$target
+if test -z "$target"; then
+       target="NONE"
+fi
+
+# new libtool
+AM_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+target=$save_target
+
+if test "$enable_static" = yes; then
+       SASL_STATIC_LIBS=libsasl2.a
+else
+       SASL_STATIC_LIBS=
+fi
+
+AC_ARG_ENABLE(staticdlopen, [  --enable-staticdlopen   try dynamic plugins when we are a static libsasl [[no]] ],
+                enable_staticdlopen=$enableval,
+                enable_staticdlopen=no)
+
+if test "$enable_staticdlopen" = yes; then
+  AC_DEFINE(TRY_DLOPEN_WHEN_STATIC,[],[Should we try to dlopen() plugins while staticly compiled?])
+fi
+
+if test "$ac_cv_prog_gcc" = yes; then
+  CFLAGS="-Wall -W ${CFLAGS}"
+fi
+
+AC_ARG_WITH(purecov,[  --with-purecov          link with purecov])
+if test "$with_purecov" = yes; then
+  AC_CHECK_PROGS(PURECOV, purecov)
+fi
+AC_ARG_WITH(purify,[  --with-purify           link with purify])
+if test "$with_purify" = yes; then
+  AC_CHECK_PROGS(PURIFY, purify)
+fi
+
+AC_ARG_ENABLE(java, [  --enable-java           compile Java support [[no]]],
+       enable_java=$enableval, enable_java=no)
+if test "$enable_java" = yes; then
+  AC_PATH_PROG(JAVAC, javac, no)
+  AC_PATH_PROGS(JAVAH, javah kaffeh, no)
+  AC_CHECK_PROGS(JAVADOC, javadoc, :)  
+  if test "$JAVAC" = "no" -o "$JAVAH" = "no"; then
+    AC_WARN([Disabling Java support])
+    enable_java=no
+  fi
+else
+# Make distcheck work
+  JAVAC="true"
+  JAVAH="true"
+  JAVADOC="true"
+fi
+AM_CONDITIONAL(JAVA, test "$enable_java" = yes)
+
+if test "$enable_java" = yes; then
+  AC_MSG_CHECKING([JNI cpp flags])
+  AC_CACHE_VAL(sasl_cv_java_includes,[
+  if test `echo $JAVAH | sed 's,.*/,,'` = "kaffeh"; then
+    sasl_cv_java_includes=-I`echo $JAVAH | sed -e 's,/bin.*,/include/kaffe,'`
+  else
+    java_base=`echo $JAVAC | sed 's,/bin.*,'','`
+
+    AC_ARG_WITH(javabase, [  --with-javabase=PATH    set path to find jni.h in [/usr/java/include] ],
+        java_base=$withval,)
+       
+
+    sasl_cv_java_includes=''
+    for dir in `find ${java_base}/include -follow -type d -print | grep -v green_threads`; do
+      sasl_cv_java_includes="${sasl_cv_java_includes} -I$dir"
+    done
+  fi
+
+  sasl_cv_java_includes="${sasl_cv_java_includes} -I$javapath/include"])
+
+  JAVA_INCLUDES=$sasl_cv_java_includes
+  AC_SUBST(JAVA_INCLUDES)
+  AC_MSG_RESULT(ok)
+
+  JAVAROOT=".."
+  AC_SUBST(JAVAROOT)
+  JAVAC=`echo "$JAVAC" | sed 's,.*/,,'`
+  JAVAH=`echo "$JAVAH" | sed 's,.*/,,'`
+fi
+
+AM_CONDITIONAL(SAMPLE, test "$enable_sample" = yes)
+
+dnl call before we do the berkeley DB checks
+CMU_SOCKETS
+
+dnl we extracted this to config/sasldb.m4
+SASL_DB_PATH_CHECK()
+SASL_DB_CHECK()
+
+# Do we not install the SASL DB man pages?
+AM_CONDITIONAL(NO_SASL_DB_MANS, test "x$SASL_DB_MANS" = "x")
+
+AC_ARG_ENABLE(keep_db_open, [  --enable-keep-db-open   keep handle to Berkeley DB open for improved performance [[no]] ],
+                keep_db_open=$enableval,
+                keep_db_open=no)
+
+# Disable if Berkeley DB is not used
+if test "$dblib" != berkeley; then
+  keep_db_open=no
+fi
+
+if test "$keep_db_open" = yes; then
+  AC_DEFINE(KEEP_DB_OPEN,[],[Should we keep handle to Berkeley DB open in SASLDB plugin?])
+fi
+AC_MSG_CHECKING(if Berkeley DB handle is kept open in SASLDB)
+AC_MSG_RESULT($keep_db_open)
+
+AC_CHECK_LIB(dl, dlopen, SASL_DL_LIB="-ldl", SASL_DL_LIB="")
+AC_SUBST(SASL_DL_LIB)
+
+dnl /dev/random ?
+
+AC_ARG_WITH(devrandom, [  --with-devrandom=PATH   set the path to /dev/random [[/dev/random]] ],
+  devrandom=$withval,
+  devrandom=/dev/random)
+AC_MSG_CHECKING(/dev/random to use)
+AC_MSG_RESULT($devrandom)
+AC_DEFINE_UNQUOTED(SASL_DEV_RANDOM, "$devrandom", [File to use for source of randomness])
+
+dnl Do we need leading underscores on our symbols?
+
+AC_CHECK_PROGS(NM, nm)
+
+AC_MSG_CHECKING(for underscore before symbols)
+AC_CACHE_VAL(sasl_cv_uscore,[
+    echo "main(){int i=1;}
+    foo(){int i=6;}" > conftest.c
+    ${CC} -o a.out conftest.c > /dev/null
+    if (${NM} a.out | grep _foo) > /dev/null; then
+      sasl_cv_uscore=yes
+    else
+      sasl_cv_uscore=no
+    fi])
+AC_MSG_RESULT($sasl_cv_uscore)
+rm -f conftest.c a.out
+
+if test $sasl_cv_uscore = yes; then
+  if test $ac_cv_lib_dl_dlopen = yes ; then
+       AC_MSG_CHECKING(whether dlsym adds the underscore for us)
+       cmu_save_LIBS="$LIBS"
+       LIBS="$LIBS $SASL_DL_LIB"
+       AC_CACHE_VAL(sasl_cv_dlsym_adds_uscore,AC_TRY_RUN( [
+#include <dlfcn.h>
+#include <stdio.h>
+foo() { int i=0;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(NULL,RTLD_LAZY);
+    if(self) { ptr1=dlsym(self,"foo"); ptr2=dlsym(self,"_foo");
+    if(ptr1 && !ptr2) exit(0); } exit(1); } 
+], [sasl_cv_dlsym_adds_uscore=yes], sasl_cv_dlsym_adds_uscore=no
+       AC_DEFINE(DLSYM_NEEDS_UNDERSCORE, [], [Do we need a leading _ for dlsym?]),
+       AC_MSG_WARN(cross-compiler, we'll do our best)))
+       LIBS="$cmu_save_LIBS"
+      AC_MSG_RESULT($sasl_cv_dlsym_adds_uscore)
+  fi
+fi
+
+dnl See if we can provide a default logging function...
+AC_CHECK_FUNCS(syslog)
+
+AC_ARG_WITH(pam, [  --with-pam=DIR          use PAM (rooted in DIR) [[yes]] ],
+       with_pam=$withval,
+       with_pam=yes)
+if test "$with_pam" != no; then
+  if test -d $with_pam; then
+    CPPFLAGS="$CPPFLAGS -I${with_pam}/include"
+    LDFLAGS="$LDFLAGS -L${with_pam}/lib"
+  fi
+  AC_CHECK_HEADERS(security/pam_appl.h pam/pam_appl.h)
+  cmu_save_LIBS="$LIBS"
+  AC_CHECK_FUNC(pam_start, :, 
+       LIBS="-lpam $LIBS" 
+       AC_TRY_LINK([[
+#include <sys/types.h>
+#ifdef HAVE_PAM_PAM_APPL_H
+#include <pam/pam_appl.h>
+#endif
+#ifdef HAVE_SECURITY_PAM_H
+#include <security/pam_appl.h>
+#endif]],[[
+const char *service="foo";
+const char *user="bar";
+pam_handle_t *pamh;
+struct pam_conv *conv;
+int baz;
+baz = pam_start(service, user, conv, &pamh);
+return 0;
+]], LIBPAM="-lpam")
+)
+  LIBS="$cmu_save_LIBS $LIBPAM"
+fi
+
+AC_ARG_WITH(saslauthd, [  --with-saslauthd=DIR    enable use of the saslauth daemon using state dir DIR ],
+               with_saslauthd=$withval,
+               with_saslauthd=yes)
+if test "$with_saslauthd" != no; then
+  if test "$with_saslauthd" = yes; then
+    with_saslauthd="/var/state/saslauthd"
+  fi
+  AC_DEFINE(HAVE_SASLAUTHD,[],[Include support for saslauthd?])
+  AC_DEFINE_UNQUOTED(PATH_SASLAUTHD_RUNDIR, "$with_saslauthd",
+                    [Where do we look for saslauthd's socket?])
+fi
+AM_CONDITIONAL(SASLAUTHD, test "$with_saslauthd" != no)
+AC_MSG_CHECKING(if I should include saslauthd)
+AC_MSG_RESULT($with_saslauthd)
+
+AC_ARG_WITH(authdaemond, [  --with-authdaemond=PATH enable use of authdaemon with default socket=PATH [[yes]] ],
+               with_authdaemon=$withval,
+               with_authdaemon=yes)
+if test "$with_authdaemon" != no; then
+  if test "$with_authdaemon" = yes; then
+    with_authdaemon="/dev/null"
+  fi
+  AC_DEFINE(HAVE_AUTHDAEMON,[],[Include support for Courier's authdaemond?])
+  AC_DEFINE_UNQUOTED(PATH_AUTHDAEMON_SOCKET, "$with_authdaemon",
+                    [Where do we look for Courier authdaemond's socket?])
+fi
+AC_MSG_CHECKING(to include Courier authdaemond support)
+AC_MSG_RESULT($with_authdaemon)
+
+AC_ARG_WITH(pwcheck,
+[  --with-pwcheck=DIR     enable deprecated pwcheck daemon using statedir DIR ],
+       with_pwcheck=$withval,
+       with_pwcheck=no)
+if test "$with_pwcheck" != no; then
+   if test "$with_pwcheck" = yes; then
+     with_pwcheck=/var/pwcheck
+   fi
+   AC_DEFINE(HAVE_PWCHECK,[],[Include Support for pwcheck daemon?])
+   AC_DEFINE_UNQUOTED(PWCHECKDIR, "$with_pwcheck", [Location of pwcheck socket])
+   AC_CHECK_FUNC(getspnam,PWCHECKMETH="getspnam",PWCHECKMETH="getpwnam")
+   AC_SUBST(PWCHECKMETH)
+fi
+AM_CONDITIONAL(PWCHECK, test "$with_pwcheck" != no)
+AC_MSG_CHECKING(if I should include pwcheck)
+AC_MSG_RESULT($with_pwcheck)
+
+AC_ARG_WITH(ipctype, [  --with-ipctype={unix,doors}    use ipctype [[unix]] ],
+       with_ipctype=$withval,
+       with_ipctype="unix")
+IPCTYPE=$with_ipctype
+AC_SUBST(IPCTYPE)
+LIB_DOOR=
+if test "$with_ipctype" = "doors"; then
+   LIB_DOOR="-ldoor"
+   AC_DEFINE(USE_DOORS,[],[use the doors IPC API for saslauthd?])
+fi
+AC_SUBST(LIB_DOOR)
+
+AC_ARG_ENABLE(alwaystrue, [  --enable-alwaystrue     enable the alwaystrue password verifier (discouraged)],
+               enable_alwaystrue=$enableval,
+               enable_alwaystrue=no)
+if test "$enable_alwaystrue" = yes; then
+  AC_DEFINE(HAVE_ALWAYSTRUE, [], [Enable 'alwaystrue' password verifier?])
+fi
+AC_MSG_CHECKING(if I should include the alwaystrue verifier)
+AC_MSG_RESULT($enable_alwaystrue)
+
+dnl sasl_checkapop support
+AC_ARG_ENABLE(checkapop, [  --enable-checkapop      enable use of sasl_checkapop [[yes]] ],
+  checkapop=$enableval,
+  checkapop=yes)
+
+AC_MSG_CHECKING(if we should enable sasl_checkapop)
+if test "$checkapop" != no; then
+  AC_MSG_RESULT(enabled)
+  AC_DEFINE(DO_SASL_CHECKAPOP, [], [should we support sasl_checkapop?])
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl CRAM-MD5
+AC_ARG_ENABLE(cram, [  --enable-cram           enable CRAM-MD5 authentication [[yes]] ],
+  cram=$enableval,
+  cram=yes)
+
+AC_MSG_CHECKING(CRAM-MD5)
+if test "$cram" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libcrammd5.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS cram.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/cram.c"
+    AC_DEFINE(STATIC_CRAMMD5, [], [Link CRAM-MD5 Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+CMU_HAVE_OPENSSL
+AC_MSG_CHECKING(for OpenSSL)
+AC_MSG_RESULT($with_openssl)
+
+SASL_DES_CHK
+
+dnl DIGEST-MD5
+AC_ARG_ENABLE(digest, [  --enable-digest         enable DIGEST-MD5 authentication [[yes]] ],
+  digest=$enableval,
+  digest=yes)
+
+if test "$digest" != no; then
+  dnl In order to compile digest, we should look for need libdes.
+  if test -d $digest; then
+    CPPFLAGS="$CPPFLAGS -I$digest/include"
+    LDFLAGS="$LDFLAGS -L$digest/lib"
+  fi
+  if test "$with_des" = no; then
+    AC_WARN(No DES support for DIGEST-MD5)
+  fi
+fi
+
+AC_MSG_CHECKING(DIGEST-MD5)
+if test "$digest" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libdigestmd5.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/digestmd5.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS digestmd5.o"
+    AC_DEFINE(STATIC_DIGESTMD5, [], [Link DIGEST-MD5 Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl OTP
+AC_ARG_ENABLE(otp, [  --enable-otp            enable OTP authentication [[yes]] ],
+  otp=$enableval,
+  otp=yes)
+
+if test "$with_openssl" = no; then
+  AC_WARN([OpenSSL not found -- OTP will be disabled])
+  otp=no
+fi
+
+AC_MSG_CHECKING(OTP)
+if test "$otp" != no; then
+  AC_MSG_RESULT(enabled)
+  OTP_LIBS="-lcrypto $LIB_RSAREF"
+
+  SASL_MECHS="$SASL_MECHS libotp.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/otp.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS otp.o"
+    AC_DEFINE(STATIC_OTP, [], [Link OTP Staticly])
+  fi
+
+  dnl Test for OPIE
+  AC_ARG_WITH(with-opie,[  --with-opie=PATH        use OPIE (One Time Passwords in Everything) from PATH],
+       with_opie="${withval}")
+
+  case "$with_opie" in
+       ""|yes) 
+               AC_CHECK_LIB(opie, opiechallenge, [
+                       AC_CHECK_HEADER(opie.h, with_opie="yes",
+                                       with_opie="no")],
+                       with_opie="no")
+               ;;
+       *)
+               if test -d $with_opie; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_opie}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_opie}/lib"
+               else
+                 with_opie="no"
+               fi
+               ;;
+  esac
+
+  AC_MSG_CHECKING(for OPIE)
+  AC_MSG_RESULT($with_opie)
+
+  if test "$with_opie" != no; then
+    AC_DEFINE(HAVE_OPIE,[],[Use OPIE for server-side OTP?])
+    OTP_LIBS="$OTP_LIBS -lopie"
+  fi
+
+  AC_SUBST(OTP_LIBS)
+
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl SRP
+AC_ARG_ENABLE(srp, [  --enable-srp            enable SRP authentication [[no]] ],
+  srp=$enableval,
+  srp=no)
+
+if test "$with_openssl" = no; then
+  AC_WARN([OpenSSL not found -- SRP will be disabled])
+  srp=no
+fi
+
+AC_MSG_CHECKING(SRP)
+if test "$srp" != no; then
+  AC_MSG_RESULT(enabled)
+  SRP_LIBS="-lcrypto $LIB_RSAREF"
+
+  SASL_MECHS="$SASL_MECHS libsrp.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/srp.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS srp.o"
+    AC_DEFINE(STATIC_SRP, [], [Link SRP Staticly])
+  fi
+
+dnl srp_setpass support
+  AC_ARG_ENABLE(srp_setpass, [  --enable-srp-setpass    enable setting SRP secrets with saslpasswd [[no]]],
+      srp_setpass=$enableval,
+      srp_setpass=no)
+
+  AC_MSG_CHECKING(if we should enable setting SRP secrets with saslpasswd)
+  if test "$srp_setpass" != no; then
+    AC_MSG_RESULT(enabled)
+    AC_DEFINE(DO_SRP_SETPASS, [], [should we support setpass() for SRP?])
+  else
+    AC_MSG_RESULT(disabled)
+  fi
+
+  AC_SUBST(SRP_LIBS)
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl Kerberos based Mechanisms
+SASL_KERBEROS_V4_CHK
+SASL_GSSAPI_CHK
+
+if test "$gssapi" != "no"; then
+  AC_DEFINE(STATIC_GSSAPIV2,[],[Link GSSAPI Staticly])
+  mutex_default="no"
+  if test "$gss_impl" = "mit"; then
+     mutex_default="yes"
+  fi
+  AC_MSG_CHECKING(to use mutexes aroung GSS calls)
+  AC_ARG_ENABLE(gss_mutexes, [  --enable-gss_mutexes     use mutexes around calls to the GSS library],
+                use_gss_mutexes=$enableval,
+                use_gss_mutexes=$mutex_default)
+  if test $use_gss_mutexes = "yes"; then
+     AC_DEFINE(GSS_USE_MUTEXES, [], [should we mutex-wrap calls into the GSS library?])
+  fi
+  AC_MSG_RESULT($use_gss_mutexes)
+fi
+
+dnl PLAIN
+SASL_PLAIN_CHK
+
+dnl ANONYMOUS
+AC_ARG_ENABLE(anon, [  --enable-anon           enable ANONYMOUS authentication [[yes]] ],
+  anon=$enableval,
+  anon=yes)
+
+AC_MSG_CHECKING(ANONYMOUS)
+if test "$anon" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libanonymous.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS anonymous.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/anonymous.c"
+    AC_DEFINE(STATIC_ANONYMOUS, [], [Link ANONYMOUS Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl LOGIN
+AC_ARG_ENABLE(login, [  --enable-login          enable unsupported LOGIN authentication [[no]] ],
+  login=$enableval,
+  login=no)
+
+AC_MSG_CHECKING(LOGIN)
+if test "$login" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS liblogin.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/login.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS login.o"
+    AC_DEFINE(STATIC_LOGIN,[],[Link LOGIN Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl NTLM
+AC_ARG_ENABLE(ntlm, [  --enable-ntlm           enable unsupported NTLM authentication [[no]] ],
+  ntlm=$enableval,
+  ntlm=no)
+
+if test "$with_openssl" = no; then
+  AC_WARN([OpenSSL not found -- NTLM will be disabled])
+  ntlm=no
+fi
+
+AC_MSG_CHECKING(NTLM)
+if test "$ntlm" != no; then
+  AC_MSG_RESULT(enabled)
+  NTLM_LIBS="-lcrypto $LIB_RSAREF"
+  AC_SUBST(NTLM_LIBS)
+
+  SASL_MECHS="$SASL_MECHS libntlm.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/ntlm.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS ntlm.o"
+    AC_DEFINE(STATIC_NTLM,[],[Link NTLM Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl PASSDSS
+AC_ARG_ENABLE(passdss, [  --enable-passdss        enable PASSDSS authentication (experimental) [[no]] ],
+  passdss=$enableval,
+  passdss=no)
+
+if test "$with_openssl" = no; then
+  AC_WARN([OpenSSL not found -- PASSDSS will be disabled])
+  passdss=no
+fi
+
+AC_MSG_CHECKING(PASSDSS)
+if test "$passdss" != no; then
+  AC_MSG_RESULT(enabled)
+  PASSDSS_LIBS="-lcrypto $LIB_RSAREF"
+  AC_SUBST(PASSDSS_LIBS)
+
+  SASL_MECHS="$SASL_MECHS libpassdss.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS passdss.o"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/passdss.c"
+    AC_DEFINE(STATIC_PASSDSS,[],[Link PASSDSS Staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+
+# make the option show up so people don't whine that it is only in the
+# saslauthd configure script --help
+AC_ARG_WITH(ldap,   [  --with-ldap=DIR         use LDAP (in DIR) for saslauthd [no] ],,with_ldap=no)
+
+
+dnl SQL
+dnl This flag also changes the requirements of --with-mysql and --with-pgsql
+dnl
+dnl Desired behavior:
+dnl
+dnl doesn't require mysql or postgres if --disable-sql is chosen
+dnl requires at least one (but not both) if --enable-sql is chosen
+
+AC_ARG_ENABLE(sql, [  --enable-sql            enable SQL auxprop [[no]] ],
+  sql=$enableval,
+  sql=no)
+
+AC_MSG_CHECKING(SQL)
+if test "$sql" != no; then
+  AC_MSG_RESULT(enabled)
+  SASL_MECHS="$SASL_MECHS libsql.la"
+  if test "$enable_static" = yes; then
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sql.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS sql.o"
+    AC_DEFINE(STATIC_SQL,[],[Link SQL plugin staticly])
+  fi
+else
+  AC_MSG_RESULT(disabled)
+fi
+
+dnl MySQL
+AC_ARG_WITH(mysql,  [  --with-mysql=PATH       use MySQL from PATH ],
+  with_mysql=$withval,
+  with_mysql=$sql)
+
+# find location of library 
+# presuming if one given then correct
+if test "${with_mysql}" = "yes"; then
+  with_mysql=notfound
+  for mysqlloc in lib/mysql lib mysql/lib
+  do
+    if test -f ${prefix}/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="${prefix}"
+      break
+    elif test -f /usr/local/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="/usr/local"
+      break
+    elif test -f /usr/${mysqlloc}/libmysqlclient.a; then
+      with_mysql="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_MYSQL=""
+
+case "$with_mysql" in
+    no) true;;
+    notfound) AC_WARN([MySQL Library not found]); true;;
+    *)
+     if test -d ${with_mysql}/lib/mysql; then
+       CMU_ADD_LIBPATH_TO(${with_mysql}/lib/mysql, LIB_MYSQL)
+     elif test -d ${with_mysql}/mysql/lib; then
+       CMU_ADD_LIBPATH_TO(${with_mysql}/mysql/lib, LIB_MYSQL)
+     elif test -d ${with_mysql}/lib; then
+       CMU_ADD_LIBPATH_TO(${with_mysql}/lib, LIB_MYSQL)
+     else
+       CMU_ADD_LIBPATH_TO(${with_mysql}, LIB_MYSQL)
+     fi
+
+     LIB_MYSQL_DIR=$LIB_MYSQL
+     LIB_MYSQL="$LIB_MYSQL -lmysqlclient"
+
+     if test -d ${with_mysql}/include/mysql; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/include/mysql"
+     elif test -d ${with_mysql}/mysql/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/mysql/include"
+     elif test -d ${with_mysql}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_mysql}"
+     fi
+
+       save_LDFLAGS=$LDFLAGS
+       LDFLAGS="$LDFLAGS $LIB_MYSQL_DIR"
+       AC_CHECK_LIB(mysqlclient, mysql_select_db,
+          AC_DEFINE(HAVE_MYSQL, [], [Do we have mysql support?]),
+           [AC_WARN([MySQL library mysqlclient does not work])
+           with_mysql=no])
+       LDFLAGS=$save_LDFLAGS;;
+         
+esac
+AC_SUBST(LIB_MYSQL)
+
+dnl PgSQL
+AC_ARG_WITH(pgsql,  [  --with-pgsql=PATH       use PostgreSQL from PATH ],
+  with_pgsql=$withval,
+  with_pgsql=$sql)
+
+# find location of library 
+# presuing if one given then correct
+if test "${with_pgsql}" = "yes"; then
+  with_pgsql=notfound
+  for pgsqlloc in lib/pgsql lib pgsql/lib
+  do
+    if test -f ${prefix}/${pgsqlloc}/libpq.a; then
+      with_pgsql="${prefix}"
+      break
+    elif test -f /usr/local/${pgsqlloc}/libpq.a; then
+      with_pgsql="/usr/local"
+      break
+    elif test -f /usr/${pgsqlloc}/libpq.a; then
+      with_pgsql="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_PGSQL=""
+
+case "$with_pgsql" in
+    no) true;;
+    notfound) AC_WARN([PostgreSQL Library not found]); true;;
+    *)
+     if test -d ${with_pgsql}/lib/pgsql; then
+       CMU_ADD_LIBPATH_TO(${with_pgsql}/lib/pgsql, LIB_PGSQL)
+     elif test -d ${with_pgsql}/pgsql/lib; then
+       CMU_ADD_LIBPATH_TO(${with_pgsql}/pgsql/lib, LIB_PGSQL)
+     elif test -d ${with_pgsql}/lib; then
+       CMU_ADD_LIBPATH_TO(${with_pgsql}/lib, LIB_PGSQL)
+     else
+       CMU_ADD_LIBPATH_TO(${with_pgsql}, LIB_PGSQL)
+     fi
+
+     LIB_PGSQL_DIR=$LIB_PGSQL
+     LIB_PGSQL="$LIB_PGSQL -lpq"
+
+     if test -d ${with_pgsql}/include/pgsql; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/include/pgsql"
+     elif test -d ${with_pgsql}/pgsql/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/pgsql/include"
+     elif test -d ${with_pgsql}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_pgsql}"
+     fi
+
+
+       save_LDFLAGS=$LDFLAGS
+       LDFLAGS="$LDFLAGS $LIB_PGSQL_DIR"
+       AC_CHECK_LIB(pq, PQsetdbLogin, AC_DEFINE(HAVE_PGSQL,[],
+          [Do we have Postgres support?]),
+           [AC_WARN([PostgreSQL Library pq does not work])
+           with_pgsql=no])
+       LDFLAGS=$save_LDFLAGS;;
+         
+esac
+AC_SUBST(LIB_PGSQL)
+
+dnl SQLite
+AC_ARG_WITH(sqlite,  [  --with-sqlite=PATH       use SQLite from PATH ],
+  with_sqlite=$withval,
+  with_sqlite=$sql)
+
+# find location of library 
+# presuing if one given then correct
+if test "${with_sqlite}" = "yes"; then
+  with_sqlite=notfound
+  for sqliteloc in lib
+  do
+    if test -f ${prefix}/${sqliteloc}/libsqlite.a; then
+      with_sqlite="${prefix}"
+      break
+    elif test -f /usr/local/${sqliteloc}/libsqlite.a; then
+      with_sqlite="/usr/local"
+      break
+    elif test -f /usr/${sqliteloc}/libsqlite.a; then
+      with_sqlite="/usr"
+      break
+    fi
+  done
+fi
+
+LIB_SQLITE=""
+
+case "$with_sqlite" in
+    no) true;;
+    notfound) AC_WARN([SQLite Library not found]); true;;
+    *)
+     if test -d ${with_sqlite}/lib; then
+         LIB_SQLITE="-L${with_sqlite}/lib -R${with_sqlite}/lib"
+     else
+         LIB_SQLITE="-L${with_sqlite} -R${with_sqlite}"
+     fi
+
+     LIB_SQLITE_DIR=$LIB_SQLITE
+     LIB_SQLITE="$LIB_SQLITE -lsqlite"
+
+     if test -d ${with_sqlite}/include; then
+         CPPFLAGS="${CPPFLAGS} -I${with_sqlite}/include"
+     else
+         CPPFLAGS="${CPPFLAGS} -I${with_sqlite}"
+     fi
+       AC_CHECK_LIB(sqlite, sqlite_open, AC_DEFINE(HAVE_SQLITE,[],
+          [Do we have SQLite support?]),
+           [AC_WARN([SQLite Library sqlite does not work])
+           with_sqlite=no], $LIB_SQLITE_DIR);;
+         
+esac
+AC_SUBST(LIB_SQLITE)
+
+if test "$sql" = yes -a "$with_pgsql" = no -a "$with_mysql" = no -a "$with_sqlite" = no; then
+    AC_ERROR([--enable-sql chosen but neither Postgres nor MySQL nor SQLite found])
+fi
+
+if test "$enable_shared" = yes; then
+       AC_DEFINE(DO_DLOPEN,[],[Should we build a shared plugin (via dlopen) library?])
+fi
+
+dnl LDAPDB
+AC_ARG_ENABLE(ldapdb, [  --enable-ldapdb         enable LDAPDB plugin [no] ],
+  ldapdb=$enableval,
+  ldapdb=no)
+AC_MSG_CHECKING(LDAPDB)
+if test "$ldapdb" != no; then
+    AC_MSG_RESULT(enabled)
+
+    if test "$with_ldap" = no; then
+        AC_MSG_ERROR([Cannot enable LDAPDB plugin: You need to specify --with-ldap])
+    fi
+
+    save_CPPFLAGS=$CPPFLAGS
+    save_LDFLAGS=$LDFLAGS
+
+    if test -d $with_ldap; then
+        CPPFLAGS="${CPPFLAGS} -I${with_ldap}/include"
+        CMU_ADD_LIBPATH(${with_ldap}/lib)
+    fi
+
+    AC_CHECK_HEADERS(ldap.h lber.h)
+
+    if test $ac_cv_header_ldap_h = yes -a $ac_cv_header_lber_h = yes; then
+        CMU_OPENLDAP_API
+
+        if test "$cmu_cv_openldap_api" = yes; then
+            AC_CHECK_LIB(ldap, ldap_initialize, [ cmu_link_openldap="-lldap -llber" ], [ cmu_link_openldap=no ],-llber)
+        fi
+    fi
+
+    if test "$cmu_cv_openldap_api" = no -o "$cmu_link_openldap" = no; then
+        AC_MSG_ERROR([Cannot enable LDAPDB plugin: Could not locate OpenLDAP])
+    else
+        CMU_OPENLDAP_COMPAT
+
+        if test "$cmu_cv_openldap_compat" = no; then
+            AC_MSG_ERROR([Cannot enable LDAPDB plugin: OpenLDAP library located but incompatible])
+        else
+            LIB_LDAP=$cmu_link_openldap
+            AC_SUBST(LIB_LDAP)
+
+            SASL_MECHS="$SASL_MECHS libldapdb.la"
+            if test "$enable_static" = yes; then
+                SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/ldapdb.c"
+                SASL_STATIC_OBJS="$SASL_STATIC_OBJS ldapdb.o"
+                AC_DEFINE(STATIC_LDAPDB,[],[Link ldapdb plugin Staticly])
+            fi
+        fi
+    fi
+
+    if test "$cmu_cv_openldap_compat" != yes; then
+        CPPFLAGS=$save_CPPFLAGS
+        LDFLAGS=$save_LDFLAGS
+    fi
+else
+    AC_MSG_RESULT(disabled)
+fi
+
+AC_SUBST(SASL_MECHS)
+AC_SUBST(SASL_STATIC_SRCS)
+AC_SUBST(SASL_STATIC_OBJS)
+AC_SUBST(SASL_STATIC_LIBS)
+
+AC_ARG_WITH(plugindir, [  --with-plugindir=DIR    set the directory where plugins will
+                          be found [[/usr/lib/sasl2]] ],
+  plugindir=$withval,
+  plugindir=/usr/lib/sasl2)
+AC_DEFINE_UNQUOTED(PLUGINDIR, "$plugindir", [Runtime plugin location])
+AC_SUBST(plugindir)
+
+AC_ARG_WITH(configdir, [   --with-configdir=DIR    set the directory where config files will
+                          be found [/usr/lib/sasl2] ],
+  configdir=$withval,
+  configdir=$plugindir:/etc/sasl2)
+AC_DEFINE_UNQUOTED(CONFIGDIR, "$configdir", [Runtime config file location])
+AC_SUBST(configdir)
+
+dnl look for rc4 libraries. we accept the CMU one or one from openSSL
+AC_ARG_WITH(rc4, [  --with-rc4              use internal rc4 routines [[yes]] ],
+       with_rc4=$withval,
+       with_rc4=yes)
+
+if test "$with_rc4" != no; then
+    AC_DEFINE(WITH_RC4,[],[Use internal RC4 implementation?])
+fi
+
+building_for_macosx=no
+case "$host_os" in
+        darwin*)
+AC_ARG_ENABLE(macos-framework, [  --disable-macos-framework       disable building and installing replacement SASL2 Framework for MacOS X-provided SASL Framework [[no]]],building_for_macosx=no,building_for_macosx=yes)
+        ;;
+esac
+AM_CONDITIONAL(MACOSX, test "$building_for_macosx" = yes)
+
+dnl dmalloc tests
+AC_MSG_CHECKING(for dmalloc library)
+AC_ARG_WITH(dmalloc, [  --with-dmalloc=DIR      with DMALLOC support (for test applications) [[no]] ],
+       with_dmalloc=$withval,
+       with_dmalloc=no)
+
+DMALLOC_LIBS=""
+
+if test "$with_dmalloc" != "no"; then
+   if test "$with_dmalloc" = "yes"; then
+       with_dmalloc="/usr/local"
+   fi
+
+   if test -r "$with_dmalloc/libdmalloc.a"; then
+       DMALLOC_LIBS="$with_dmalloc/libdmalloc.a"
+       AC_DEFINE(WITH_DMALLOC,[],[Linking against dmalloc?])
+       AC_MSG_RESULT(yes)
+   elif test -r "$with_dmalloc/lib/libdmalloc.a"; then
+       DMALLOC_LIBS="$with_dmalloc/lib/libdmalloc.a"
+       AC_DEFINE(WITH_DMALLOC,[],[Linking against dmalloc?])
+       AC_MSG_RESULT(yes)
+   else
+       AC_MSG_ERROR(cannot find dmalloc library, please check your installation.)
+   fi
+else
+   AC_MSG_RESULT(no)
+fi
+
+AC_SUBST(DMALLOC_LIBS)
+
+dnl sfio tests
+AC_MSG_CHECKING(for sfio library)
+AC_ARG_WITH(sfio, [  --with-sfio=DIR         with SFIO support (for smtptest/libsfsasl) [[no]] ],
+       with_sfio=$withval,
+       with_sfio=no)
+
+if test "$with_sfio" != "no"; then
+   if test "$with_sfio" = "yes"; then
+       with_sfio="/usr/local"
+   fi
+
+   AC_DEFUN([SFIO_INC_CHK],
+       [if test -r "$with_sfio$1/sfio.h"; then SFIO_DIR=$with_sfio;
+                                             SFIO_INC_DIR=$with_sfio$1])
+
+   AC_DEFUN([SFIO_LIB_CHK],[
+               str="$SFIO_DIR/$1/libsfio.*"
+               for i in `echo $str`; do
+                       if test -r $i; then
+                               SFIO_LIBDIR=$SFIO_DIR/$1
+                               break 2
+                       fi
+               done
+               ])
+
+   SFIO_INC_CHK()
+   el[]SFIO_INC_CHK(/include)
+   el[]SFIO_INC_CHK(/include/sfio)
+   fi
+
+   if test -z "$SFIO_DIR"; then
+       AC_MSG_ERROR(Cannot find sfio.h, Please check your SFIO installation.)
+   fi
+
+   SFIO_LIB_CHK(lib)
+   SFIO_LIB_CHK(lib/sfio)
+
+   if test -z "$SFIO_LIBDIR"; then
+       AC_MSG_ERROR(Cannot find sfio library, Please check your SFIO installation.)
+   fi
+
+   SFIO_INC_FLAGS="-I$SFIO_INC_DIR"
+   SFIO_LIB_FLAGS="-L$SFIO_LIBDIR -lsfio"
+   SMTPTEST_PROGRAM="smtptest"
+   SASL_UTIL_LIBS_EXTRA=libsfsasl2.la
+   SASL_UTIL_HEADERS_EXTRA=sfsasl.h
+
+   AC_MSG_RESULT(yes)
+else
+   AC_MSG_RESULT(no)
+   SFIO_INC_FLAGS=""
+   SFIO_LIB_FLAGS=""
+   SMTPTEST_PROGRAM=""
+   SASL_UTIL_LIBS_EXTRA=""
+   SASL_UTIL_HEADERS_EXTRA=""
+fi
+
+AC_SUBST(SFIO_INC_FLAGS)
+AC_SUBST(SFIO_LIB_FLAGS)
+AC_SUBST(SMTPTEST_PROGRAM)
+AC_SUBST(SASL_UTIL_LIBS_EXTRA)
+AC_SUBST(SASL_UTIL_HEADERS_EXTRA)
+
+dnl check for getsubopt
+sasl_cv_getsubopt=no
+AC_CHECK_FUNC(getsubopt, [AC_DEFINE(HAVE_GETSUBOPT,[],
+       [do we have getsubopt()?])], [sasl_cv_getsubopt=yes])
+if test $sasl_cv_getsubopt = yes; then
+       AC_LIBOBJ(getsubopt)
+       GETSUBOPT="getsubopt.lo"
+fi
+AC_SUBST(GETSUBOPT)
+
+dnl Check for snprintf
+sasl_cv_snprintf=no
+SNPRINTFOBJS=""
+AC_CHECK_FUNC(snprintf, [AC_DEFINE(HAVE_SNPRINTF,[],[Does the system have snprintf()?])], [sasl_cv_snprintf=yes])
+AC_CHECK_FUNC(vsnprintf, [AC_DEFINE(HAVE_VSNPRINTF,[],[Does the system have vsnprintf()?])], [sasl_cv_snprintf=yes])
+if test $sasl_cv_snprintf = yes; then
+       AC_LIBOBJ(snprintf)
+        SNPRINTFOBJS="snprintf.o"
+        LTSNPRINTFOBJS="snprintf.lo"
+fi
+AC_SUBST(SNPRINTFOBJS)
+AC_SUBST(LTSNPRINTFOBJS)
+
+dnl do we need to link in -lresolv?
+AC_CHECK_LIB(resolv, inet_aton)
+
+dnl Check for getaddrinfo
+GETADDRINFOOBJS=""
+sasl_cv_getaddrinfo=yes
+IPv6_CHECK_FUNC(getaddrinfo, [IPv6_CHECK_FUNC(gai_strerror,
+                [AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo() function?])
+                sasl_cv_getaddrinfo=no])])
+if test $sasl_cv_getaddrinfo = yes; then
+    AC_LIBOBJ(getaddrinfo)
+    GETADDRINFOOBJS="getaddrinfo.o"
+    LTGETADDRINFOOBJS="getaddrinfo.lo"
+fi
+AC_SUBST(GETADDRINFOOBJS)
+AC_SUBST(LTGETADDRINFOOBJS)
+
+dnl Check for getnameinfo
+GETNAMEINFOOBJS=""
+sasl_cv_getnameinfo=no
+IPv6_CHECK_FUNC(getnameinfo,
+               [AC_DEFINE(HAVE_GETNAMEINFO,[],[Do we have a getnameinfo() function?])], [sasl_cv_getnameinfo=yes])
+if test $sasl_cv_getnameinfo = yes; then
+       AC_LIBOBJ(getnameinfo)
+        GETNAMEINFOOBJS="getnameinfo.o"
+        LTGETNAMEINFOOBJS="getnameinfo.lo"
+fi
+AC_SUBST(GETNAMEINFOOBJS)
+AC_SUBST(LTGETNAMEINFOOBJS)
+
+LTLIBOBJS=`echo "$LIB@&t@OBJS" | sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
+AC_SUBST(LTLIBOBJS)
+
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_MODE_T
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+
+AC_HEADER_TIME
+AC_HEADER_STDC
+AC_HEADER_DIRENT
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(des.h dlfcn.h fcntl.h limits.h malloc.h paths.h strings.h sys/file.h sys/time.h syslog.h unistd.h inttypes.h sys/uio.h sys/param.h sysexits.h stdarg.h varargs.h)
+
+IPv6_CHECK_SS_FAMILY()
+IPv6_CHECK_SA_LEN()
+IPv6_CHECK_SOCKLEN_T()
+
+#AC_FUNC_MEMCMP
+#AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(gethostname getdomainname getpwnam getspnam gettimeofday inet_aton memcpy mkdir select socket strchr strdup strerror strspn strstr strtol jrand48)
+
+if test $enable_cmulocal = yes; then
+    AC_WARN([enabling CMU local kludges])
+    AC_DEFINE(KRB4_IGNORE_IP_ADDRESS,[],[Ignore IP Address in Kerberos 4 tickets?])
+    AC_DEFINE_UNQUOTED(PREFER_MECH, "KERBEROS_V4", [Force a preferred mechanism])
+fi
+
+AC_EGREP_HEADER(sockaddr_storage, sys/socket.h, [
+               AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE,[],[Do we have struct sockaddr_stroage?])])
+
+AC_SUBST(DIRS)
+
+AC_CONFIG_SUBDIRS(saslauthd)
+
+AH_TOP([
+/* acconfig.h - autoheader configuration input */
+/* 
+ * 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
+])
+
+AH_BOTTOM([
+
+
+/* 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/types.h>
+#include <sys/uio.h>
+#endif
+
+/* location of the random number generator */
+#ifdef DEV_RANDOM
+#undef DEV_RANDOM
+#endif
+#define DEV_RANDOM SASL_DEV_RANDOM
+
+/* 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"
+#define SASL_CONF_PATH_ENV_VAR "SASL_CONF_PATH"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef WIN32
+# include <netdb.h>
+# ifdef HAVE_SYS_PARAM_H
+#  include <sys/param.h>
+# endif
+#else /* WIN32 */
+# include <winsock2.h>
+#endif /* WIN32 */
+#include <string.h>
+
+#include <netinet/in.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#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        gai_strerror    sasl_gai_strerror
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+#define        getnameinfo     sasl_getnameinfo
+#endif
+
+#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO)
+#include "gai.h"
+#endif
+
+#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
+#define AI_NUMERICHOST  4
+#define NI_NUMERICHOST  2
+#define NI_NAMEREQD     4
+#define NI_NUMERICSERV  8
+#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
+
+/* 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
+
+#ifndef HIER_DELIMITER
+#define HIER_DELIMITER '/'
+#endif
+
+#endif /* CONFIG_H */
+])
+
+AC_CONFIG_HEADERS(config.h)
+
+AC_OUTPUT(Makefile
+include/Makefile
+sasldb/Makefile
+plugins/Makefile
+lib/Makefile
+utils/Makefile
+doc/Makefile
+sample/Makefile
+java/Makefile
+java/CyrusSasl/Makefile
+java/Test/Makefile
+java/javax/Makefile
+java/javax/security/Makefile
+java/javax/security/auth/Makefile
+java/javax/security/auth/callback/Makefile
+pwcheck/Makefile
+man/Makefile)
+
+echo Configuration Complete.  Type \'make\' to build.
diff --git a/dlcompat-20010505/APPLE_LICENSE b/dlcompat-20010505/APPLE_LICENSE
new file mode 100644 (file)
index 0000000..84687a4
--- /dev/null
@@ -0,0 +1,372 @@
+APPLE PUBLIC SOURCE LICENSE
+Version 1.1 - April 19,1999
+
+Please read this License carefully before downloading this software.
+By downloading and using this software, you are agreeing to be bound
+by the terms of this License.  If you do not or cannot agree to the
+terms of this License, please do not download or use the software.
+
+1. General; Definitions.  This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") publicly announces as
+subject to this Apple Public Source License and which contains a
+notice placed by Apple identifying such program or work as "Original
+Code" and stating that it is subject to the terms of this Apple Public
+Source License version 1.1 (or subsequent version thereof), as it may
+be revised from time to time by Apple ("License").  As used in this
+License:
+
+1.1 "Affected Original Code" means only those specific portions of
+Original Code that allegedly infringe upon any party's intellectual
+property rights or are otherwise the subject of a claim of
+infringement.
+
+1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Deploy" means to use, sublicense or distribute Covered Code other
+than for Your internal research and development (R&D), and includes
+without limitation, any and all internal use or distribution of
+Covered Code within Your business or organization except for R&D use,
+as well as direct or indirect sublicensing or distribution of Covered
+Code by You to any third party in any form or manner.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of Covered Code.  When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License.  For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions.  Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non- exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 You may use, copy, modify and distribute Original Code, with or
+without Modifications, solely for Your internal research and
+development, provided that You must in each instance:
+
+(a) retain and reproduce in all copies of Original Code the copyright
+and other proprietary notices and disclaimers of Apple as they appear
+in the Original Code, and keep intact all notices in the Original Code
+that refer to this License;
+
+(b) include a copy of this License with every copy of Source Code of
+Covered Code and documentation You distribute, and You may not offer
+or impose any terms on such Source Code that alter or restrict this
+License or the recipients' rights hereunder, except as permitted under
+Section 6; and
+
+(c) completely and accurately document all Modifications that you have
+made and the date of each such Modification, designate the version of
+the Original Code you used, prominently include a file carrying such
+information with the Modifications, and duplicate the notice in
+Exhibit A in each file of the Source Code of all such Modifications.
+
+2.2 You may Deploy Covered Code, provided that You must in each
+  instance:
+
+(a) satisfy all the conditions of Section 2.1 with respect to the
+Source Code of the Covered Code;
+
+(b) make all Your Deployed Modifications publicly available in Source
+Code form via electronic distribution (e.g. download from a web site)
+under the terms of this License and subject to the license grants set
+forth in Section 3 below, and any additional terms You may choose to
+offer under Section 6.  You must continue to make the Source Code of
+Your Deployed Modifications available for as long as you Deploy the
+Covered Code or twelve (12) months from the date of initial
+Deployment, whichever is longer;
+
+(c) if You Deploy Covered Code containing Modifications made by You,
+inform others of how to obtain those Modifications by filling out and
+submitting the information found at
+http://www.apple.com/publicsource/modifications.html, if available;
+and
+
+(d) if You Deploy Covered Code in object code, executable form only,
+include a prominent notice, in the code itself as well as in related
+documentation, stating that Source Code of the Covered Code is
+available under the terms of this License with information on how and
+where to obtain such Source Code.
+
+3. Your Grants.  In consideration of, and as a condition to, the
+licenses granted to You under this License:
+
+(a) You hereby grant to Apple and all third parties a non-exclusive,
+royalty-free license, under Your Applicable Patent Rights and other
+intellectual property rights owned or controlled by You, to use,
+reproduce, modify, distribute and Deploy Your Modifications of the
+same scope and extent as Apple's licenses under Sections 2.1 and 2.2;
+and
+
+(b) You hereby grant to Apple and its subsidiaries a non-exclusive,
+worldwide, royalty-free, perpetual and irrevocable license, under Your
+Applicable Patent Rights and other intellectual property rights owned
+or controlled by You, to use, reproduce, execute, compile, display,
+perform, modify or have modified (for Apple and/or its subsidiaries),
+sublicense and distribute Your Modifications, in any form, through
+multiple tiers of distribution.
+
+4. Larger Works.  You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product.  In each such
+instance, You must make sure the requirements of this License are
+fulfilled for the Covered Code or any portion thereof.
+
+5. Limitations on Patent License.  Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein.  Modifications and/or Larger Works may require
+additional patent licenses from Apple which Apple may grant in its
+sole discretion.
+
+6. Additional Terms.  You may choose to offer, and to charge a fee
+for, warranty, support, indemnity or liability obligations and/or
+other rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered
+Code. However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple. You must obtain the
+recipient's agreement that any such Additional Terms are offered by
+You alone, and You hereby agree to indemnify, defend and hold Apple
+harmless for any liability incurred by or claims asserted against
+Apple by reason of any such Additional Terms.
+
+7. Versions of the License.  Apple may publish revised and/or new
+versions of this License from time to time.  Each version will be
+given a distinguishing version number.  Once Original Code has been
+published under a particular version of this License, You may continue
+to use it under the terms of that version. You may also choose to use
+such Original Code under the terms of any subsequent version of this
+License published by Apple.  No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT.  The Original Code may contain in whole or
+in part pre-release, untested, or not fully tested works.  The
+Original Code may contain errors that could cause failures or loss of
+data, and may be incomplete or contain inaccuracies.  You expressly
+acknowledge and agree that use of the Original Code, or any portion
+thereof, is at Your sole and entire risk.  THE ORIGINAL CODE IS
+PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND
+AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND
+9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS
+"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+RIGHTS.  APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE
+ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
+THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT
+DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED.  NO ORAL OR WRITTEN
+INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED
+REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE
+SCOPE OF THIS WARRANTY.  You acknowledge that the Original Code is not
+intended for use in the operation of nuclear facilities, aircraft
+navigation, communication systems, or air traffic control machines in
+which case the failure of the Original Code could lead to death,
+personal injury, or severe physical or environmental damage.
+
+9. Liability.
+
+9.1 Infringement.  If any portion of, or functionality implemented by,
+the Original Code becomes the subject of a claim of infringement,
+Apple may, at its option: (a) attempt to procure the rights necessary
+for Apple and You to continue using the Affected Original Code; (b)
+modify the Affected Original Code so that it is no longer infringing;
+or (c) suspend Your rights to use, reproduce, modify, sublicense and
+distribute the Affected Original Code until a final determination of
+the claim is made by a court or governmental administrative agency of
+competent jurisdiction and Apple lifts the suspension as set forth
+below.  Such suspension of rights will be effective immediately upon
+Apple's posting of a notice to such effect on the Apple web site that
+is used for implementation of this License.  Upon such final
+determination being made, if Apple is legally able, without the
+payment of a fee or royalty, to resume use, reproduction,
+modification, sublicensing and distribution of the Affected Original
+Code, Apple will lift the suspension of rights to the Affected
+Original Code by posting a notice to such effect on the Apple web site
+that is used for implementation of this License.  If Apple suspends
+Your rights to Affected Original Code, nothing in this License shall
+be construed to restrict You, at Your option and subject to applicable
+law, from replacing the Affected Original Code with non-infringing
+code or independently negotiating for necessary rights from such third
+party.
+
+9.2 LIMITATION OF LIABILITY.  UNDER NO CIRCUMSTANCES SHALL APPLE BE
+LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO
+USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY
+OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY
+OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF
+ANY REMEDY.  In no event shall Apple's total liability to You for all
+damages under this License exceed the amount of fifty dollars
+($50.00).
+
+10. Trademarks.  This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac
+OS X Server" or any other trademarks or trade names belonging to Apple
+(collectively "Apple Marks") and no Apple Marks may be used to endorse
+or promote products derived from the Original Code other than as
+permitted by and in strict compliance at all times with Apple's third
+party trademark usage guidelines which are posted at
+http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership.  Apple retains all rights, title and interest in and to
+the Original Code and any Modifications made by or on behalf of Apple
+("Apple Modifications"), and such Apple Modifications will not be
+automatically subject to this License.  Apple may, at its sole
+discretion, choose to license such Apple Modifications under this
+License, or on different terms from those contained in this License or
+may choose not to license them at all.  Apple's development, use,
+reproduction, modification, sublicensing and distribution of Covered
+Code will not be subject to this License.
+
+12. Termination.
+
+12.1 Termination.  This License and the rights granted hereunder will
+   terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach; (b) immediately in the event of
+the circumstances described in Section 13.5(b); or (c) automatically
+without notice from Apple if You, at any time during the term of this
+License, commence an action for patent infringement against Apple.
+
+12.2 Effect of Termination.  Upon termination, You agree to
+immediately stop any further use, reproduction, modification,
+sublicensing and distribution of the Covered Code and to destroy all
+copies of the Covered Code that are in your possession or control.
+All sublicenses to the Covered Code which have been properly granted
+prior to termination shall survive any termination of this License.
+Provisions which, by their nature, should remain in effect beyond the
+termination of this License shall survive, including but not limited
+to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13.  Neither party will be
+liable to the other for compensation, indemnity or damages of any sort
+solely as a result of terminating this License in accordance with its
+terms, and termination of this License will be without prejudice to
+any other right or remedy of either party.
+
+13.  Miscellaneous.
+
+13.1 Government End Users.  The Covered Code is a "commercial item" as
+defined in FAR 2.101.  Government software and technical data rights
+in the Covered Code include only those rights customarily provided to
+the public as defined in this License. This customary commercial
+license in technical data and software is provided in accordance with
+FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation).  Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties.  This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between You and Apple, and You will not represent to
+the contrary, whether expressly, by implication, appearance or
+otherwise.
+
+13.3 Independent Development.  Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction.  Failure by Apple to enforce any provision
+of this License will not be deemed a waiver of future enforcement of
+that or any other provision.  Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+will not apply to this License.
+
+13.5 Severability.  (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect.  (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution.  Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law.  This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof.  This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+Reserved.  This file contains Original Code and/or Modifications of
+Original Code as defined in and that are subject to the Apple Public
+Source License Version 1.1 (the "License").  You may not use this file
+except in compliance with the License.  Please obtain a copy of the
+License at http://www.apple.com/publicsource and read it before using
+this file.
+
+The Original Code and all software distributed under the License are
+distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+License for the specific language governing rights and limitations
+under the License."
diff --git a/dlcompat-20010505/ChangeLog b/dlcompat-20010505/ChangeLog
new file mode 100644 (file)
index 0000000..49bc51b
--- /dev/null
@@ -0,0 +1,20 @@
+2001-05-05  Christoph Pfisterer  <cp@chrisp.de>
+
+       * dlfcn.h: Added wrapper for C++.
+
+2001-01-23  Christoph Pfisterer  <cp@chrisp.de>
+
+       * dlopen.c: Added optional debugging output. Modules are now
+       searched for in various directories when no absolute path is
+       specified and the module is not found in the current directory. A
+       new function, _dl_search_paths, was added to accomplish the
+       search. Added an include for <limits.h>, because PATH_MAX is
+       defined there.
+       * Makefile: Some rearragements for the optional debugging
+       output. (Use "make DEBUG=1" to enable it.)
+
+2001-01-16  Christoph Pfisterer  <cp@chrisp.de>
+
+       * dlopen.c: Removed #include for ofi.h - it doesn't seem to be
+       needed.
+
diff --git a/dlcompat-20010505/Makefile b/dlcompat-20010505/Makefile
new file mode 100644 (file)
index 0000000..3291cf2
--- /dev/null
@@ -0,0 +1,63 @@
+#
+# Makefile for dlcompat
+#
+#
+# Copyright (c) 2001 Christoph Pfisterer.
+#
+# Portions Copyright (c) 1999-2001 Apple Computer, Inc. All Rights
+# Reserved.
+#
+# This file contains Original Code and/or Modifications of Original
+# Code as defined in and that are subject to the Apple Public Source
+# License Version 1.2 (the "License"). You may not use this file
+# except in compliance with the License. Please obtain a copy of the
+# License at http://www.apple.com/publicsource and read it before
+# using this file.
+#
+# The Original Code and all software distributed under the License are
+# distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+# EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+# INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
+# NON-INFRINGEMENT. Please see the License for the specific language
+# governing rights and limitations under the License.
+# 
+
+
+prefix=/usr/local
+DEBUG=0
+
+CC=cc
+CFLAGS=-Wall -O2 -DDEBUG=$(DEBUG)
+AR=ar cru
+RANLIB=ranlib
+INSTALL=install
+
+OBJS = dlopen.o
+
+
+all: libdl.a libdl.dylib
+
+install: all
+       if test ! -d $(prefix)/lib ; then mkdir $(prefix)/lib ; fi
+       $(INSTALL) -m 644 libdl.a $(prefix)/lib
+       $(RANLIB) $(prefix)/lib/libdl.a
+       chmod 644 $(prefix)/lib/libdl.a
+       $(INSTALL) -m 755 libdl.dylib $(prefix)/lib
+       if test ! -d $(prefix)/include ; then mkdir $(prefix)/include ; fi
+       $(INSTALL) -c -m 644 dlfcn.h $(prefix)/include
+
+.c.o:
+       $(CC) $(CFLAGS) -fno-common -o $@ -c $<
+
+libdl.a: $(OBJS)
+       $(AR) libdl.a $(OBJS)
+       $(RANLIB) libdl.a
+
+libdl.dylib: $(OBJS)
+       $(CC) -dynamiclib -undefined error -o libdl.dylib $(OBJS) -install_name $(prefix)/lib/libdl.dylib
+
+clean:
+       rm -f $(OBJS) libdl.*
+
+# EOF
diff --git a/dlcompat-20010505/README b/dlcompat-20010505/README
new file mode 100644 (file)
index 0000000..858ce8e
--- /dev/null
@@ -0,0 +1,71 @@
+ dlcompat for Darwin
+=====================
+
+This is release 20010505 of dlcompat. dlcompat is a small library that
+emulates the dlopen() interface on top of Darwin's dyld API. It is
+based on a CVS snapshot of Apple's Darwin CVS repository, taken on
+Jan 16 2001 (and still current as of May 5 2001). Since it's based on
+Apple code, it is released under the terms of the Apple Public Source
+License; see the file APPLE_LICENSE for the text of the license.
+
+Changes were made to automatically search for the module in several
+directories (taken from the environment variables DYLD_LIBRARY_PATH
+and LD_LIBRARY_PATH, plus /usr/lib and /lib) when no absolute path is
+specified and the module is not found in the current directory. If you
+prefer to run unmodified Apple code, download release 20010116.
+
+
+ Installation
+--------------
+As root, type:
+
+  make install
+
+This will compile the source file, generate both a static and shared
+library called libdl and install it into /usr/local/lib. The header
+file dlfcn.h will be installed in /usr/local/include.
+
+If you want to place the files somewhere else, run
+
+  make clean
+  make install prefix=<prefix>
+
+where <prefix> is the hierarchy you want to install into, e.g. /usr
+for /usr/lib and /usr/include (_NOT_ recommended!).
+
+To enable debugging output, run
+
+  make clean
+  make DEBUG=1
+  make install
+
+Combinations of those commands are left as an excercise to the
+reader. :-)
+
+
+ Usage
+-------
+Software that uses GNU autoconf will likely check for a library called
+libdl, that's why I named it that way. For software that doesn't find
+the library on its own, you must add a '-ldl' to the appropriate
+Makefile (or environment) variable, usually LIBS.
+
+If you installed dlcompat into a directory other than /usr/local/lib,
+you must tell the compiler where to find it. Add '-L<prefix>/lib' to
+LDFLAGS (or CFLAGS) and '-I<prefix>/include' to CPPFLAGS (or CFLAGS).
+
+
+ Genesis
+---------
+The files dlfcn.h and dlopen.c are taken from the Darwin CVS,
+directory Commands/Apple/cctools/libdyld. For release 20010116, I
+removed an unneccessary include statement from dlopen.c and added the
+Makefile. For release 20010123, I added debugging output and library
+searching. The changes are clearly documented, as required by the
+Apple Public Source License. For release 20010505, I added wrappers to
+disable C++ name mangling. That allows the library to be used by C++
+code, but be aware that there are issues with C++ and bundles, like
+static initializers not being called.
+
+
+Christoph Pfisterer <cp@chrisp.de>
diff --git a/dlcompat-20010505/dlfcn.h b/dlcompat-20010505/dlfcn.h
new file mode 100644 (file)
index 0000000..c287399
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * This file was modified by Christoph Pfisterer <cp@chrisp.de>
+ * on Sat, May 5 2001. See the file "ChangeLog" for details of what
+ * was changed.
+ *
+ *
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void * dlopen(
+    const char *path,
+    int mode);
+extern void * dlsym(
+    void * handle,
+    const char *symbol);
+extern const char * dlerror(
+    void);
+extern int dlclose(
+    void * handle);
+
+#define RTLD_LAZY      0x1
+#define RTLD_NOW       0x2
+#define RTLD_LOCAL     0x4
+#define RTLD_GLOBAL    0x8
+#define RTLD_NOLOAD    0x10
+#define RTLD_SHARED    0x20    /* not used, the default */
+#define RTLD_UNSHARED  0x40
+#define RTLD_NODELETE  0x80
+#define RTLD_LAZY_UNDEF        0x100
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/dlcompat-20010505/dlopen.c b/dlcompat-20010505/dlopen.c
new file mode 100644 (file)
index 0000000..a2d2036
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * This file was modified by Christoph Pfisterer <cp@chrisp.de>
+ * on Tue, Jan 23 2001. See the file "ChangeLog" for details of what
+ * was changed.
+ *
+ *
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include "mach-o/dyld.h"
+#include "dlfcn.h"
+
+/*
+ * debugging macros
+ */
+#if DEBUG > 0
+#define DEBUG_PRINT(format) fprintf(stderr,(format));fflush(stderr)
+#define DEBUG_PRINT1(format,arg1) fprintf(stderr,(format),(arg1));\
+  fflush(stderr)
+#define DEBUG_PRINT2(format,arg1,arg2) fprintf(stderr,(format),\
+  (arg1),(arg2));fflush(stderr)
+#define DEBUG_PRINT3(format,arg1,arg2,arg3) fprintf(stderr,(format),\
+  (arg1),(arg2),(arg3));fflush(stderr)
+#else
+#define DEBUG_PRINT(format) /**/
+#define DEBUG_PRINT1(format,arg1) /**/
+#define DEBUG_PRINT2(format,arg1,arg2) /**/
+#define DEBUG_PRINT3(format,arg1,arg2,arg3) /**/
+#undef DEBUG
+#endif
+
+/*
+ * The structure of a dlopen() handle.
+ */
+struct dlopen_handle {
+    dev_t dev;         /* the path's device and inode number from stat(2) */
+    ino_t ino; 
+    int dlopen_mode;   /* current dlopen mode for this handle */
+    int dlopen_count;  /* number of times dlopen() called on this handle */
+    NSModule module;   /* the NSModule returned by NSLinkModule() */
+    struct dlopen_handle *prev;
+    struct dlopen_handle *next;
+};
+static struct dlopen_handle *dlopen_handles = NULL;
+static const struct dlopen_handle main_program_handle = {NULL};
+static char *dlerror_pointer = NULL;
+
+/*
+ * NSMakePrivateModulePublic() is not part of the public dyld API so we define
+ * it here.  The internal dyld function pointer for
+ * __dyld_NSMakePrivateModulePublic is returned so thats all that maters to get
+ * the functionality need to implement the dlopen() interfaces.
+ */
+static
+int
+NSMakePrivateModulePublic(
+NSModule module)
+{
+    static int (*p)(NSModule module) = NULL;
+
+       if(p == NULL)
+           _dyld_func_lookup("__dyld_NSMakePrivateModulePublic",
+                             (unsigned long *)&p);
+       if(p == NULL){
+#ifdef DEBUG
+           printf("_dyld_func_lookup of __dyld_NSMakePrivateModulePublic "
+                  "failed\n");
+#endif
+           return(FALSE);
+       }
+       return(p(module));
+}
+
+/*
+ * helper routine: search for a named module in various locations
+ */
+static
+int
+_dl_search_paths(
+const char *filename,
+char *pathbuf,
+struct stat *stat_buf)
+{
+    const char *pathspec;
+    const char *element;
+    const char *p;
+    char *q;
+    char *pathbuf_end;
+    const char *envvars[] = {
+        "$DYLD_LIBRARY_PATH",
+        "$LD_LIBRARY_PATH",
+        "/usr/lib:/lib",
+        NULL };
+    int envvar_index;
+
+        pathbuf_end = pathbuf + PATH_MAX - 8;
+
+       for(envvar_index = 0; envvars[envvar_index]; envvar_index++){
+           if(envvars[envvar_index][0] == '$'){
+               pathspec = getenv(envvars[envvar_index]+1);
+           }
+           else {
+               pathspec = envvars[envvar_index];
+           }
+
+           if(pathspec != NULL){
+               element = pathspec;
+               while(*element){
+                   /* extract path list element */
+                   p = element;
+                   q = pathbuf;
+                   while(*p && *p != ':' && q < pathbuf_end)
+                        *q++ = *p++;
+                   if(q == pathbuf){  /* empty element */
+                       if(*p){
+                           element = p+1;
+                           continue;
+                       }
+                       break;
+                   }
+                   if (*p){
+                       element = p+1;
+                   }
+                   else{
+                       element = p;  /* this terminates the loop */
+                   }
+
+                   /* add slash if neccessary */
+                   if(*(q-1) != '/' && q < pathbuf_end){
+                       *q++ = '/';
+                   }
+
+                   /* append module name */
+                   p = filename;
+                   while(*p && q < pathbuf_end) *q++ = *p++;
+                   *q++ = 0;
+
+                   if(q >= pathbuf_end){
+                       /* maybe add an error message here */
+                       break;
+                   }
+
+                   if(stat(pathbuf, stat_buf) == 0){
+                       return 0;
+                   }
+               }
+           }
+       }
+
+       /* we have searched everywhere, now we give up */
+       return -1;
+}
+
+/*
+ * dlopen() the MacOS X version of the FreeBSD dlopen() interface.
+ */
+void *
+dlopen(
+const char *path,
+int mode)
+{
+    const char *module_path;
+    void *retval;
+    struct stat stat_buf;
+    NSObjectFileImage objectFileImage;
+    NSObjectFileImageReturnCode ofile_result_code;
+    NSModule module;
+    struct dlopen_handle *p;
+    unsigned long options;
+    NSSymbol NSSymbol;
+    void (*init)(void);
+    char pathbuf[PATH_MAX];
+
+        DEBUG_PRINT2("libdl: dlopen(%s,0x%x) -> ", path, (unsigned int)mode);
+
+       dlerror_pointer = NULL;
+       /*
+        * A NULL path is to indicate the caller wants a handle for the
+        * main program.
+        */
+       if(path == NULL){
+           retval = (void *)&main_program_handle;
+           DEBUG_PRINT1("main / %p\n", retval);
+           return(retval);
+       }
+
+       /* see if the path exists and if so get the device and inode number */
+       if(stat(path, &stat_buf) == -1){
+           dlerror_pointer = strerror(errno);
+
+           if(path[0] == '/'){
+               DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
+               return(NULL);
+           }
+
+           /* search for the module in various places */
+           if(_dl_search_paths(path, pathbuf, &stat_buf)){
+               /* dlerror_pointer is unmodified */
+               DEBUG_PRINT1("ERROR (stat): %s\n", dlerror_pointer);
+               return(NULL);
+           }
+           DEBUG_PRINT1("found %s -> ", pathbuf);
+           module_path = pathbuf;
+           dlerror_pointer = NULL;
+       }
+       else{
+           module_path = path;
+       }
+
+       /*
+        * If we don't want an unshared handle see if we already have a handle
+        * for this path.
+        */
+       if((mode & RTLD_UNSHARED) != RTLD_UNSHARED){
+           p = dlopen_handles;
+           while(p != NULL){
+               if(p->dev == stat_buf.st_dev && p->ino == stat_buf.st_ino){
+                   /* skip unshared handles */
+                   if((p->dlopen_mode & RTLD_UNSHARED) == RTLD_UNSHARED)
+                       continue;
+                   /*
+                    * We have already created a handle for this path.  The
+                    * caller might be trying to promote an RTLD_LOCAL handle
+                    * to a RTLD_GLOBAL.  Or just looking it up with
+                    * RTLD_NOLOAD.
+                    */
+                   if((p->dlopen_mode & RTLD_LOCAL) == RTLD_LOCAL &&
+                      (mode & RTLD_GLOBAL) == RTLD_GLOBAL){
+                       /* promote the handle */
+                       if(NSMakePrivateModulePublic(p->module) == TRUE){
+                           p->dlopen_mode &= ~RTLD_LOCAL;
+                           p->dlopen_mode |= RTLD_GLOBAL;
+                           p->dlopen_count++;
+                           DEBUG_PRINT1("%p\n", p);
+                           return(p);
+                       }
+                       else{
+                           dlerror_pointer = "can't promote handle from "
+                                             "RTLD_LOCAL to RTLD_GLOBAL";
+                           DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+                           return(NULL);
+                       }
+                   }
+                   p->dlopen_count++;
+                   DEBUG_PRINT1("%p\n", p);
+                   return(p);
+               }
+               p = p->next;
+           }
+       }
+       
+       /*
+        * We do not have a handle for this path if we were just trying to
+        * look it up return NULL to indicate we don't have it.
+        */
+       if((mode & RTLD_NOLOAD) == RTLD_NOLOAD){
+           dlerror_pointer = "no existing handle for path RTLD_NOLOAD test";
+           DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+           return(NULL);
+       }
+
+       /* try to create an object file image from this path */
+       ofile_result_code = NSCreateObjectFileImageFromFile(module_path,
+                                                           &objectFileImage);
+       if(ofile_result_code != NSObjectFileImageSuccess){
+           switch(ofile_result_code){
+           case NSObjectFileImageFailure:
+               dlerror_pointer = "object file setup failure";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           case NSObjectFileImageInappropriateFile:
+               dlerror_pointer = "not a Mach-O MH_BUNDLE file type";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           case NSObjectFileImageArch:
+               dlerror_pointer = "no object for this architecture";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           case NSObjectFileImageFormat:
+               dlerror_pointer = "bad object file format";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           case NSObjectFileImageAccess:
+               dlerror_pointer = "can't read object file";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           default:
+               dlerror_pointer = "unknown error from "
+                                 "NSCreateObjectFileImageFromFile()";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           }
+       }
+
+       /* try to link in this object file image */
+       options = NSLINKMODULE_OPTION_PRIVATE;
+       if((mode & RTLD_NOW) == RTLD_NOW)
+           options |= NSLINKMODULE_OPTION_BINDNOW;
+       module = NSLinkModule(objectFileImage, module_path, options);
+       NSDestroyObjectFileImage(objectFileImage) ;
+       if(module == NULL){
+           dlerror_pointer = "NSLinkModule() failed for dlopen()";
+           DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+           return(NULL);
+       }
+
+       /*
+        * If the handle is to be global promote the handle.  It is done this
+        * way to avoid multiply defined symbols.
+        */
+       if((mode & RTLD_GLOBAL) == RTLD_GLOBAL){
+           if(NSMakePrivateModulePublic(module) == FALSE){
+               dlerror_pointer = "can't promote handle from RTLD_LOCAL to "
+                                 "RTLD_GLOBAL";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           }
+       }
+
+       p = malloc(sizeof(struct dlopen_handle));
+       if(p == NULL){
+           dlerror_pointer = "can't allocate memory for the dlopen handle";
+           DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+           return(NULL);
+       }
+
+       /* fill in the handle */
+       p->dev = stat_buf.st_dev;
+        p->ino = stat_buf.st_ino;
+       if(mode & RTLD_GLOBAL)
+           p->dlopen_mode = RTLD_GLOBAL;
+       else
+           p->dlopen_mode = RTLD_LOCAL;
+       p->dlopen_mode |= (mode & RTLD_UNSHARED) |
+                         (mode & RTLD_NODELETE) |
+                         (mode & RTLD_LAZY_UNDEF);
+       p->dlopen_count = 1;
+       p->module = module;
+       p->prev = NULL;
+       p->next = dlopen_handles;
+       if(dlopen_handles != NULL)
+           dlopen_handles->prev = p;
+       dlopen_handles = p;
+
+       /* call the init function if one exists */
+       NSSymbol = NSLookupSymbolInModule(p->module, "__init");
+       if(NSSymbol != NULL){
+           init = NSAddressOfSymbol(NSSymbol);
+           init();
+       }
+       
+       DEBUG_PRINT1("%p\n", p);
+       return(p);
+}
+
+/*
+ * dlsym() the MacOS X version of the FreeBSD dlopen() interface.
+ */
+void *
+dlsym(
+void * handle,
+const char *symbol)
+{
+    struct dlopen_handle *dlopen_handle, *p;
+    NSSymbol NSSymbol;
+    void *address;
+
+        DEBUG_PRINT2("libdl: dlsym(%p,%s) -> ", handle, symbol);
+
+       dlopen_handle = (struct dlopen_handle *)handle;
+
+       /*
+        * If this is the handle for the main program do a global lookup.
+        */
+       if(dlopen_handle == (struct dlopen_handle *)&main_program_handle){
+           if(NSIsSymbolNameDefined(symbol) == TRUE){
+               NSSymbol = NSLookupAndBindSymbol(symbol);
+               address = NSAddressOfSymbol(NSSymbol);
+               dlerror_pointer = NULL;
+               DEBUG_PRINT1("%p\n", address);
+               return(address);
+           }
+           else{
+               dlerror_pointer = "symbol not found";
+               DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+               return(NULL);
+           }
+       }
+
+       /*
+        * Find this handle and do a lookup in just this module.
+        */
+       p = dlopen_handles;
+       while(p != NULL){
+           if(dlopen_handle == p){
+               NSSymbol = NSLookupSymbolInModule(p->module, symbol);
+               if(NSSymbol != NULL){
+                   address = NSAddressOfSymbol(NSSymbol);
+                   dlerror_pointer = NULL;
+                   DEBUG_PRINT1("%p\n", address);
+                   return(address);
+               }
+               else{
+                   dlerror_pointer = "symbol not found";
+                   DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+                   return(NULL);
+               }
+           }
+           p = p->next;
+       }
+
+       dlerror_pointer = "bad handle passed to dlsym()";
+       DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+       return(NULL);
+}
+
+/*
+ * dlerror() the MacOS X version of the FreeBSD dlopen() interface.
+ */
+const char *
+dlerror(
+void)
+{
+    const char *p;
+
+       p = (const char *)dlerror_pointer;
+       dlerror_pointer = NULL;
+       return(p);
+}
+
+/*
+ * dlclose() the MacOS X version of the FreeBSD dlopen() interface.
+ */
+int
+dlclose(
+void * handle)
+{
+    struct dlopen_handle *p, *q;
+    unsigned long options;
+    NSSymbol NSSymbol;
+    void (*fini)(void);
+
+        DEBUG_PRINT1("libdl: dlclose(%p) -> ", handle);
+
+       dlerror_pointer = NULL;
+       q = (struct dlopen_handle *)handle;
+       p = dlopen_handles;
+       while(p != NULL){
+           if(p == q){
+               /* if the dlopen() count is not zero we are done */
+               p->dlopen_count--;
+               if(p->dlopen_count != 0){
+                   DEBUG_PRINT("OK");
+                   return(0);
+               }
+
+               /* call the fini function if one exists */
+               NSSymbol = NSLookupSymbolInModule(p->module, "__fini");
+               if(NSSymbol != NULL){
+                   fini = NSAddressOfSymbol(NSSymbol);
+                   fini();
+               }
+
+               /* unlink the module for this handle */
+               options = 0;
+               if(p->dlopen_mode & RTLD_NODELETE)
+                   options |= NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED;
+               if(p->dlopen_mode & RTLD_LAZY_UNDEF)
+                   options |= NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES;
+               if(NSUnLinkModule(p->module, options) == FALSE){
+                   dlerror_pointer = "NSUnLinkModule() failed for dlclose()";
+                   DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+                   return(-1);
+               }
+               if(p->prev != NULL)
+                   p->prev->next = p->next;
+               if(p->next != NULL)
+                   p->next->prev = p->prev;
+               if(dlopen_handles == p)
+                   dlopen_handles = p->next;
+               free(p);
+               DEBUG_PRINT("OK");
+               return(0);
+           }
+           p = p->next;
+       }
+       dlerror_pointer = "invalid handle passed to dlclose()";
+       DEBUG_PRINT1("ERROR: %s\n", dlerror_pointer);
+       return(-1);
+}
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644 (file)
index 0000000..0fac586
--- /dev/null
@@ -0,0 +1,89 @@
+# Makefile.am for SASL documentation
+# Rob Earhart
+# $Id: Makefile.am,v 1.34 2004/11/24 18:05:28 ken3 Exp $
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+EXTRA_DIST =   rfc1321.txt \
+               rfc1939.txt \
+               rfc2104.txt \
+               rfc2195.txt \
+               rfc2222.txt \
+               rfc2243.txt \
+               rfc2245.txt \
+               rfc2289.txt \
+               rfc2444.txt \
+               rfc2595.txt \
+               rfc2831.txt \
+               rfc2945.txt \
+               rfc3174.txt \
+               testing.txt \
+               server-plugin-flow.fig \
+               draft-burdis-cat-srp-sasl-xx.txt \
+               draft-ietf-sasl-anon-xx.txt \
+               draft-ietf-sasl-crammd5-xx.txt \
+               draft-ietf-sasl-gssapi-xx.txt \
+               draft-ietf-sasl-plain-xx.txt \
+               draft-ietf-sasl-rfc2222bis-xx.txt \
+               draft-ietf-sasl-rfc2831bis-xx.txt \
+               draft-ietf-sasl-saslprep-xx.txt \
+               draft-murchison-sasl-login-xx.txt \
+               draft-newman-sasl-c-api-xx.txt \
+               draft-newman-sasl-passdss-xx.txt \
+               programming.html \
+               sysadmin.html \
+               gssapi.html \
+               advanced.html \
+               options.html \
+               plugprog.html \
+               appconvert.html \
+               macosx.html \
+               windows.html \
+               readme.html \
+               mechanisms.html \
+               upgrading.html \
+               index.html \
+               components.html \
+               install.html \
+               TODO \
+               ONEWS \
+               NTMakefile
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644 (file)
index 0000000..e2d4e0a
--- /dev/null
@@ -0,0 +1,429 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for SASL documentation
+# Rob Earhart
+# $Id: Makefile.am,v 1.34 2004/11/24 18:05:28 ken3 Exp $
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+EXTRA_DIST = rfc1321.txt \
+               rfc1939.txt \
+               rfc2104.txt \
+               rfc2195.txt \
+               rfc2222.txt \
+               rfc2243.txt \
+               rfc2245.txt \
+               rfc2289.txt \
+               rfc2444.txt \
+               rfc2595.txt \
+               rfc2831.txt \
+               rfc2945.txt \
+               rfc3174.txt \
+               testing.txt \
+               server-plugin-flow.fig \
+               draft-burdis-cat-srp-sasl-xx.txt \
+               draft-ietf-sasl-anon-xx.txt \
+               draft-ietf-sasl-crammd5-xx.txt \
+               draft-ietf-sasl-gssapi-xx.txt \
+               draft-ietf-sasl-plain-xx.txt \
+               draft-ietf-sasl-rfc2222bis-xx.txt \
+               draft-ietf-sasl-rfc2831bis-xx.txt \
+               draft-ietf-sasl-saslprep-xx.txt \
+               draft-murchison-sasl-login-xx.txt \
+               draft-newman-sasl-c-api-xx.txt \
+               draft-newman-sasl-passdss-xx.txt \
+               programming.html \
+               sysadmin.html \
+               gssapi.html \
+               advanced.html \
+               options.html \
+               plugprog.html \
+               appconvert.html \
+               macosx.html \
+               windows.html \
+               readme.html \
+               mechanisms.html \
+               upgrading.html \
+               index.html \
+               components.html \
+               install.html \
+               TODO \
+               ONEWS \
+               NTMakefile
+
+subdir = doc
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am TODO
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  doc/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+       uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/NTMakefile b/doc/NTMakefile
new file mode 100644 (file)
index 0000000..6c0f848
--- /dev/null
@@ -0,0 +1,28 @@
+# Prevent all diagnostic messages
+VERBOSE=0
+
+!INCLUDE ..\win32\common.mak
+
+docdir = $(prefix)\doc
+
+all: all-recursive
+
+#
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
+#
+# In order to force xcopy not to confirm if the second parameter is file or directory,
+# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
+# instead of libsasl.lib. Ugly, but works!
+#
+install:
+       @xcopy *.txt $(docdir) /I /F /Y
+       @xcopy *.fig $(docdir) /I /F /Y
+       @xcopy *.html $(docdir) /I /F /Y
+       @xcopy TODO $(docdir) /I /F /Y
+       @xcopy ONEWS $(docdir) /I /F /Y
+
+all-recursive:
+       @echo Nothing to build for target all
+
+clean:
+       @echo Nothing to do for target clean
diff --git a/doc/ONEWS b/doc/ONEWS
new file mode 100644 (file)
index 0000000..2e92535
--- /dev/null
+++ b/doc/ONEWS
@@ -0,0 +1,179 @@
+New in 1.5.26
+-------------
+* Interoperability bug in DIGEST-MD5's layers was fixed.
+* DIGEST-MD5's DES layer has been disabled until the interoperability 
+  can be worked out.
+
+New in 1.5.25
+-------------
+
+* The DIGEST-MD5 plugin now includes an implementation of RC4, since
+  it's a lot easier to get working than interfacing with OpenSSL.
+* A delayed-open plugin mode has been implemented, but not yet documented.
+
+New in 1.5.24
+-------------
+* be a little paranoid about what we give PAM
+* small bugfixes
+
+New in 1.5.22
+-------------
+* fixed some DIGEST-MD5 buglets
+* fixed serious bug that a client could avoid the authorization callback
+* added pwcheck method "sia" for Digital Unix
+* now should try libdb-3 before libdb.
+
+New in 1.5.21
+-------------
+* build process fixes
+
+New in 1.5.20
+-------------
+* bug fixes
+* LOGIN mechanism has a compatibility tweak
+
+New in 1.5.19
+-------------
+* Initial srp work
+* Programmers Guide more complete
+* bug fixes (of course)
+
+New in 1.5.18
+-------------
+* javasasl library in conformance with internet draft
+* man pages for all functions written
+* bug fixes (of course)
+
+New in 1.5.17
+-------------
+* give application authentication name and realm more uniformly
+* sasldblistusers utility to list users in sasldb
+* memory leaks eliminated; boundary cases tested
+
+New in 1.5.16
+-------------
+* pwcheck_method now defaults to sasldb.
+  READ UPGRADE INSTRUCTIONS IN README
+
+* sanity checking inputs throughout the code.
+* Unsupported LOGIN plugin added to the Windows build.
+* calling sasl_checkpass() with pwcheck_method: kerberos_v4 restores the
+  old ticket file before returning.
+
+New in 1.5.15
+-------------
+* configure now correctly detects Berkeley DB 3.x (Claus Assmann).
+
+New in 1.5.14
+-------------
+* Upgraded to libtool 1.3.4.
+* External SSF handled more uniformly, and handle min/max SSF requests
+  correctly.
+* Unsupported LOGIN plugin added, by Rainer Schoepf <schoepf@uni-mainz.de>.
+  Please don't enable it unless you know you need it.
+* HP/UX support, contributed by Claus Assmann.
+
+New in 1.5.13
+-------------
+* Sanity check to make sure there's at least something in sasldb
+  READ UPGRADE INSTRUCTIONS IN README
+
+* Fixes to how external layers are handled (some fixes by Alexey Melnikov)
+* Berkeley DB 3.x support contributed by Greg Shapiro
+* Additional pwcheck fixes (Joe Hohertz)
+* Fixed Heimdal krb5 configure checks
+* other random fixes
+
+New in 1.5.12
+-------------
+* lots of bugfixes
+* DIGEST-MD5 more in conformance with spec
+* support for Berkeley DB
+* support for OpenSSL's version of RC4
+
+New in 1.5.11
+-------------
+* bugfix in realm support for DIGEST-MD5
+
+New in 1.5.10
+-------------
+* DIGEST-MD5 layer support
+* dbconversion utility added
+
+New in 1.5.9
+------------
+* Bug fixes
+* More win32 support
+* Realm support in the database (database format changed again, sorry)
+  Other realm support in plugins; need to document it
+* Preliminary code for pwcheck added; not yet tested (and probably not 
+  working)
+* config stuff should be less case/whitespace sensitive
+* more error conditions logged
+
+New in 1.5.5
+------------
+* Bug fixes
+* sasldb plaintext support (database format changed!!!)
+* Handles multiple realms in DIGEST
+* New Windows compatibility (tested!)
+
+New in 1.5.3
+------------
+* Bug fixes
+* Tested GSSAPI & added layers
+* Some changes for Windows compatibility (next release)
+
+New in 1.5.2
+------------
+* A few bug fixes
+* Better portability
+* Upgraded libtool
+
+New in 1.5.0
+------------
+* Lots of bug fixes
+* A few API changes (watch especially sasl_get_prop() and sasl_set_prop()!)
+* Digest authentication works
+* Configuration file
+* Some more documentation (doc/programming)
+* Code cleanup
+
+New in 1.4.1
+------------
+* Tested kerberos4, cram, plain, and anonymous fairly extensively
+* Many bugs fixed
+* Created sample programs
+* Added digest
+* Prototype credential API
+
+New in 1.3b1
+------------
+* Added saslpasswd for setting sasl passwords
+* Added sfsasl for people using sfio
+* Lots of bug fixes
+
+New in 1.2b3
+------------
+* Slightly better documentation, easier compilation
+* Plain now understands authorization and callbacks
+
+New in 1.2b2
+------------
+* Win32 support
+* Fixes to anonymous, kerberos mechs
+* Some signed lengths in the API changed to unsigned
+
+New in 1.2b1
+------------
+* Lots of bug fixes
+* GSSAPI
+* Cleaner getopt interface
+* Cleaner plugin callback lookup interface
+* Global inits now take callback list, not just a sasl_getopt_t
+* Preliminary Java support
+* Authentication database hook
+* Default AuthDB routines moved from mechanisms to library
+* Logging hook
+* Default syslog-based logging hook in library
+* Preliminary plaintext transition for CRAM/SCRAM
diff --git a/doc/TODO b/doc/TODO
new file mode 100644 (file)
index 0000000..f1de296
--- /dev/null
+++ b/doc/TODO
@@ -0,0 +1,62 @@
+Library
+~~~~~~~
+) Better/FASTER random numbers (init time is pretty miserable)
+) Test suite [still] needs work
+) better support for including missing routines
+) check return settings (ssf, etc.) on auth failure
+
+Documentation
+~~~~~~~~~~~~~
+) so much to do here
+) man pages (check spelling) 
+) programmers/sysadmin guide updates and clarifications
+) update INSTALL to have clearer step-by-step instructions
+
+Mechs to write
+~~~~~~~~~~~~~~
+
+SRP
+~~~
+) Testing
+
+OTP
+~~~
+) Checking edge cases
+) Testing
+
+Digest-MD5
+~~~~~~~~~~
+) Checking wacko cases or even not so wacko cases
+) Testing
+
+Kerberos_V4
+~~~~~~~~~~~
+) client-side should set realm
+) is prompt_need callback set default value
+
+GSSAPI
+~~~~~~
+) Allow specification of alternate keytab file
+
+Plain
+~~~~~
+
+Cram-MD5
+~~~~~~~~
+) needs snprintf support
+
+Database stuff
+~~~~~~~~~~~~~~
+) transactions?
+) version the database?
+) atomic updates of passwords (we can crash and leave the user with 
+  different passwords for different mechanisms) [through failure to
+  make setpass calls]
+) locks (to help fortify protection against OTP race attack)?
+
+ABI
+~~~
+) Consider IRIX ABI issues for plugins
+       - /usr/lib32/sasl?
+       - /usr/lib/sasl/{ABI}?
+) Standardize the plugin ABI
diff --git a/doc/advanced.html b/doc/advanced.html
new file mode 100644 (file)
index 0000000..da92454
--- /dev/null
@@ -0,0 +1,35 @@
+<HTML><head>
+<TITLE>Cyrus SASL Library -- Advanced Usage</TITLE>
+</head>
+<body>
+<h1>Cyrus SASL library, version 2.0</h1>
+<h2>Notes for Advanced Usage of libsasl</h2>
+
+<h3>Using Cyrus SASL as a static library</h3>
+As of v2.0.2-ALPHA, Cyrus SASL supports the option to compile all of the
+supported mechanisms and glue code into a single static library that may
+be linked into any application.  In practice, this saves memory by avoiding
+the need to have a jump table for each process's reference into the shared
+library, and ensures that all the mechanisms are loaded when the application
+loads (thus reducing the overhead of loading the DSOs).<P>
+
+However, this is not a recommended procedure to use in general.  It loses
+the flexibility of the DSOs that allow one to simply drop in a new mechanism
+that even currently-running applications will see for each new connection.
+That is, if you choose to use the static version of the library, not only
+will you need to recompile the library each time you add a mechanism (provided
+the mechanisms even support being compiled staticly), but you will need to
+recompile every application that uses Cyrus SASL as well.<P>
+
+However, if you are sure you wish to use a static version of Cyrus SASL,
+compile it by giving <tt>configure</tt> the <tt>--enable-static</tt> option.
+This will compile <b>both</b> a dynamic and a static version.  Then, whenever
+an application links to libsasl, it will also need to explicitly pull in
+any dynamic libraries that may be needed by Cyrus SASL.  Most notably, these
+might include the GSSAPI, Kerberos, and Database libraries.  To avoid compiling
+the dynamic version, pass <tt>--disable-shared</tt>.<P>
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
diff --git a/doc/appconvert.html b/doc/appconvert.html
new file mode 100644 (file)
index 0000000..f1de611
--- /dev/null
@@ -0,0 +1,100 @@
+<HTML>
+<HEAD>
+<TITLE>Converting Applications from SASLv1 to SASLv2</TITLE>
+<BODY>
+<H1>Application Conversion Guide for SASLv2</H1>
+
+<p>This documents our conversion experience with Cyrus IMAPd, an application
+that uses almost every part of SASL, so it should give a good idea what caveats
+need to be looked for when one is converting an application which uses SASLv1
+to use SASLv2.</P>
+
+<P>The major changes in the SASLv2 API have to do with memory management.
+That is, the rule "If you allocate it, you free it" is now enforced.  That
+means that if the application allocates something (for example, an interaction
+or callback response), it must free it.  Likewise, the application does
+NOT free anything handed to it by the SASL library, such as responses
+given by sasl_client_step or sasl_decode.</P>
+
+<UL>
+<LI>Tips for both clients and servers:<P>
+<UL>
+<LI>Change configure scripts to search for libsasl2 and include files
+prefixed with sasl/ (sasl/sasl.h, sasl/saslutil.h, etc)</LI>
+<LI><tt>sasl_decode64</tt> now takes an
+additional parameter that is the size of the buffer it is passed.</LI>
+<LI>External authentication properties are no longer handled by a
+<tt>sasl_external_properties_t</tt>.  Instead you make 2 separate calls to
+<tt>sasl_setprop.</tt>
+One with SASL_SSF_EXTERNAL to tell the SASL library what SSF is being
+provided by the external layer. The other sets SASL_AUTH_EXTERNAL to indicate
+the authentication name.</LI>
+<LI>
+<tt>sasl_getprop</tt> now returns its value in a <tt>const void **</tt>
+</LI>
+<LI><tt>sasl_encode</tt> and <tt>sasl_decode</tt> now return a constant output buffer, which
+you do not need to free (it is only valid until the next call for this sasl_
+conn_t, however)</LI>
+<LI>The SASL_IP_REMOTE and SASL_IP_LOCAL properties are now SASL_IPLOCALPORT
+and SASL_IPREMOTEPORT and take strings instead of sockaddrs. These strings
+may also be passed to the sasl_[client/server]_new functions.  They
+are in one of the following formats:
+<UL>
+<LI>a.b.c.d;p (IPv4, with port)</LI>
+<LI>e:f:g:h:i:j:k:l;p (IPv6, with port)</LI>
+<LI>e:j:k:l;p (IPv6, abbreviated zero fields, with port)</LI>
+</UL></LI>
+<li>Error handling and reporting is different. All of the functions that used
+to return a "reply" string no longer do.  Now you should (always) check
+<tt>sasl_errdetail</tt>.  Callbacks MUST likewise use <tt>sasl_seterror</tt>
+instead of setting their (now nonexistent) reply parameter.</li>
+<li>Be very careful about your handling of maxoutbuf.  If you claim that
+you can only read 4096 bytes at a time, be sure to only pass at most
+that much at a time to the SASL library!</li>
+</UL></LI>
+
+<LI>Tips for clients:</LI>
+<OL>
+<LI>In <tt>sasl_client_new</tt> you can now pass ip address strings as
+parameters 3 and 4 instead of calling setprop later on sockaddr's.
+This is preferred but not required (not passing them by either method disables
+mechs which require IP address information).   You might find the iptostring()
+function in utils/smtptest.c to be useful for this.  If the protocol supports
+the server sending data on success you should pass SASL_SUCCESS_DATA as a
+flag.</LI>
+<LI><tt>sasl_client_start</tt> loses the 3rd "secret" parameter.
+Also, NULL clientout and clientoutlen indicates that the protocol does not
+support client-send-first.  A NULL return value indicates that there is no
+first client send. (as opposed to an empty string, which indicates that
+the first client send is the empty string).</LI>
+<LI>
+Both <tt>sasl_client_start</tt> and <tt>sasl_client_step</tt> now take
+const clientout parameters that you are no longer responsible for freeing
+(it is only valid until the next call for this <tt>sasl_conn_t</tt>, however)
+</LI>
+<LI>When interactions and callbacks happen you are responsible for freeing
+the results.</LI>
+</OL></LI>
+
+<LI>Tips for Servers:</LI>
+<OL>
+<LI>SASL_SECURITY_LAYER flag no longer exists, whether or not to use a
+security layer is solely determined by the security properties information,
+namely, the <tt>maxbufsize</tt> member of the
+<tt>sasl_security_properties_t</tt></LI>
+<LI><tt>sasl_server_new</tt> now can take ip address strings.</li>
+<LI><tt>sasl_checkpass</tt> no longer has a "reply" parameter.  There
+are also considerably fewer possible values for the pwcheck_method
+option (now only auxprop, saslauthd, authdaemond, and pwcheck).</li>
+<li><tt>sasl_server_start</tt> / <tt>sasl_server_step</tt> have same
+output parameter deal as their equivalents on the client side</li>
+<li><tt>sasl_listmech</tt> has a constant output parameter</li>
+<li>If you used to canonicalize the username in a SASL_CB_PROXY_POLICY
+callback you should now separate the functionality of authorization and
+canonicalization.  That is, only do authorization in SASL_CB_PROXY_POLICY,
+and do canonicalization in the SASL_CB_CANON_USER callback</li>
+</OL></LI>
+
+</UL>
+</BODY>
+</HTML>
diff --git a/doc/components.html b/doc/components.html
new file mode 100644 (file)
index 0000000..3002b3c
--- /dev/null
@@ -0,0 +1,178 @@
+<HTML><HEAD>
+<title>SASL Components</title>
+<!-- $Id: components.html,v 1.4 2003/07/15 17:38:57 ken3 Exp $ -->
+</HEAD>
+<BODY>
+<H1>SASL Components</H1>
+
+<p>As the SASL library is a 'glue layer' between many different parts of the
+authentication system, there are a lot of different components
+that often cause confusion to users of the library who are trying to
+configure it for use on their system.  This document will try to provide
+some structure to all of these components, though you will also need
+to read the <a href=sysadmin.html>System Administration</a> to have a full
+understanding of how to install SASL on your system.</p>
+
+<p>The first thing to realize is that there is a difference between SASL,
+the protocol, and Cyrus SASL, the library.  The first is a specification
+that describes how authentication mechanisms can be plugged into an application
+protocol <i>on the wire</i>.  The later is an implementation that aims
+to make this easier for application developers to integrate authentication
+mechanisms into their application in a generic way.  It is quite possible
+to have an application that uses SASL (the specification) without using
+Cyrus SASL (the implementation).</p>
+
+<p>The remainder of this document will refer to components of the Cyrus
+SASL implementation, though some of these will necessarily have a broader
+scope.</p>
+
+<h3>The Application</h3>
+The application is a client of the SASL library.  It can be a client or server
+application (or both, in the case of a proxy).  It takes care of the
+on-the-wire representation of the SASL negotiation, however it performs no
+analysis of the exchange itself.  It relies on the judgment of the SASL
+library whether authentication has occurred or not.  The application is also
+responsible for determining if the authenticated user may authorize as another
+user id (For more details on authentication and authorization identities
+and their differences, see
+<a href=sysadmin.html>Cyrus SASL for System Administrators</a>)</p>
+
+<p>Examples of applications are Cyrus IMAPd, OpenLDAP, Sendmail, Mutt, 
+sieveshell, cyradm, and many others.</p>
+
+<h3>The SASL Glue Layer</h3>
+
+<p>The first component of the SASL library is affectionately called the
+&quot;glue&quot; layer.  It takes care of ensuring that the application and
+the mechanisms can work together successfully.  To this end, it does a
+variety of basic tasks:</p>
+
+<ul>
+<li>Loading of any plugins (more on these below)</li>
+<li>Ascertaining necessary security properties from the application to aid
+in the choice of mechanism (or to limit the available mechanisms)</li>
+<li>Listing of available plugins to the application (mostly used on the server
+side)</li>
+<li>Choosing the &quot;best&quot; mechanism from a list of available mechanisms
+for a particular authentication attempt (client-side)</li>
+<li>Routing the authentication (and in the case of a mechanism with a security
+layer, encrypted) data packets between the application and the
+chosen mechanism.</li>
+<li>Providing information about the SASL negotiation back to the application
+(authenticated user, requested authorization identity, security strength of
+any negotiated security layer, and so on).</li>
+</ul>
+
+<p>The Cyrus SASL implementation also provides several other services to
+both its plugins and applications.  Some of these are simply general utilities,
+such as MIME Base-64 encoding and decoding, and random number generation.
+Others are more specific to the task of authentication, such as providing
+password verification services.  Such services are capable of taking
+a username and a plaintext password and saying &quot;yes&quit; or
+&quot;no&quot;.  Details of available password verification services are
+discussed below.</p>
+
+<p>Finally, the glue code allows the mechanisms and applications access to
+two special types of plugins, Auxiliary Property or &quot;auxprop&quot;
+plugins, which provide a simple database interface and can return properties
+about the user such as password, home directory, or mail
+routing address, and Username Canonicalization, which might provide
+site-specific ways to canonicalize a username or perform other tasks.</p>
+
+<p>In the Cyrus SASL Implementation, the glue code is entirely contained
+within <tt>libsasl2.so</tt> (or <tt>libsasl2.a</tt>)</p>
+
+<h3>Plugins (General)</h3>
+
+<p>The Cyrus SASL architechure is very modular, using loadable modules for
+things such as the mechanism profiles and the database access done by the
+auxillary property plugins.  This means that it is easy to limit what
+parts are loaded by a given application, and that third parties can write
+their own modules to provide services, just by adhering to the API description
+in <tt>saslplug.h</tt>.</p>
+
+<h3>Plugins (SASL Mechanisms)</h3>
+
+<p>The simplest types of plugins to understand are those which provide
+SASL mechanisms, such as CRAM-MD5, DIGEST-MD5, GSSAPI, PLAIN, SRP, and so on.
+These mechanisms take care of both server-side and client-side parts
+of the SASL negotiation.  If the given mechanism supports a security layer
+(that is, makes guarantees about privacy or integrity of data after the
+negotiation is complete), the plugin provides that functionality as well.</p>
+
+<p>SASL mechanisms are generally defined by the IETF standards process,
+however, some mechanisms are not (For example, NTLM).  This is in contrast
+to the other types of plugins, which provide database and username
+canonicalization services to other plugins and thus aren't standardized in
+their behavior (they are specific to our implementation).  Password verifiers
+are also an implementation detail (though saslauthd makes use of
+standards such as PAM and LDAP to perform that verification)</p>
+
+<p>There are several types of mechanisms, in broad strokes we have:</p>
+<ul>
+<li><b>Password Verification Mechanisms</b> - For example, PLAIN.  These receive a raw password from the remote and then pass it into the glue code for
+verification by a password verifier.  These require the existence of an
+outside security layer to hide the otherwise plaintext password from people
+who might be snooping on the wire.  These mechanisms do not require that
+the server have access to a plaintext (or plaintext-equivalent) version
+of the password.</li>
+<li><b>Shared Secret Mechanisms</b> - For these mechanisms, such as CRAM-MD5,
+DIGEST-MD5, and SRP, there is a shared secret between the server and client
+(e.g. a password).  However, in this case the password itself does not travel
+on the wire.  Instead, the client passes a server a token that proves that
+it knows the secret (without actually sending the secret across the wire).
+For these mechanisms, the server generally needs a plaintext equivalent of
+the secret to be in local storage (not true for SRP).
+<li><b>Kerberos Mechanisms</b> - Kerberos mechanisms use a trusted
+third party to authenticate the client.  These mechanisms don't require
+the server to share any secret information with the client, it is all performed
+through the Kerberos protocol.</li>
+</ul>
+
+<p>Mechanism plugins are generally contained in a .so file that has a name
+similar to the mechanism's name.  Though, in a static compilation they
+can also be a part of <tt>libsasl2.a</tt></p>
+
+<h3>Plugins (Auxiliary Property)</h3>
+
+<p>Auxiliary Property (or auxprop) plugins provide a database service for the
+glue layer (and through it, to the mechanisms and application).  Cyrus SASL
+ships with two auxprop plugins: SASLdb and SQL.  Though they can be use
+in much more generic ways, auxprop plugins are mostly only used by
+shared secret mechanisms (or by the auxprop password verify) to access the
+&quot;userPassword&quot; attribute.  This provides a plaintext copy of the
+password that allows for authentication to take place.</p>
+
+<p>Like the mechanism plugins, these are named similarly to the databases
+that they implement an interface for.</p>
+
+<h3>Plugins (Username Canonicalization)</h3>
+
+Username Canonicalization plugins are not widely used, however it may be
+useful to use as a hook if your site has specific requirements for how userids
+are presented to the applications.
+
+<h3>Password Verification Services</h3>
+
+<p>As described above, the password verifiers take a username and plaintext
+password, and say either &quot;yes&quot; or &quot;no&quot;.  It is not possible
+to use them to verify hashes that might be provided by the shared secret
+mechanisms.</p>
+
+<p>Password verifiers are selected using the &quot;pwcheck_method&quot;
+SASL option.  There are two main password verifiers provided with Cyrus SASL:</p>
+<ul>
+<li><b>auxprop</b> - This uses an auxprop plugin to fetch the password and then
+compares it with the client-provided copy to make the determination.</li>
+<li><b>saslauthd</b> - This calls out to the <tt>saslauthd</tt> daemon, which
+also ships with the distribution.  The <tt>saslauthd</tt> daemon has a number
+of modules of its own, which allow it to do verification of passwords in 
+a variety of ways, including PAM, LDAP, against a Kerberos database, and so on.
+This is how you would want to, for example, use the data contained in
+<tt>/etc/shadow</tt> to authenticate users.</li>
+</ul>
+
+<hr>
+Back to the <a href=index.html>index</a>.
+</BODY>
+</HTML>
diff --git a/doc/draft-burdis-cat-srp-sasl-xx.txt b/doc/draft-burdis-cat-srp-sasl-xx.txt
new file mode 100644 (file)
index 0000000..d784f82
--- /dev/null
@@ -0,0 +1,2858 @@
+
+
+
+Network                                                        K. Burdis
+Internet-Draft                                         Rhodes University
+Expires: November 28, 2003                                     R. Naffah
+                                                          Forge Research
+                                                            May 30, 2003
+
+
+            Secure Remote Password Authentication Mechanism
+                      draft-burdis-cat-srp-sasl-08
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that other
+   groups may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time. It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at http://
+   www.ietf.org/ietf/1id-abstracts.txt.
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This Internet-Draft will expire on November 28, 2003.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+Abstract
+
+   This document describes an authentication mechanism based on the
+   Secure Remote Password protocol (SRP-6) and how to use it with the
+   authentication frameworks Secure Authentication and Security Layer
+   (SASL), Generic Security Services Application Programming Interface
+   (GSS-API) and Extensible Authentication Protocol (EAP).  This
+   mechanism performs mutual authentication and can provide a security
+   layer with replay detection, integrity protection and/or
+   confidentiality protection.
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 1]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Table of Contents
+
+   1.    Introduction . . . . . . . . . . . . . . . . . . . . . . . .  4
+   2.    Conventions Used in this Document  . . . . . . . . . . . . .  5
+   3.    Data Element Formats . . . . . . . . . . . . . . . . . . . .  6
+   3.1   Scalar Numbers . . . . . . . . . . . . . . . . . . . . . . .  6
+   3.2   Multi-Precision Integers . . . . . . . . . . . . . . . . . .  6
+   3.3   Octet Sequences  . . . . . . . . . . . . . . . . . . . . . .  7
+   3.4   Extended Octet Sequences . . . . . . . . . . . . . . . . . .  7
+   3.5   Text . . . . . . . . . . . . . . . . . . . . . . . . . . . .  7
+   3.6   Buffers  . . . . . . . . . . . . . . . . . . . . . . . . . .  8
+   3.7   Data Element Size Limits . . . . . . . . . . . . . . . . . .  8
+   3.8   Unsigned Integers  . . . . . . . . . . . . . . . . . . . . .  8
+   4.    Protocol Description . . . . . . . . . . . . . . . . . . . .  9
+   4.1   Client Sends its Identity  . . . . . . . . . . . . . . . . . 11
+   4.2   Server Agrees to Re-use Parameters of a Previous Session . . 11
+   4.3   Server Sends Protocol Elements . . . . . . . . . . . . . . . 12
+   4.4   Client Sends its Ephemeral Public Key and Evidence . . . . . 15
+   4.5   Server Verifies Client's Evidence and Sends its Evidence . . 17
+   5.    Security Layer . . . . . . . . . . . . . . . . . . . . . . . 19
+   5.1   Cryptographic Primitives . . . . . . . . . . . . . . . . . . 20
+   5.1.1 Pseudo Random Number Generator . . . . . . . . . . . . . . . 20
+   5.1.2 Key Derivation Function  . . . . . . . . . . . . . . . . . . 22
+   5.2   Confidentiality Protection . . . . . . . . . . . . . . . . . 23
+   5.3   Replay Detection . . . . . . . . . . . . . . . . . . . . . . 24
+   5.4   Integrity Protection . . . . . . . . . . . . . . . . . . . . 25
+   5.5   Summary of Security Layer Output . . . . . . . . . . . . . . 25
+   6.    Discussion . . . . . . . . . . . . . . . . . . . . . . . . . 27
+   6.1   Mandatory Algorithms . . . . . . . . . . . . . . . . . . . . 27
+   6.2   Modulus and Generator Values . . . . . . . . . . . . . . . . 27
+   6.3   Replay Detection Sequence Number Counters  . . . . . . . . . 27
+   6.4   Re-using the Parameters of a Previous Session  . . . . . . . 28
+   7.    SASL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
+   7.1   Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 30
+   7.2   Mechanism Name . . . . . . . . . . . . . . . . . . . . . . . 30
+   7.3   Security Layer . . . . . . . . . . . . . . . . . . . . . . . 30
+   7.4   Profile Considerations . . . . . . . . . . . . . . . . . . . 30
+   7.5   Example  . . . . . . . . . . . . . . . . . . . . . . . . . . 31
+   8.    GSS-API  . . . . . . . . . . . . . . . . . . . . . . . . . . 34
+   8.1   Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 34
+   8.2   Terminology  . . . . . . . . . . . . . . . . . . . . . . . . 34
+   8.3   Initial Token  . . . . . . . . . . . . . . . . . . . . . . . 34
+   8.4   Security Layer . . . . . . . . . . . . . . . . . . . . . . . 35
+   9.    EAP  . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
+   9.1   Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 36
+   9.2   Terminology  . . . . . . . . . . . . . . . . . . . . . . . . 36
+   9.3   Method Details . . . . . . . . . . . . . . . . . . . . . . . 36
+   9.4   Security Claims  . . . . . . . . . . . . . . . . . . . . . . 37
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 2]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   10.   Security Considerations  . . . . . . . . . . . . . . . . . . 40
+   11.   Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 41
+         Normative References . . . . . . . . . . . . . . . . . . . . 42
+         Informative References . . . . . . . . . . . . . . . . . . . 44
+         Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 46
+   A.    Modulus and Generator Values . . . . . . . . . . . . . . . . 47
+   B.    Changes since the previous draft . . . . . . . . . . . . . . 49
+         Intellectual Property and Copyright Statements . . . . . . . 50
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 3]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+1. Introduction
+
+   The Secure Remote Password (SRP) is a password-based, zero-knowledge,
+   authentication and key-exchange protocol developed by Thomas Wu.  It
+   has good performance, is not plaintext-equivalent and maintains
+   perfect forward secrecy.  It provides authentication (optionally
+   mutual authentication) and the negotiation of a shared context key
+   [SRP].
+
+   The mechanism described herein is based on the SRP-6 protocol,
+   described in [SRP-6] and [SRP-6i].  SRP-6 is an improved version of
+   the original SRP protocol (also called SRP-3) described in
+   [RFC-2945].  Due to the design of the mechanism, mutual
+   authentication is MANDATORY.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 4]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+2. Conventions Used in this Document
+
+   o  A hex digit is an element of the set:
+
+         {0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, A, B, C, D, E, F}
+
+      A hex digit is the representation of a 4-bit string.  Examples:
+
+         7 = 0111
+
+         A = 1010
+
+   o  An octet is an 8-bit string.  In this document an octet may be
+      written as a pair of hex digits.  Examples:
+
+         7A = 01111010
+
+         02 = 00000010
+
+   o  All data is encoded and sent in network byte order (big-endian).
+
+   o  The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
+      NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL"
+      in this document are to be interpreted as described in [RFC-2119].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 5]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+3. Data Element Formats
+
+   This section describes the encoding of the data elements used by the
+   mechanism described in this document.
+
+3.1 Scalar Numbers
+
+   Scalar numbers are unsigned quantities.  Using b[k] to refer to the
+   k-th octet being processed, the value of a two-octet scalar is:
+
+      ((b[0] << 8) + b[1]),
+
+   where << is the bit left-shift operator.  The value of a four-octet
+   scalar is:
+
+      ((b[0] << 24) + (b[1] << 16) + (b[2] << 8) + b[3]).
+
+
+3.2 Multi-Precision Integers
+
+   Multi-Precision Integers, or MPIs, are positive integers used to hold
+   large integers used in cryptographic computations.
+
+   MPIs are encoded using a scheme inspired by that used by OpenPGP -
+   [RFC-2440] (section 3.2) - for encoding such entities:
+
+      The encoded form of an MPI SHALL consist of two pieces: a
+      two-octet scalar that represents the length of the entity, in
+      octets, followed by a sequence of octets that contain the actual
+      integer.
+
+      These octets form a big-endian number; A big-endian number can be
+      encoded by prefixing it with the appropriate length.
+
+      Examples: (all numbers are in hexadecimal)
+
+         The sequence of octets [00 01 01] encodes an MPI with the value
+         1, while the sequence [00 02 01 FF] encodes an MPI with the
+         value of 511.
+
+      Additional rule:
+
+      *  The length field of an encoded MPI describes the octet count
+         starting from the MPI's first non-zero octet, containing the
+         most significant non-zero bit.  Thus, the encoding [00 02 01]
+         is not formed correctly; It should be [00 01 01].
+
+   We shall use the syntax mpi(A) to denote the encoded form of the
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 6]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   multi-precision integer A.  Furthermore, we shall use the syntax
+   bytes(A) to denote the big-endian sequence of octets forming the
+   multi-precision integer with the most significant octet being the
+   first non-zero octet containing the most significant bit of A.
+
+3.3 Octet Sequences
+
+   This mechanism generates, uses and exchanges sequences of octets;
+   e.g. output values of message digest algorithm functions.  When such
+   entities travel on the wire, they shall be preceded by a one-octet
+   scalar quantity representing the count of following octets.
+
+   Note that a zero-length octet sequence is encoded as a single 00
+   octet.
+
+   We shall use the syntax os(s) to denote the encoded form of the octet
+   sequence.  Furthermore, we shall use the syntax bytes(s) to denote
+   the sequence of octets s, in big-endian order.
+
+3.4 Extended Octet Sequences
+
+   Extended sequences of octets are exchanged when using the security
+   layer.  When these sequences travel on the wire, they shall be
+   preceded by a four-octet scalar quantity representing the count of
+   following octets.
+
+   We shall use the syntax eos(s) to denote the encoded form of the
+   extended octet sequence.  Furthermore, we shall use the syntax
+   bytes(s) to denote the sequence of octets s, in big-endian order.
+
+3.5 Text
+
+   The only character set for text is the UTF-8 encoding [RFC-2279] of
+   Unicode characters [ISO-10646]. All text MUST be in Unicode
+   Normalization Form KC [UNICODE-KC] without NUL characters.
+
+   In addition, to avoid non-interoperability due to incompatible
+   normalisation techniques, the client MUST prepare strings using the
+   [SASLprep] profile of [RFC-3454]
+
+   We shall use the syntax utf8(L) to denote the string L in UTF-8
+   encoding, preceded by a two-octet scalar quantity representing the
+   count of following octets.  Furthermore, we shall use the syntax
+   bytes(L) to denote the sequence of octets representing the UTF-8
+   encoding of L, in big-endian order.
+
+   Not that the empty string is encoded as the two octet sequence 00 00.
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 7]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+3.6 Buffers
+
+   In this mechanism data is exchanged between the client and server
+   using buffers.  A buffer acts as an envelope for the sequence of data
+   elements sent by one end-point of the exchange, and expected by the
+   other.
+
+   A buffer MAY NOT contain other buffers.  It may only contain zero,
+   one or more data elements.
+
+   A buffer shall be encoded as two fields: a four-octet scalar quantity
+   representing the count of following octets, and the concatenation of
+   the octets of the data element(s) contained in the buffer.
+
+   We shall use the syntax {A|B|C} to denote a buffer containing A, B
+   and C in that order.  For example:
+
+      { mpi(N) | mpi(g) | utf8(L) }
+
+   is a buffer containing, in the designated order, the encoded forms of
+   an MPI N, an MPI g and a Text L.
+
+3.7 Data Element Size Limits
+
+   The following table details the size limit, in number of octets, for
+   each of the data element encodings described earlier.
+
+      Data element type          Header       Size limit in octets
+                                (octets)       (excluding header)
+      ------------------------------------------------------------
+      Octet Sequence               1                  255
+      MPI                          2                 65,535
+      Text                         2                 65,535
+      Extended Octet Sequence      4             2,147,483,383
+      Buffer                       4             2,147,483,643
+
+   An implementation MUST signal an exception if any size constraint is
+   violated.
+
+3.8 Unsigned Integers
+
+   This mechanism uses unsigned integer values ranging from zero to
+   4,294,967,296.
+
+   When such entities travel on the wire, they shall be encoded as
+   4-octet Scalar Numbers.  We shall use the syntax uint(n) to denote
+   the encoding of an Unsigned Integer n.
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 8]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+4. Protocol Description
+
+   The following sections describe the sequence of data transmitted
+   between the client and server for SRP authentication, as well as the
+   extra control information exchanged to enable a client to request
+   whether or not replay detection, integrity protection and/or
+   confidentiality protection should be provided by a security layer.
+   There are two possible mechanism data exchanges during the
+   authentication phase:
+
+   The following exchange occurs when a new session is negotiated
+   between the client and the server.  It will also occur when the
+   client requests re-use of the parameters of a previous session and
+   either the server does not support such re-use or no longer considers
+   the previous session to be valid:
+
+    Client                                                   Server
+
+    ---  { utf8(U) | utf8(I) | utf8(sid) | os(cn) }  ------------->
+
+    <------ { 00 | mpi(N) | mpi(g) | os(s) | mpi(B) | utf8(L) } ---
+
+    ---  { mpi(A) | os(M1) | utf8(o) | os(cIV) }  ---------------->
+
+    <------ { os(M2) | os(sIV) | utf8(sid) | uint(ttl) }  ---------
+
+   where:
+
+      U   is the authentication identity (username),
+
+      I   is the authorisation identity (userid),
+
+      sid is the identifier of a previous session whose parameters the
+      client wishes to re-use,
+
+      cn  is the client's nonce used in deriving a new shared context
+      key from the shared context key of the previous session,
+
+      00  is an octet indicating that the previous session parameters
+      will NOT be re-used,
+
+      N   is the safe prime modulus,
+
+      g   is the generator,
+
+      s   is the user's password salt,
+
+      B   is the server's ephemeral public key,
+
+
+
+Burdis & Naffah        Expires November 28, 2003                [Page 9]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      L   is the options list indicating available security services,
+
+      A   is the client's ephemeral public key,
+
+      M1  is the client's evidence that the shared key K is known,
+
+      o   is the options list indicating chosen security services,
+
+      cIV is the client's initial vector for the chosen encryption
+      algorithm,
+
+      M2  is the server's evidence that the shared key K is known.
+
+      sIV is the server's initial vector for the chosen encryption
+      algorithm,
+
+      sid is the identifier the server gives to this session for
+      possible later re-use of the negotiated parameters,
+
+      ttl is the time period for which this session's parameters may be
+      re-usable,
+
+   The following exchange occurs when the client requests that the
+   parameters negotiated in a previous session be re-used in this
+   session, but with a newly derived shared context key, and the server
+   agrees:
+
+    Client                                                   Server
+
+    ---  { utf8(U) | utf8(I) | utf8(sid) | os(cn) }  -------------->
+
+    <----------------------------------  { FF | os(sn) }  ----------
+
+   where:
+
+      U   is the authentication identity (username),
+
+      I   is the authorisation identity (userid),
+
+      sid is the identifier of a previous session whose parameters the
+      client wishes to re-use,
+
+      cn  is the client's nonce used in deriving a new shared context
+      key from the shared context key of the previous session,
+
+      FF  is an octet indicating that the previous session parameters
+      WILL be re-used,
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 10]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      sn  is the server's nonce used in deriving a new shared context
+      key from the shared context key of the previous session,
+
+
+4.1 Client Sends its Identity
+
+   The client determines its authentication identity U and authorisation
+   identity I, encodes them and sends them to the server.
+
+   The semantics of both U and I are intended to be the same as
+   described in [SASL].  Specifically, the authentication identity U is
+   derived from the client's authentication credentials, and the
+   authorisation identity I is used by the server as the primary
+   identity for making access policy decisions.
+
+   As a client might not have the same information as the server,
+   clients SHOULD NOT themselves try to derive authorisation identities
+   from authentication identities.  When an authorisation identity is
+   not specified by the user the client SHOULD send an empty string
+   instead.
+
+   If the client does not wish to re-use parameters negotiated in a
+   previous session then it sets sid to the empty string and cn to a
+   zero-length octet sequence.
+
+   However, if the client does wish to attempt to re-use the parameters
+   negotiated in a previous session then it sets sid to the session
+   identifier for that session, and sets cn as follows:
+
+      cn = prng()
+
+   where:
+
+      prng()  is a random number generation function that outputs at
+      least 16 octets of data.
+
+   See Section 6.4 for more information on re-using negotiated
+   parameters of a previous session.
+
+   The client sends:
+
+      { utf8(U) | utf8(I) | utf8(sid) | os(cn) }
+
+
+4.2 Server Agrees to Re-use Parameters of a Previous Session
+
+   If the server supports re-using the parameters negotiated in a
+   previous session and it considers the previous session, identified by
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 11]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   the session identifier (sid) received from the client, to be valid,
+   it responds as follows:
+
+   The server sends the octet FF as the first element of the message to
+   indicate to the client that parameters of the previous session are
+   being re-used.  It also generates a nonce (sn), which is later used
+   in deriving a new shared context key for this session:
+
+      sn = prng()
+
+   where:
+
+      prng()  is a random number generation function that outputs at
+      least 16 octets of data.
+
+   Note that the server nonce (sn) MUST NOT be the same as the client
+   nonce (cn).
+
+   The server sends:
+
+      { FF | os(sn) }
+
+   See Section 6.4 for more information on re-using negotiated
+   parameters of a previous session and deriving the new shared context
+   key.
+
+4.3 Server Sends Protocol Elements
+
+   Otherwise, the server receives U and looks up the safe prime modulus
+   N, the generator g, the salt s, and the verifier v, to be used for
+   that identity.  It uses the this information to generate its
+   ephemeral public key B as follows:
+
+      b = prng();
+
+      B = ((3 * v) + (g ** b)) % N;
+
+   where:
+
+      prng() is a random number generation function,
+
+      b      is the MPI that will act as the server's private key,
+
+      v      is the stored password verifier value,
+
+      g      is the generator,
+
+      N      is the safe prime modulus,
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 12]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      *      is the multiplication operator,
+
+      +      is the addition operator,
+
+      **     is the exponentiation operator,
+
+      %      is the modulus operator,
+
+   The server also creates an options list L, which consists of a
+   comma-separated list of option strings that specify the options the
+   server supports.  This options list MUST NOT contain any whitespace
+   characters and all alphabetic characters MUST be in lowercase.  When
+   used in digest calculations by the client the options list MUST be
+   used as received.
+
+   The following option strings are defined:
+
+   o  "mda=<MDA-name>" indicates that the server supports the designated
+      hash function as the underlying Message Digest Algorithm for the
+      designated user to be used for all SRP calculations - to compute
+      both client-side and server-side digests.  The specified algorithm
+      MUST meet the requirements specified in section 3.2 of [RFC-2945]:
+
+         "Any hash function used with SRP should produce an output of at
+         least 16 bytes and have the property that small changes in the
+         input cause significant nonlinear changes in the output."
+
+      Note that in the interests of interoperability between client and
+      server implementations and with other SRP-based tools, both the
+      client and the server MUST support SHA-160 as an underlying
+      Message Digest Algorithm.  While the server is not required to
+      list SHA-160 as an available underlying Message Digest Algorithm,
+      it must be able to do so.
+
+   o  "integrity=hmac-<MDA-name>" indicates that the server supports
+      integrity protection using the HMAC algorithm [RFC-2104] with
+      <MDA-name> as the underlying Message Digest Algorithm.  Acceptable
+      MDA names are chosen from [SCAN] under the MessageDigest section.
+      A server SHOULD send such an option string for each HMAC algorithm
+      it supports.  The server MUST advertise at least one integrity
+      protection algorithm and in the interest of interoperability the
+      server SHOULD advertise support for the HMAC-SHA-160 algorithm.
+
+   o  "replay_detection" indicates that the server supports replay
+      detection using sequence numbers.  Replay detection SHALL NOT be
+      activated without also activating integrity protection.  If the
+      replay detection option is offered (by the server) and/or chosen
+      (by the client) without explicitly specifying an integrity
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 13]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      protection option, then the default integrity protection option
+      "integrity=hmac-sha-160" is implied and SHALL be activated.
+
+   o  "confidentiality=<cipher-name>" indicates that the server supports
+      confidentiality protection using the symmetric key block cipher
+      algorithm <cipher-name>.  The server SHOULD send such an option
+      string for each confidentiality protection algorithm it supports.
+      Note that in the interest of interoperability, if the server
+      offers confidentiality protection, it MUST send the option string
+      "confidentiality=aes" since it is then MANDATORY for it to provide
+      support for the [AES] algorithm.
+
+   o  "mandatory=[integrity|replay_detection|confidentiality]" is an
+      option only available to the server that indicates that the
+      specified security layer option is MANDATORY and MUST be chosen by
+      the client for use in the resulting security layer.  If a server
+      specifies an option as mandatory in this way, it MUST abort the
+      connection if the specified option is not chosen by the client.
+      It doesn't make sense for the client to send this option since it
+      is only able to choose options that the server advertises.  The
+      client SHOULD abort the connection if the server does not offer an
+      option that it requires.  If this option is not specified then
+      this implies that no options are mandatory.  The server SHOULD
+      always send the "mandatory=integrity" option indicating that
+      integrity protection is required.
+
+   o  "maxbuffersize=<number-of-bytes>" indicates to the peer the
+      maximum number of raw bytes (excluding the buffer header) to be
+      processed by the security layer at a time, if one is negotiated.
+      The value of <number-of-bytes> MUST NOT exceed the Buffer size
+      limit defined in section 3.7.  If this option is not detected by a
+      client or server mechanism, then it shall operate its security
+      layer on the assumption that the maximum number of bytes that may
+      be sent, to the peer server or client mechanism respectively, is
+      the Buffer data size limit indicated in section 3.7.  On the other
+      hand, if a recipient detects this option, it shall break any
+      octet-sequence longer than the designated limit into two or more
+      fragments, before sending them separately, in sequence, to the
+      peer.
+
+   For example, if the server supports integrity protection using the
+   HMAC-SHA-160 and HMAC-MD5 algorithms, replay detection and no
+   confidentiality protection, the options list would be:
+
+      mda=sha-1,integrity=hmac-sha-160,integrity=hmac-md5,replay_detection
+
+   The server sends the octet 00 as the first element of the message to
+   indicate to the client that parameters from a previous session are
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 14]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   NOT being used.
+
+   The server sends:
+
+      { 00 | mpi(N) | mpi(g) | os(s) | mpi(B) | utf8(L) }
+
+
+4.4 Client Sends its Ephemeral Public Key and Evidence
+
+   The client receives the options list L from the server that specifies
+   the Message Digest Algorithm(s) available to be used for all SRP
+   calculations, the security service options the server supports,
+   including the maximum buffer size the server can handle, and the
+   server's ephemeral public key B.  The client selects options from
+   this list and creates a new options list o that specifies the
+   selected Message Digest Algorithm to be used for SRP calculations and
+   the security services that will be used in the security layer.  At
+   most one available Message Digest Algorithm name, one available
+   integrity protection algorithm and one available confidentiality
+   protection algorithm may be selected.  In addition the client may
+   specify the maximum buffer size it can handle.  The client MUST
+   include any option specified by the mandatory option.
+
+   The client SHOULD always select an integrity protection algorithm
+   even if the server does not make it mandatory to do so.  If the
+   client selects a confidentiality protection algorithm it SHOULD then
+   also select an integrity protection algorithm.
+
+   The options list o MUST NOT contain any whitespace characters and all
+   alphabetic characters MUST be in lowercase.  When used in digest
+   calculations by the server the options list MUST be used as received.
+
+   The client generates its ephemeral public key A as follows:
+
+      a = prng();
+
+      A = (g ** a) % N;
+
+   where:
+
+      a      is the MPI that will act as the client's private key,
+
+   The client also calculates the shared context key K, and calculates
+   the evidence M1 that proves to the server that it knows the shared
+   context key K, as well as the server's ephemeral public key B, the
+   user's authorisation identity I and the server's options list L.
+
+   K, on the client's side is computed as follows:
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 15]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      x = H(s | H(U | ":" | p));
+
+      u = H(A | B);
+
+      S = ((B - (3 * (g ** x))) ** (a + (u * x))) % N;
+
+      K = H(S);
+
+   where:
+
+      s    is the user's password salt,
+
+      U    is the authentication identity (username),
+
+      p    is the password value.
+
+      A    is the client's ephemeral public key,
+
+      B    is the server's ephemeral public key,
+
+      g    is the generator,
+
+      N    is the safe prime modulus,
+
+      H()  is the result of digesting the designated input/data with the
+      chosen underlying Message Digest Algorithm function.
+
+      -    is the subtraction operator,
+
+      *    is the multiplication operator,
+
+      +    is the addition operator,
+
+      **   is the exponentiation operator,
+
+      %    is the modulus operator,
+
+   M1 is computed as:
+
+            H(   bytes(H( bytes(N) )) ^ bytes( H( bytes(g) ))
+               | bytes(H( bytes(U) ))
+               | bytes(s)
+               | bytes(A)
+               | bytes(B)
+               | bytes(K)
+               | bytes(H( bytes(I) ))
+               | bytes(H( bytes(L) ))
+             )
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 16]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   where:
+
+      ^    is the bitwise XOR operator.
+
+   All parameters received from the server that are used as input to a
+   digest operation MUST be used as received.
+
+   If the client chooses to activate the Confidentiality Protection
+   service in the Security Layer, it MUST send the Initial Vector cIV
+   that the server will use to set up its encryption context.  (See
+   Section 5.2 for details on the Confidentiality Protection service and
+   how cIV is generated.)  However, this element MAY be a zero-length
+   octet stream if the server does not advertise the Confidentiality
+   Protection service or the client decides not to activate it.
+
+   The client sends:
+
+      { mpi(A) | os(M1) | utf8(o) | os(cIV) }
+
+
+4.5 Server Verifies Client's Evidence and Sends its Evidence
+
+   The server calculates the shared context key K, and verifies the
+   client's evidence M1.
+
+   K, on the server's side is computed as follows:
+
+      u = H(A | B);
+
+      S = ((A * (v ** u)) ** b) % N;
+
+      K = H(S);
+
+   where:
+
+      A    is the client's ephemeral public key,
+
+      B    is the server's ephemeral public key,
+
+      v    is the stored password verifier value,
+
+      b    is the server's ephemeral private key,
+
+      N    is the safe prime modulus,
+
+      H()  is the result of digesting the designated input/data with the
+      chosen underlying Message Digest Algorithm function.
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 17]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      *    is the multiplication operator,
+
+      **   is the exponentiation operator,
+
+      %    is the modulus operator,
+
+   If the client chose to activate the Confidentiality Protection
+   service in the Security Layer then the server MUST send the Initial
+   Vector sIV that the client will use to set up its encryption context.
+   (See Section 5.2 for details on the Confidentiality Protection
+   service and how sIV is generated.)  However, this element MAY be a
+   zero-length octet sequence if the client did not choose to activate
+   the Confidentiality Protection service.
+
+   If the server's policy allows re-using the parameters of this session
+   then it sets sid to a unique identifier for this session and sets ttl
+   to the number of seconds for which the session MAY be valid.  If the
+   server does not support re-using the parameters of this session then
+   it sets sid to the empty string and ttl to any value.  See Section
+   6.4 for more information on re-using negotiated parameters of a
+   previous session.
+
+   The server computes its evidence M2, which proves to the client that
+   it knows the shared context key K, as well as U, I and o, as follows:
+
+            H(   bytes(A)
+               | bytes(M1)
+               | bytes(K)
+               | bytes(H( bytes(I) ))
+               | bytes(H( bytes(o) ))
+               | bytes(sid)
+               | ttl
+            )
+
+   All parameters received from the client that are used as input to a
+   digest operation MUST be used as received.
+
+   The server sends:
+
+      { os(M2) | os(sIV) | sid | ttl }
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 18]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+5. Security Layer
+
+   Depending on the options offered by the server and chosen by the
+   client, the security layer may provide integrity protection, replay
+   detection, and/or confidentiality protection.
+
+   The security layer can be thought of as a three-stage filter through
+   which the data flows from the output of one stage to the input of the
+   following one.  The first input is the original data, while the last
+   output is the data after being subject to the transformations of this
+   filter.
+
+   The data always passes through this three-stage filter, though any of
+   the stages may be inactive.  Only when a stage is active would the
+   output be different from the input.  In other words, if a stage is
+   inactive, the octet sequence at the output side is an exact duplicate
+   of the same sequence at the input side.
+
+   Schematically, the three-stage filter security layer appears as
+   follows:
+
+                 +----------------------------+
+                 |                            |     I/ p1
+         p1  --->| Confidentiality protection |---+
+                 |                            |   | A/ c
+                 +----------------------------+   |
+                                                  |
+             +------------------------------------+
+             |
+             |   +----------------------------+
+             |   |                            |     I/ p2
+         p2  +-->|      Replay detection      |---+
+                 |                            |   | A/ p2 | q
+                 +----------------------------+   |
+                                                  |
+             +------------------------------------+
+             |
+             |   +----------------------------+
+             |   |                            |     I/ p3
+         p3  +-->|    Integrity protection    |--->
+                 |                            |     A/ p3 | C
+                 +----------------------------+
+
+   where:
+
+      p1, p2 and p3 are the input octet sequences at each stage,
+
+      I/ denotes the output at the end of one stage if/when the stage is
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 19]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      inactive or disabled,
+
+      A/ denotes the output at the end of one stage if/when the stage is
+      active or enabled,
+
+      c is the encrypted (sender-side) or decrypted (receiver-side)
+      octet sequence.  c1 shall denote the value computed by the sender,
+      while c2 shall denote the value computed by the receiver.
+
+      q is a four-octet scalar quantity representing a sequence number,
+
+      C is the Message Authentication Code.  C1 shall denote the value
+      of the MAC as computed by the sender, while C2 shall denote the
+      value computed by the receiver.
+
+   It is worth noting here that both client and server have their own
+   distinct security contexts, including distinct encryption and
+   decryption sub-contexts.  In principal, nothing in this specification
+   should prevent an implementation from supporting asynchronous
+   connections.
+
+5.1 Cryptographic Primitives
+
+5.1.1 Pseudo Random Number Generator
+
+   This mechanism requires random data to be generated for use in:
+
+   1.  The CALG key material for both the client and server when the
+       Confidentiality Protection service is enabled.
+
+   2.  The IALG key material for both the client and server when the
+       Integrity Protection service is enabled.
+
+   The PRNG used in this specification is based on the pseudo-random
+   function described in section 5 of [UMAC].  It uses the [AES]
+   algorithm, in its 128-bit key size variant, as the underlying
+   symmetric key block cipher for its operations.
+
+   A formal description of this PRNG follows:
+
+   o  Initialisation
+
+      *  SK: a 16-octet sequence (seeding key to AES)
+
+   o  Input
+
+      *  n: a positive integer
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 20]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   o  Output
+
+      *  Y: an n-octet sequence
+
+   o  Algorithm
+
+      *  (initialisation)
+
+         1.  Initialise an AES instance for encryption with the first 16
+             octets of SK as its user-supplied key material.  Let "aes"
+             be that instance; i.e. aes = AES(SK, ENCRYPTION);
+
+         2.  Initialise T to be an all-zero 16-octet long sequence;
+
+      *  (for every input)
+
+         1.  Initialise "remaining" to n;
+
+         2.  Initialise Y to be a 0-length octet sequence;
+
+         3.  while (remaining > 0) do
+
+             1.  T = aes(T);
+
+             2.  Append m octets from T to Y, where m is the minimum of
+                 16 and remaining;
+
+             3.  Subtract 16 from remaining;
+
+         4.  return Y;
+
+   In this document, "PRNG(key,n)" will refer to this algorithm, with
+   the initialisation parameter SK set to be the octets of the specified
+   key, returning n bits of pseudo-random data.  For example,
+   "PRNG(K,n)" will refer to this algorithm, with the initialisation
+   parameters SK set to the shared context key K computed by the SRP
+   calculations (see Section 4.4 and Section 4.5), returning n bits of
+   pseudo-random data.
+
+   This algorithm MAY also be used as part of the SRP calculations to
+   generate the required "a" and "b" parameters used in creating the
+   client and server ephemeral private keys ("A" and "B"), or to
+   generate the cn and sn parameters used in session re-use, or to
+   generate the initial vectors sIV and cIV used to set up the
+   encryption contexts. In this case the initialisation parameter SK can
+   be any 16-octet sequence (e.g. multiple representations of the
+   time-of-day).
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 21]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   If the same PRNG instance is used for both these calculations and the
+   calculations in this specification, it MUST be re-initialised with
+   the shared context key K before any of the latter calculations are
+   performed.
+
+5.1.2 Key Derivation Function
+
+   During the authentication phase, both parties compute the shared
+   context key K (see Section 4.4 for the client, and Section 4.5 for
+   the server sides respectively).  The length of K is s bits, where "s"
+   is the output length of the chosen underlying Message Digest
+   Algorithm used in the SRP calculations (see "mda" option in Section
+   4.3).
+
+   When Confidentiality Protection is required, and the length of K is
+   not equal to the length of the user-supplied key material needed to
+   initialise the chosen Confidentiality Algorithm (CALG), the peers
+   MUST apply the Key Derivation Function (KDF) in order to obtain
+   enough data for this purpose.
+
+   Similarly, when Integrity Protection is required, and the length of K
+   is not equal to the required length of the key material needed to
+   initialise the chosen Integrity Algorithm (IALG), the peers MUST
+   apply the Key Derivation Function (KDF) in order to obtain enough
+   data for this purpose too.
+
+   If the KDF is required for both the key used with the CALG and the
+   key used with the IALG then it is first applied for the CALG key and
+   thereafter for the IALG key.
+
+   We define this KDF as:
+
+      Km = KDF(n)
+
+   where:
+
+      Km  is the required key material,
+
+      K   is the shared context key, and
+
+      n   is the required length of Km.
+
+   The following steps describe the KDF algorithm:
+
+      If length of K is greater than or equal to n, then
+
+         Let Km be the first n bytes of K;
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 22]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      Else
+
+         Let Km = PRNG(K, n);
+
+      return Km
+
+
+5.2 Confidentiality Protection
+
+   The plaintext data octet sequence p1 is encrypted using the chosen
+   confidentiality algorithm (CALG) with key size m, initialised for
+   encryption with the key material Kc obtained as follows:
+
+      Kc = KDF(m)
+
+      c1 = CALG(Kc, ENCRYPTION)( bytes(p1) )
+
+   On the receiving side, the ciphertext data octet sequence p1 is
+   decrypted using the chosen confidentiality algorithm (CALG)
+   initialised for decryption, with the key Kc obtained by a similar
+   process:
+
+      Kc = KDF(m)
+
+      c2 = CALG(Kc, DECRYPTION)( bytes(p1) )
+
+   The designated CALG symmetric-key block cipher MUST be used in OFB
+   (Output Feedback Block) mode in the ISO variant, as described in
+   [HAC], algorithm 7.20.
+
+   Let k be the block size of the chosen symmetric key block cipher
+   algorithm; e.g. for AES this is 128 bits or 16 octets. The OFB mode
+   used shall have a block size of k.
+
+   It is recommended that block ciphers operating in OFB mode be used
+   with an Initial Vector (the mode's IV).  In such a mode of operation
+   - OFB with key re-use - the IV need not be secret.  For the mechanism
+   described in this document, the server MUST use cIV received from the
+   client as the Initial Vector when initialising its encryption
+   context, and the client MUST use sIV received from the server as the
+   Initial Vector when initialising its encryption context.  These
+   Initial Vectors are generated as:
+
+      cIV = prng(k);
+
+      sIV = prng(k);
+
+   where:
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 23]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      prng() is a random number generation function that outputs k
+      octets of data,
+
+      k      is the block size of the chosen symmetric key block cipher
+      algorithm
+
+   The input data to the confidentiality protection algorithm shall be a
+   multiple of the symmetric key block cipher block size k.  When the
+   input length is not a multiple of k octets, the data shall be padded
+   according to the following scheme (described in [PKCS7] which itself
+   is based on [RFC-1423]):
+
+      Assuming the length of the input is l octets, (k - (l mod k))
+      octets, all having the value (k - (l mod k)), shall be appended to
+      the original data.  In other words, the input is padded at the
+      trailing end with one of the following sequences:
+
+
+
+                   01 -- if l mod k = k-1
+                  02 02 -- if l mod k = k-2
+                            ...
+                            ...
+                            ...
+                k k ... k k -- if l mod k = 0
+
+      The padding can be removed unambiguously since all input is padded
+      and no padding sequence is a suffix of another.  This padding
+      method is well-defined if and only if k < 256 octets, which is the
+      case with symmetric block ciphers today, and in the forseeable
+      future.
+
+   The output of this stage, when it is active, is:
+
+      at the sending side: CALG(Kc, ENCRYPT)( bytes(p1) )
+
+      at the receiving side: CALG(Kc, DECRYPT)( bytes(p1) )
+
+
+5.3 Replay Detection
+
+   A sequence number q is incremented every time a message is sent to
+   the peer.
+
+   The output of this stage, when it is active, is:
+
+      p2 | q
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 24]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   At the other end, the receiver increments its instance of the
+   sequence number.  This new value of the sequence number is then used
+   in the integrity protection transformation, which must also be active
+   as described in Section 4.3.  See Section 6.3 for more details.
+
+5.4 Integrity Protection
+
+   When the Integrity Protection stage is active, a message
+   authentication code C is computed using the chosen integrity
+   protection algorithm (IALG) as follows:
+
+   o  the IALG is initialised (once) with the key material Ki of size n
+      (the required key size of the chosen IALG); i.e. Ki = KDF(n),
+
+   o  the IALG is updated with every exchange of the sequence p3,
+      yielding the value C and a new IALG context for use in the
+      following exchange.
+
+   At the other end, the receiver computes its version of C, using the
+   same transformation, and checks that its value is equal to that
+   received. If the two values do not agree, the receiver MUST signal an
+   exception and abort.
+
+   The output of this stage, when it is active, is then:
+
+      IALG(Ki)( bytes(p3) )
+
+
+5.5 Summary of Security Layer Output
+
+   The following table shows the data exchanged by the security layer
+   peers, depending on the possible legal combinations of the three
+   security services in operation:
+
+      CP   IP   RD   Peer sends/receives
+
+      I    I    I    { eos(p) }
+      I    A    I    { eos(p) | os( IALG(Ki)( bytes(p) ) ) }
+      I    A    A    { eos(p) | os( IALG(Ki)( bytes(p) | bytes(q)) ) }
+      A    I    I    { eos(c) }
+      A    A    I    { eos(c) | os( IALG(Ki)( bytes(c) ) ) }
+      A    A    A    { eos(c) | os( IALG(Ki)((bytes(c) | bytes(q)) )}
+
+   where
+
+      CP    Confidentiality protection,
+
+      IP    Integrity protection,
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 25]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      RD    Replay detection,
+
+      I     Security service is Inactive/disabled,
+
+      A     Security service is Active/enabled,
+
+      p     The original plaintext,
+
+      q     The sequence number.
+
+      c     The enciphered input obtained by either:
+
+         CALG(Kc, ENCRYPT)( bytes(p) ) at the sender's side, or
+
+         CALG(Kc, DECRYPT)( bytes(p) ) at the receiver's side
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 26]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+6. Discussion
+
+6.1 Mandatory Algorithms
+
+   The algorithms specified as mandatory were chosen for utility and
+   availablity.  We felt that a mandatory confidentiality and integrity
+   protection algorithm for the security layer and a mandatory Message
+   Digest Algorithm for SRP calculations should be specified to ensure
+   interoperability between implementations of this mechanism:
+
+   o  The SHA-160 Message Digest Algorithm was chosen as an underlying
+      algorithm for SRP calculations because this allows for easy
+      interoperability with other SRP-based tools that use the SRP-SHA1
+      protocol described in section 3 of [RFC-2945] and create their
+      password files using this algorithm.
+
+   o  The HMAC algorithm was chosen as an integrity algorithm because it
+      is faster than MAC algorithms based on secret key encryption
+      algorithms [RFC-2847].
+
+   o  AES was chosen as a symmetric-key block cipher because it has
+      undergone thorough scrutiny by the best cryptographers in the
+      world.
+
+   Since confidentiality protection is optional, this mechanism should
+   be usable in countries that have strict controls on the use of
+   cryptography.
+
+6.2 Modulus and Generator Values
+
+   It is RECOMMENDED that the server use values for the modulus N and
+   generator g chosen from those listed in Appendix A so that the client
+   can avoid expensive constraint checks, since these predefined values
+   already meet the constraints described in [RFC-2945]:
+
+      "For maximum security, N should be a safe prime (i.e. a number of
+      the form N = 2q + 1, where q is also prime).  Also, g should be a
+      generator modulo N (see [SRP] for details), which means that for
+      any X where 0 < X < N, there exists a value x for which g**x == X
+      (mod N).
+
+   If other values are used for N and g then these values SHOULD undergo
+   the specified constraint checks.
+
+6.3 Replay Detection Sequence Number Counters
+
+   The mechanism described in this document allows the use of a Replay
+   Detection security service that works by including sequence number
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 27]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   counters in the message authentication code (MAC) created by the
+   Integrity Protection service.  As noted in Section 4.3 integrity
+   protection is always activated when the Replay Detection service is
+   activated.
+
+   Both the client and the server keep two sequence number counters.
+   Each of these counters is a 32-bit unsigned integer initialised with
+   a Starting Value and incremented by an Increment Value with every
+   successful transmission of a data buffer through the security layer.
+   The Sent counter is incremented for each buffer sent through the
+   security layer. The Received counter is incremented for each buffer
+   received through the security layer.  If the value of a sequence
+   number counter exceeds 2**32-1 it wraps around and starts from zero
+   again.
+
+   When a sender sends a buffer it includes the value of its Sent
+   counter in the computation of the MAC accompanying each integrity
+   protected message.  When a recipient receives a buffer it uses the
+   value of it's Received counter in its computation of the integrity
+   protection MAC for the received message.  The recipient's Received
+   counter must be the same as the sender's Sent counter in order for
+   the received and computed MACs to match.
+
+   This specification assumes that for each sequence number counter the
+   Starting Value is ZERO, and that the Increment Value is ONE.  These
+   values do not affect the security or the intended objective of the
+   replay detection service, since they never travel on the wire.
+
+6.4 Re-using the Parameters of a Previous Session
+
+   Re-using the parameters of a previous session enables the client and
+   server to avoid the overhead of the full authentication exchange
+   where the client and server communicate more than once during a
+   server-specified time period.
+
+   Servers are not required to support re-using the parameters of the
+   current session in future sessions.  If they do not wish to support
+   this then they send an empty string for the session identifier (sid).
+   However, if the server's policy allows for the parameters of the
+   current session to be re-used later, it generates a session
+   identifier (sid) that will uniquely identify the session within the
+   specified time period (ttl).  The time period (ttl) is specified in
+   seconds and only gives an indication to the client how long the
+   session  may be valid. The server is not required to ensure that the
+   session is valid for this time period. Note that a ttl of 0 indicates
+   an indeterminate time period.
+
+   To avoid session hijacking, servers SHOULD NOT indicate that a
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 28]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   session may be re-used unless a security layer with integrity
+   protection and/or confidentiality protection has been negotiated.
+
+   Clients are not required to support re-using the parameters of
+   previous sessions.  If they do not wish to support it or they do not
+   wish to re-use the parameters of a previous session then they send
+   the empty string as the value for the session identifier (sid) and
+   send a zero-length octet sequence for the nonce (cn).  If they do
+   support it and wish to use the parameters of a previous session then
+   they send the session identifier for this session that they
+   previously received from the server and calculate cn as described in
+   Section 4.1.
+
+   If a client specifies a session id (sid) for a session that the
+   server still considers valid then the server sends the octet FF, to
+   indicate to the client that parameters of a previous session are
+   being re-used, and the nonce (sn) calculated as described in Section
+   4.2.  The client and server then calculate the new shared context key
+   Kn for this session as follows:
+
+      Kn = H(K | cn | sn)
+
+   where:
+
+      K    is the shared context key for the previous session identified
+      by sid.
+
+      H()  is the result of digesting the designated input/data with the
+      Message Digest Algorithm function negotiated in the previous
+      session identified by sid.
+
+   Then, if the confidentiality and/or integrity protection services
+   were negotiated for the previous session, new keys for these services
+   are derived using the KDF for use in this session.  (See Section
+   5.1.2.)
+
+   If the server does not support re-using parameters of previous
+   sessions or no longer considers the specified previous session to be
+   valid, it ignores the session id specified by the client and
+   continues the full authentication exchange.  However, the first
+   element of the next buffer it sends is the octet 00, which indicates
+   to the client that no parameters of a previous session will be
+   re-used.
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 29]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+7. SASL
+
+7.1 Overview
+
+   SASL is described as follows [RFC-2222]:
+
+      The Simple Authentication and Security Layer (SASL) is a method
+      for adding authentication support to connection-based protocols.
+
+   This document describes a mechanism that can be used within the SASL
+   authentication framework.
+
+7.2 Mechanism Name
+
+   The SASL mechanism name associated with this protocol is "SRP".
+
+7.3 Security Layer
+
+   Section 3 of [RFC-2222] describes the operation of the security layer
+   as follows:
+
+      "The security layer takes effect immediately following the last
+      response of the authentication exchange for data sent by the
+      client and the completion indication for data sent by the server.
+      Once the security layer is in effect, the protocol stream is
+      processed by the security layer into buffers of cipher-text.  Each
+      buffer is transferred over the connection as a stream of octets
+      prepended with a four octet field in network byte order that
+      represents the length of the following buffer.  The length of the
+      cipher-text buffer must be no larger than the maximum size that
+      was defined or negotiated by the other side."
+
+
+7.4 Profile Considerations
+
+   As mentioned briefly in [RFC-2222], and detailed in [SASL] a SASL
+   specification has three layers: (a) a protocol definition using SASL
+   known as the "Profile", (b) a SASL mechanism definition, and (c) the
+   SASL framework.
+
+   Point (3) in section 5 of [SASL] ("Protocol profile requirements")
+   clearly states that it is the responsibility of the Profile to define
+   "...how the challenges and responses are encoded, how the server
+   indicates completion or failure of the exchange, how the client
+   aborts an exchange, and how the exchange method interacts with any
+   line length limits in the protocol."
+
+   The username entity, referenced as U throughout this document, and
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 30]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   used by the server to locate the password data, is assumed to travel
+   "in the clear," meaning that no transformation is applied to its
+   contents. This assumption was made to allow the same SRP password
+   files to be used in this mechanism, as those used with other SRP
+   applications and tools.
+
+   A Profile may decide, for privacy or other reason, to disallow such
+   information to travel in the clear, and instead use a hashed version
+   of U, or more generally a transformation function applied to U; i.e.
+   f(U).  Such a Profile would require additional tools to add the
+   required entries to the SRP password files for the new value(s) of
+   f(U).  It is worth noting too that if this is the case, and the same
+   user shall access the server through this mechanism as well as
+   through other SRP tools, then at least two entries, one with U and
+   the other with f(U) need to be present in the SRP password files if
+   those same files are to be used for both types of access.
+
+7.5 Example
+
+   The example below uses SMTP authentication [RFC-2554]. The base64
+   encoding of challenges and responses, as well as the reply codes
+   preceding the responses are part of the SMTP authentication
+   specification, not part of this SASL mechanism itself.
+
+   "C:" and "S:" indicate lines sent by the client and server
+   respectively.
+
+    S: 220 smtp.example.com ESMTP server ready
+
+    C: EHLO zaau.example.com
+
+    S: 250-smtp.example.com
+    S: 250 AUTH SRP CRAM-MD5 DIGEST-MD5
+
+    C: AUTH SRP AAAADAAEdGVzdAAEdGVzdA==
+
+     with:
+
+       U = "test"
+
+       I = "test"
+
+    S: 334 AAABygEArGvbQTJKmpvxZt5eE4lYL69ytmUZh+4H/DGSlD21YFCjcynLtKCZ
+    7YGT4HV3Z6E91SMSq0sDMQ3Nf0ip2gT9UOgIOWntt2ewz2CVF5oWOrNmGgX71fqq6Ck
+    YqZYvC5O4Vfl5k+yXXuqoDXQK2/T/dHNZ0EHVwz6nHSgeRGsUdzvKl7Q6I/uAFna9IH
+    pDbGSB8dK5B4cXRhpbnTLmiPh3SFRFI7UksNV9Xqd6J3XS7PoDLPvb9S+zeGFgJ5AE5
+    Xrmr4dOcwPOUymczAQce8MI2CpWmPOo0MOCca41+Onb+7aUtcgD2J965DXeI21SX1R1
+    m2XjcvzWjvIPpxEfnkr/cwABAgqsi3AvmIqdEbREALhtZGE9U0hBLTEsbWFuZGF0b3J
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 31]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+    5PXJlcGxheSBkZXRlY3Rpb24scmVwbGF5IGRldGVjdGlvbixpbnRlZ3JpdHk9aG1hYy
+    1zaGExLGludGVncml0eT1obWFjLW1kNSxjb25maWRlbnRpYWxpdHk9YWVzLGNvbmZpZ
+    GVudGlhbGl0eT1jYXN0NSxjb25maWRlbnRpYWxpdHk9Ymxvd2Zpc2gsbWF4YnVmZmVy
+    c2l6ZT0yMTQ3NDgzNjQz
+
+     with:
+
+       N = "21766174458617435773191008891802753781907668374255538511144
+       6432246898862353838409572109090130860564015713997172358072665816
+       4960647214841029141336415219736447718088739565548373811507267740
+       2235101762521901569820740293149529620419333266262073471054548368
+       7360395197024862265062488610602569718029849535611214426801576680
+       0076142998822245709041387397397017192709399211475176516806361476
+       1119615476233422096442783117971236371647333871414335895773474667
+       3089670508070055093204247996784170368679283167612722742303140675
+       4829113358247958306143957755934710196177140617368437852270348349
+       5337037655006751328447510550299250924469288819"
+
+       g = "2"
+
+       s = "814819216327401865851972"
+
+       L = "mda=sha-1,mandatory=replay_detection,replay_detection,integ
+       rity=hmac-sha1,integrity=hmac-md5,confidentiality=aes,confidenti
+       ality=cast5,confidentiality=blowfish,maxbuffersize=2147483643"
+
+    C: AAABYwEAAp5q/4zhXoTUzXBscozN97SWgfDcAImIk3lNHNvd0b+Dr7jEm6upXblZ
+    T5sL9mPgFsejlIh+B/eCu/HvzWCrXj6ylPZv8dy3LCH3LIORqQ45S7Lsbmrrg/dukDh
+    4tZCJMLD4r3evzaY8KVhtJeLMVbeXuh4JljKP42Ll59Lzwf8jfPh4+4Lae1rpWUCL9D
+    ueKcY+nN+xNHTit/ynLATxwL93P6+GoGY4TkUbUBfjiI1+rAMvyMDMw5XozGy07FOEc
+    ++U0iPeXCQP4MT5FipOUoz8CYX7J1LbaXp2WJuFHlkyVXF7oCoyHbhld/5CfR3o6q/B
+    /x9+yZRqaHH+JfllOgBfbWRhPVNIQS0xLHJlcGxheSBkZXRlY3Rpb24saW50ZWdyaXR
+    5PWhtYWMtbWQ1LGNvbmZpZGVudGlhbGl0eT1ibG93ZmlzaCxtYXhidWZmZXJzaXplPT
+    IxNDc0ODM2NDM=
+
+     with:
+
+       A = "33059541846712102497463123211304342021934496372587869281515
+       9695658237779884462777478850394977744553746930451895815615888405
+       0562780707370878253753979367019077142882237029766166623275718227
+       6555389834190840322081091599089081947324537907613924707058150037
+       7802790776231793962143786411792516760030102436603621046541729396
+       6890613394379900527412007068242559299422872893332111365840536495
+       1858834742328835373387573188369956379881606380890675411966073665
+       1106922002294035533470301541999274557200666703389531481794516625
+       4757418442215980634933876533189969562613241499465295849832999091
+       40398081321840949606581251320320995783959866"
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 32]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+       o = mda=sha-1,replay_detection,integrity=hmac-md5,confidentialit
+       y=blowfish,maxbuffersize=2147483643"
+
+    S: 334 AAABAgEAOUKbXpnzMhziivGgMwm+FS8sKGSvjh5M3D+80RF/5z9rm0oPoi4+
+    pF83fueWn4Hz9M+muF/22PHHZkHtlutDrtapj4OtirdxC21fS9bMtEh3F0whTX+3mPv
+    thw5sk11turandHiLvcUZOgcrAGIoDKcBPoGyBud+8bMgpkf/uGfyBM2nEX/hV+oGgg
+    X+LiHjmkxAJ3kewfQPH0eV9ffEuuyu8BUcBXkJsS6l7eWkuERSCttVOi/jS031c+CD/
+    nuecUXYiF8IYzW03rbcwYhZzifmTi3VK9C8zG2K1WmGU+cDKlZMkyCPMmtCsxlbgE8z
+    SHCuCiOgQ35XhcA0Qa0C3Q==
+
+     with:
+
+       B: "722842847565031844205403087285424428589273458129750231766015
+       4465607827529853239240118185263492617243523916106658696965596526
+       8585300845435562962039149169549800169184521786717633959469278439
+       8771344445002432579509292115598435685062882631760796416554562980
+       8475896198325835507901319556929511421472132184990365213059654962
+       7218189966140113906545856088040473723048909402258929560823932725
+       2022154114087913895411927676707073040281136096806681758265221209
+       8822374723416364340410020172215773934302794679034424699999611678
+       9730443114919539575466941344964841591072763617954717789621871251
+       71089179399349194452686682517183909017223901"
+
+    C: AAAAFRTkoju6xGP+zH89iaDWIFjfIKt5Kg==
+
+    S: 235 Authentication successful.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 33]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+8. GSS-API
+
+8.1 Overview
+
+   The GSS-API is described as follows:
+
+      The Generic Security Service Application Program Interface
+      (GSS-API), Version 2, as defined in [RFC-2078], provides security
+      services to callers in a generic fashion, supportable with a range
+      of underlying mechanisms and technologies and hence allowing
+      source-level portability of applications to different
+      environments.
+
+   According to [RFC-2078] there are certain specifications related to
+   the GSS-API that are:
+
+      "documents defining token formats, protocols, and procedures to be
+      implemented in order to realize GSS-API services atop particular
+      security mechanisms"
+
+   This specification is such a document - it defines a security
+   mechanism that can be used with the GSS-API authentication framework.
+
+8.2 Terminology
+
+   The tokens referred to in the GSS-API specification [RFC-2078] are
+   the same as the buffers referred to in this document.
+
+8.3 Initial Token
+
+   [RFC-2078] states that:
+
+      The first context-level token obtained from GSS_Init_sec_context()
+      is required to indicate at its very beginning a
+      globally-interpretable mechanism identifier, i.e., an Object
+      Identifier (OID) of the security mechanism.  The remaining part of
+      this token as well as the whole content of all other tokens are
+      specific to the particular underlying mechanism used to support
+      the GSS-API.
+
+   To satisfy this requirement and make use of the mechanism described
+   in this document as a GSS-API mechanism, the following octets must be
+   prefixed to the first buffer sent as part of the protocol described
+   in Section 4:
+
+      [ 60 08 06 06 2B 06 01 05 05 08 ]
+
+   Each octet is written as a pair of hex digits - see Section 2.
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 34]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   These octets represent the encoding of the GSS-API mechanism
+   identifier as per section 3.1 of [RFC-2078].  The OID for this
+   mechanism is iso.org.dod.internet.security.mechanisms.srp
+   (1.3.6.1.5.5.8).
+
+   Note that it is not possible to make this requirement part of the
+   security protocol itself, because other authentication frameworks
+   have different requirements for the initial octets in a mechanism
+   buffer.
+
+8.4 Security Layer
+
+   This mechanism does not provide distinct replay detection and
+   sequencing services as part of the security layer.  Both of these
+   services are provided through the use of sequence numbers in
+   integrity protected messages.  If a GSS-API caller sets either the
+   replay_det_req_flag or the sequence_req_flag (section 1.2.3 of
+   [RFC-2078]) then this selects the "replay_detection" security
+   service.
+
+   This mechanism does not make use of any channel binding data (section
+   1.1.6 of [RFC-2078]).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 35]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+9. EAP
+
+9.1 Overview
+
+   The Extensible Authentication Protocol (EAP) [RFC-2284] is an
+   authentication framework that supports multiple authentication
+   mechanisms.  It is used with link layer protocols such as PPP and the
+   IEEE-802 wired and wireless protocols.
+
+9.2 Terminology
+
+   EAP uses the following terms to describe the entities involved in the
+   authentication exchange [rfc2284bis]:
+
+   Authenticator: The entity that initiates EAP authentication in order
+      to authenticate a Peer.
+
+   Peer: The entity that responds to requests from the Authenticator.
+
+   In this document, the Server corresponds to the Authenticator and the
+   Client corresponds to the Peer.
+
+9.3 Method Details
+
+   The EAP authentication method described in this document has the
+   following properties:
+
+   Method Name: SRP
+
+   Method Type: 7
+
+   As described in section 2 of [rfc2284bis] the EAP authentication
+   exchange is initiated by the Authenticator sending a Request packet
+   to the peer with a Type field indicating the type of request.  The
+   Peer responds with a corresponding Reply packet, and the
+   Authenticator and Peer exchange additional corresponding Request and
+   Reply packets until the Authenticator deems that the authentication
+   exchange is successful and complete, whereafter the Authenticator
+   sends a Success packet.  However, if at any time the Authenticator
+   deems the authentication exchange to be unsuccessful it sends a
+   Failure packet to indicate this.
+
+   When using this authentication method, the Type field in all Request
+   and Reply packets is set to 7 and the Type Data is as described in
+   Section 4 and the rest of this document.  The diagrams below
+   illustrate the EAP packet exchanges for this authentication method.
+
+   The following exchange occurs when a new session is negotiated
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 36]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   between the client and the server.  It will also occur when the
+   client requests re-use of the parameters of a previous session and
+   either the server does not support such re-use or no longer considers
+   the previous session to be valid:
+
+    Peer (client)                            Authenticator (server)
+
+    <------------  Request [ 7, { } ]  ----------------------------
+
+    ----  Reply [ 7, { U, I, sid, cn } ] ------------------------->
+
+    <------------  Request [ 7, { 00, N, g, s, B, L } ]  ----------
+
+    ----  Reply [ 7, { A, M1, o, cIV } ]  ------------------------>
+
+    <------------  Request [ 7, { M2, sIV, sid, ttl } ]  ----------
+
+    ----  Reply [ 7, { } ]  -------------------------------------->
+
+   The following exchange occurs when the client requests that the
+   parameters negotiated in a previous session be re-used in this
+   session, but with a newly derived shared context key, and the server
+   agrees:
+
+    Peer (client)                            Authenticator (server)
+
+    <-----------------------------  Request [ 7, { } ]  -----------
+
+    ---------  Reply [ 7, { U, I, sid, cn } ]  ------------------->
+
+    <-----------------------------  Request [ 7, { FF, sn } ]  ----
+
+    ---------  Reply [ 7, { } ]  --------------------------------->
+
+   If a security layer is negotiated then the payloads of all subsequent
+   lower layer packets sent over the link are protected using the
+   negotiated security services.
+
+9.4 Security Claims
+
+   As required by section 7.2 of [rfc2284bis], these are the security
+   claims made by this authentication method indicating the level of
+   security provided:
+
+   Intended Use: Wired networks, including PPP, PPPOE, and IEEE-802
+      wired media.  Use over the Internet or with wireless media only
+      when the recommended security layer has been negotiated.
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 37]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   Mechanism: Passphrase
+
+   Mutual authentication: Yes.  This mechanism requires mutual
+      authentication.
+
+   Integrity protection: Yes.  The calculations of evidence that the
+      shared context key is known - M1 sent by the client and M2 sent by
+      the server - include the  protocol elements received from the
+      other party, so any modification by a third party will be
+      detected.  SRP itself is resistent to known active and passive
+      attacks - see [SRP].
+
+   Replay protection: Yes.  Both the client and the server randomly
+      generate ephemeral private keys (a and b) that are used in the SRP
+      calculations, but are not publicly revealed.  New ephemeral
+      private keys are generated for each session making replay attacks
+      infeasible.
+
+   Confidentiality: No.
+
+   Key Derivation: No.
+
+   Dictionary attack protection: Yes. From [SRP]: "An attacker with
+      neither the user's password nor the host's password file cannot
+      mount a dictionary attack on the password".
+
+   Fast reconnect: Yes.  An optional, optimised alternate authentication
+      exchange is available where the parameters of a previously
+      negotiated session are re-used, but with a newly derived shared
+      context key - see Section 6.4.
+
+   Man-in-the-Middle resistance: Yes.  The calculations of evidence - M1
+      sent by the client and M2 sent by the server - include the
+      protocol elements received from the other party, so any
+      modification by a third party will be detected.  SRP itself is
+      resistent to known active attacks, including man-in-the-middle
+      attacks - see [SRP].
+
+   Acknowledged result indications: Yes.  When the client receives M2
+      from the server it knows that the server has verified that the
+      evidence (M1) it presented to prove its knowledge of the shared
+      context key is correct, so it knows that it is authenticated to
+      the server. When the server receives the empty response from the
+      client at the end of the authentication exchange, it knows that
+      the client has verified that the evidence (M2) it presented to
+      prove its knowledge of the shared context key is correct, so it
+      knows that it is authenticated to the client.  Similarly for
+      session re-use where the client receives the server nonce (sn)
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 38]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+      from the server, and the server receives the final empty response
+      from the client.
+
+   Key hierarchy: N/A
+
+   Key strength: The shared context key (K) negotiated between the
+      client and server has a length of s, where "s" is the output
+      length of the chosen underlying Message Digest Algorithm used in
+      the SRP calculations (see "mda" option in Section 4.3).  For
+      example, the recommended Message Digest Algorithm SHA-160 has an
+      output length of 160 bits, so in this case the length of K would
+      be 160 bits.  Keys for the confidentiality and integrity
+      protection services are derived from K - see Section 5.1.2 - and
+      have sizes appropriate for the algorithms being used.  Note that
+      all Message Digest Algorithms used with this mechanism MUST have
+      an output of at least 16 bytes (see "mda" option in Section 4.3),
+      which means that the shared context key will always have a length
+      of at least 128 bits.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 39]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+10. Security Considerations
+
+   This mechanism relies on the security of SRP, which bases its
+   security on the difficulty of solving the Diffie-Hellman problem in
+   the multiplicative field modulo a large safe prime.  See section 4
+   "Security Considerations" of [RFC-2945], section 4 "Security
+   analysis" of [SRP], and [SRP-6i].
+
+   This mechanism also relies on the security of the HMAC algorithm and
+   the underlying hash function when integrity protection is used.
+   Section 6 "Security" of [RFC-2104] discusses these security issues in
+   detail.  Weaknesses found in MD5 do not impact HMAC-MD5 [DOBBERTIN].
+
+   U, I, A and o, sent from the client to the server, and N, g, s, B and
+   L, sent from the server to the client, could be modified by an
+   attacker before reaching the other party.  For this reason, these
+   values are included in the respective calculations of evidence (M1
+   and M2) to prove that each party knows the shared context key K.
+   This allows each party to verify that these values were received
+   unmodified.
+
+   The use of integrity protection is RECOMMENDED to detect message
+   tampering and to avoid session hijacking after authentication has
+   taken place.
+
+   Replay attacks may be avoided through the use of sequence numbers,
+   because sequence numbers make each integrity protected message
+   exchanged during a session different, and each session uses a
+   different key.
+
+   Research [KRAWCZYK] shows that the order and way of combining message
+   encryption (Confidentiality Protection) and message authentication
+   (Integrity Protection) are important.  This mechanism follows the EtA
+   (encrypt-then-authenticate) method and is "generically secure".
+
+   This mechanism uses a Pseudo-Random Number Generator (PRNG) for
+   generating some of its parameters.  Section 5.1.1 describes a
+   securely seeded, cryptographically strong PRNG implementation for
+   this purpose.
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 40]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+11. Acknowledgements
+
+   The following people provided valuable feedback in the preparation of
+   this document:
+
+      Stephen Farrell <stephen.farrell@baltimore.ie>
+
+      Sam Hartman <hartmans@mit.edu>
+
+      Timothy Martin <tmartin@andrew.cmu.edu>
+
+      Alexey Melnikov <mel@messagingdirect.com>
+
+      Ken Murchison <ken@oceana.com>
+
+      Magnus Nystrom <magnus@rsasecurity.com>
+
+      David Taylor <DavidTaylor@forge.com.au>
+
+      Thomas Wu <tom@arcot.com>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 41]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Normative References
+
+   [RFC-2078]
+              Linn, J., "Generic Security Service Application Program
+              Interface, Version 2", RFC 2078, January 1997, <http://
+              www.ietf.org/rfc/rfc2078.txt>.
+
+   [RFC-2104]
+              Krawczyk, H., "HMAC: Keyed-Hashing for Message
+              Authentication", RFC 2104, February 1997, <http://
+              www.ietf.org/rfc/rfc2104.txt>.
+
+   [RFC-2119]
+              Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 0014, RFC 2119, March 1997,
+              <http://www.ietf.org/rfc/rfc2119.txt>.
+
+   [RFC-2222]
+              Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997, <http://www.ietf.org/rfc/
+              rfc2222.txt>.
+
+   [RFC-2284]
+              Blunk, L. and J. Vollbrecht, "PPP Extensible
+              Authentication Protocol (EAP)", RFC 2284, March 1998,
+              <http://www.ietf.org/rfc/rfc2284.txt>.
+
+   [rfc2284bis]
+              Blunk, L., Vollbrecht, J., Aboba, B., Carlson, J. and H.
+              Levkowetz, "Extensible Authentication Protocol (EAP), work
+              in progress", May 2003, <http://www.ietf.org/
+              internet-drafts/draft-ietf-eap-rfc2284bis-03.txt>.
+
+   [RFC-2945]
+              Wu, T., "The SRP Authentication and Key Exchange System",
+              RFC 2945, September 2000, <http://www.ietf.org/rfc/
+              rfc2945.txt>.
+
+   [RFC-3454]
+              Hoffman, P. and M. Blanchet, "Preparation of
+              Internationalized Strings ("stringprep")", RFC 3454,
+              December 2002, <http://www.ietf.org/rfc/rfc3454.txt>.
+
+   [SASL]     Myers, J., "Simple Authentication and Security Layer
+              (SASL)", April 2002, <http://www.ietf.org/internet-drafts/
+              draft-myers-saslrev-02.txt>.
+
+   [SASLprep]
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 42]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+              Zeilenga, K., "SASLprep: Stringprep profile for user names
+              and passwords, work in progress", May 2003, <http://
+              www.ietf.org/internet-drafts/
+              draft-ietf-sasl-saslprep-01.txt>.
+
+   [SRP]      Wu, T., "The Secure Remote Password Protocol, Proceedings
+              of the 1998 Internet Society Network and Distributed
+              System Security Symposium, San Diego, CA, Mar 1998, pp.
+              97-111", March 1998, <http://srp.stanford.edu/ndss.html>.
+
+   [SRP-6i]   Wu, T., "SRP-6: Improvements and Refinements to the Secure
+              Remote Password Protocol", October 2002, <http://
+              srp.stanford.edu/srp6.ps>.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 43]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Informative References
+
+   [AES]      National Institute of Standards and Technology, "Rijndael:
+              NIST's Selection for the AES", December 2000, <http://
+              csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf>.
+
+   [DOBBERTIN]
+              Dobbertin, H., "The Status of MD5 After a Recent Attack",
+              December 1996, <ftp://ftp.rsasecurity.com/pub/cryptobytes/
+              crypto2n2.pdf>.
+
+   [HAC]      Menezes, A., van Oorschot, P. and S. Vanstone, "Handbook
+              of Applied Cryptography", CRC Press, Inc., ISBN
+              0-8493-8523-7, 1997, <http://www.cacr.math.uwaterloo.ca/
+              hac/about/chap7.ps>.
+
+   [ISO-10646]
+              International Standards Organization, "International
+              Standard --Information technology-- Universal
+              Multiple-Octet Coded Character Set (UCS) -- Part 1
+              Architecture and Basic Multilingual Plane. UTF-8 is
+              described in Annex R, adopted but not yet published.
+              UTF-16 is described in Annex Q, adopted but not yet
+              published.", ISO/IEC 10646-1, 1993.
+
+   [KRAWCZYK]
+              Krawczyk, H., "The order of encryption and authentication
+              for protecting communications (Or: how secure is SSL?)",
+              June 2001, <http://eprint.iacr.org/2001/045/>.
+
+   [PKCS7]    RSA Data Security, Inc., "PKCS #7: Cryptographic Message
+              Syntax Standard", Version 1.5, November 1993, <ftp://
+              ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-7.asc>.
+
+   [RFC-1423]
+              Balenson, D., "Privacy Enhancement for Internet Electronic
+              Mail: Part III: Algorithms, Modes, and Identifiers", RFC
+              1423, February 1993, <http://www.ietf.org/rfc/
+              rfc1423.txt>.
+
+   [RFC-2279]
+              Yergeau, F., "UTF-8, a transformation format of Unicode
+              and ISO 10646", RFC 2279, January 1998, <http://
+              www.ietf.org/rfc/rfc2279.txt>.
+
+   [RFC-2440]
+              Callas, J., Donnerhacke, L., Finney, H. and R. Thayer,
+              "OpenPGP Message Format", RFC 2440, November 1998, <http:/
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 44]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+              /www.ietf.org/rfc/rfc2440.txt>.
+
+   [RFC-2554]
+              Myers, J., "SMTP Service Extension for Authentication",
+              RFC 2554, March 1999.
+
+   [RFC-2629]
+              Rose, M., "Writing I-Ds and RFCs using XML", RFC 2629,
+              June 1999, <http://www.ietf.org/rfc/rfc2629.txt>.
+
+   [RFC-2847]
+              Eisler, M., "LIPKEY - A Low Infrastructure Public Key
+              Mechanism Using SPKM", RFC 2847, June 2000, <http://
+              www.ietf.org/rfc/rfc2847.txt>.
+
+   [SCAN]     Hopwood, D., "Standard Cryptographic Algorithm Naming",
+              June 2000, <http://www.eskimo.com/~weidai/scan-mirror/>.
+
+   [SRP-6]    Wu, T., "SRP Protocol Design", October 2002, <http://
+              srp.stanford.edu/design.html>.
+
+   [SRPimpl]  Wu, T., "SRP: The Open Source Password Authentication
+              Standard", March 1998, <http://srp.stanford.edu/srp/>.
+
+   [UMAC]     Black, J., Halevi, S., Krawczyk, H., Krovetz, T. and P.
+              Rogaway, "UMAC: Fast and Secure Message Authentication,
+              Advances in Cryptology - CRYPTO '99. Lecture Notes in
+              Computer Science, vol. 1666, Springer-Verlag, 1999, pp.
+              216-233", October 2000, <http://www.cs.ucdavis.edu/
+              ~rogaway/umac/umac_proc.pdf>.
+
+   [UNICODE]  The Unicode Consortium, "The Unicode Standard, Version
+              3.2.0, is defined by The Unicode Standard, Version 3.0, as
+              amended by the Unicode Standard Annex #27: Unicode 3.1 and
+              by the Unicode Standard Annex #28: Unicode 3.2.", March
+              2002, <http://www.unicode.org/reports/tr28/tr28-3.html>.
+
+   [UNICODE-KC]
+              Durst, D., "Unicode Standard Annex #15: Unicode
+              Normalization Forms.", March 2001, <http://
+              www.unicode.org/unicode/reports/tr15>.
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 45]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Authors' Addresses
+
+   Keith Burdis
+   Rhodes University
+   Computer Science Department
+   Grahamstown  6139
+   ZA
+
+   EMail: keith@rucus.ru.ac.za
+
+
+   Raif S. Naffah
+   Forge Research Pty. Limited
+   Suite 116, Bay 9
+   Locomotive Workshop,
+   Australian Technology Park
+   Cornwallis Street
+   Eveleigh, NSW  1430
+   AU
+
+   EMail: raif@forge.com.au
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 46]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Appendix A. Modulus and Generator Values
+
+   Modulus N and generator g values for various modulus lengths are
+   given below.  In each case the modulus is a large safe prime and the
+   generator is a primitve root of GF(n) [RFC-2945].  These values are
+   taken from software developed by Tom Wu and Eugene Jhong for the
+   Stanford SRP distribution [SRPimpl].
+
+      [264 bits]
+        Modulus (base 16) =
+          115B8B692E0E045692CF280B436735C77A5A9E8A9E7ED56C965F87DB5B2A2
+          ECE3
+        Generator = 2
+
+      [384 bits]
+        Modulus (base 16) =
+          8025363296FB943FCE54BE717E0E2958A02A9672EF561953B2BAA3BAACC3E
+          D5754EB764C7AB7184578C57D5949CCB41B
+        Generator = 2
+
+      [512 bits]
+        Modulus (base 16) =
+          D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF75
+          6EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DB
+          DFCA43
+        Generator = 2
+
+      [640 bits]
+        Modulus (base 16) =
+          C94D67EB5B1A2346E8AB422FC6A0EDAEDA8C7F894C9EEEC42F9ED250FD7F0
+          046E5AF2CF73D6B2FA26BB08033DA4DE322E144E7A8E9B12A0E4637F6371F
+          34A2071C4B3836CBEEAB15034460FAA7ADF483
+        Generator = 2
+
+      [768 bits]
+        Modulus (base 16) =
+          B344C7C4F8C495031BB4E04FF8F84EE95008163940B9558276744D91F7CC9
+          F402653BE7147F00F576B93754BCDDF71B636F2099E6FFF90E79575F3D0DE
+          694AFF737D9BE9713CEF8D837ADA6380B1093E94B6A529A8C6C2BE33E0867
+          C60C3262B
+        Generator = 2
+
+      [1024 bits]
+        Modulus (base 16) =
+          EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256
+          576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D60
+          89DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F56
+          6660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC6
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 47]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+          1D2FC0EB06E3
+        Generator = 2
+
+      [1280 bits]
+        Modulus (base 16) =
+          D77946826E811914B39401D56A0A7843A8E7575D738C672A090AB1187D690
+          DC43872FC06A7B6A43F3B95BEAEC7DF04B9D242EBDC481111283216CE816E
+          004B786C5FCE856780D41837D95AD787A50BBE90BD3A9C98AC0F5FC0DE744
+          B1CDE1891690894BC1F65E00DE15B4B2AA6D87100C9ECC2527E45EB849DEB
+          14BB2049B163EA04187FD27C1BD9C7958CD40CE7067A9C024F9B7C5A0B4F5
+          003686161F0605B
+        Generator = 2
+
+      [1536 bits]
+        Modulus (base 16) =
+          9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19C
+          C4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A
+          22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D4754838
+          1DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2F
+          D53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87
+          F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A23
+          4DCF76E3FED135F9BB
+        Generator = 2
+
+      [2048 bits]
+        Modulus (base 16) =
+          AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56
+          050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA
+          04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A99
+          62F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D28
+          1E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5
+          B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3
+          786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D
+          0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372
+          FCD68EF20FA7111F9E4AFF73
+        Generator = 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 48]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Appendix B. Changes since the previous draft
+
+   Removed specific references to SASL in the main document, instead
+   isolating them to their own section.
+
+   Added sections describing how the mechanism can be used with the
+   GSS-API and EAP authentication frameworks.
+
+   Adopted SRP-6 exchange for the base protocol.
+
+   Mandated the use of SASLprep profile for text based information.
+
+   Added an optional, optimised alternate authentication exchange where
+   the parameters of a previously negotiated session are re-used, but
+   with a newly derived shared context key.
+
+   TODO: Regenerate SASL example.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 49]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+Intellectual Property Statement
+
+   The IETF takes no position regarding the validity or scope of any
+   intellectual property or other rights that might be claimed to
+   pertain to the implementation or use of the technology described in
+   this document or the extent to which any license under such rights
+   might or might not be available; neither does it represent that it
+   has made any effort to identify any such rights. Information on the
+   IETF's procedures with respect to rights in standards-track and
+   standards-related documentation can be found in BCP-11. Copies of
+   claims of rights made available for publication and any assurances of
+   licenses to be made available, or the result of an attempt made to
+   obtain a general license or permission for the use of such
+   proprietary rights by implementors or users of this specification can
+   be obtained from the IETF Secretariat.
+
+   The IETF invites any interested party to bring to its attention any
+   copyrights, patents or patent applications, or other proprietary
+   rights which may cover technology that may be required to practice
+   this standard. Please address the information to the IETF Executive
+   Director.
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works. However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assignees.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 50]
+\f
+Internet-Draft        SRP Authentication Mechanism              May 2003
+
+
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Burdis & Naffah        Expires November 28, 2003               [Page 51]
+\f
+
diff --git a/doc/draft-ietf-sasl-anon-xx.txt b/doc/draft-ietf-sasl-anon-xx.txt
new file mode 100644 (file)
index 0000000..bcff00a
--- /dev/null
@@ -0,0 +1,507 @@
+
+
+
+
+
+
+INTERNET-DRAFT                           Editor: Kurt D. Zeilenga
+Intended Category: Standards Track            OpenLDAP Foundation
+Expires in six months                                30 June 2003
+Obsoletes: RFC 2245
+
+
+                       The Anonymous SASL Mechanism
+                      <draft-ietf-sasl-anon-02.txt>
+
+
+Status of Memo
+
+  This document is an Internet-Draft and is in full conformance with all
+  provisions of Section 10 of RFC2026.
+
+  This document is intended to be, after appropriate review and
+  revision, submitted to the RFC Editor as a Standards Track document.
+  Distribution of this memo is unlimited.  Technical discussion of this
+  document will take place on the IETF SASL mailing list
+  <ietf-sasl@imc.org>.  Please send editorial comments directly to the
+  document editor <Kurt@OpenLDAP.org>.
+
+  Internet-Drafts are working documents of the Internet Engineering Task
+  Force (IETF), its areas, and its working groups.  Note that other
+  groups may also distribute working documents as Internet-Drafts.
+  Internet-Drafts are draft documents valid for a maximum of six months
+  and may be updated, replaced, or obsoleted by other documents at any
+  time.  It is inappropriate to use Internet-Drafts as reference
+  material or to cite them other than as ``work in progress.''
+
+  The list of current Internet-Drafts can be accessed at
+  <http://www.ietf.org/ietf/1id-abstracts.txt>. The list of
+  Internet-Draft Shadow Directories can be accessed at
+  <http://www.ietf.org/shadow.html>.
+
+  Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+  Please see the Full Copyright section near the end of this document
+  for more information.
+
+
+Abstract
+
+  It is common practice on the Internet to permit anonymous access to
+  various services.  Traditionally, this has been done with a plain text
+  password mechanism using "anonymous" as the user name and optional
+  trace information, such as an email address, as the password.  As
+  plain text login commands are not permitted in new IETF protocols, a
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 1]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  new way to provide anonymous login is needed within the context of the
+  Simple Authentication and Security Layer (SASL) framework.
+
+
+Conventions
+
+  The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+  "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+  document are to be interpreted as described in [Keywords].
+
+
+1. Anonymous SASL mechanism
+
+  This document defines an anonymous mechanism for the Simple
+  Authentication and Security Layer ([SASL]) framework.  The name
+  associated with this mechanism is "ANONYMOUS".
+
+  This document replaces RFC 2245.  Changes since RFC 2245 are detailed
+  in Appendix A.
+
+  The mechanism consists of a single message from the client to the
+  server.  The client sends optional trace information in the form of a
+  string of [UTF-8] encoded [Unicode] characters prepared in accordance
+  with [StringPrep] and the "trace" stringprep profile defined in
+  Section 2 of this document.  The trace information, which has no
+  semantical value, should take one of three forms: an Internet email
+  address, an opaque string which does not contain the '@' (U+0040)
+  character and can be interpreted by the system administrator of the
+  client's domain, or nothing.  For privacy reasons, an Internet email
+  address or other information identifying the user should only be used
+  with permission from the user.
+
+  A server which permits anonymous access will announce support for the
+  ANONYMOUS mechanism, and allow anyone to log in using that mechanism,
+  usually with restricted access.
+
+  This mechanism does not provide a security layer.
+
+  A formal grammar for the client message using Augmented BNF [ABNF] is
+  provide below as a tool for understanding this technical
+  specification.
+
+      message     = [ email / token ]
+                       ;; MUST be prepared in accordance with Section 2
+
+      UTF1        = %x00-3F / %x41-7F ;; less '@' (U+0040)
+      UTF2        = %xC2-DF UTF0
+      UTF3        = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 2]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+                    %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
+      UTF4        = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
+                    %xF4 %x80-8F 2(UTF0)
+      UTF0        = %x80-BF
+
+      TCHAR       = UTF1 / UTF2 / UTF3 / UTF4
+                    ;; any UTF-8 encoded Unicode character
+                    ;; except '@' (U+0040)
+
+      email       = addr-spec
+                    ;; as defined in [IMAIL], except with no free
+                    ;; insertion of linear-white-space, and the
+                    ;; local-part MUST either be entirely enclosed in
+                    ;; quotes or entirely unquoted
+
+      token       = 1*255TCHAR
+
+  Note to implementors:
+      The <token> production is restricted to 255 UTF-8 encoded Unicode
+      characters.   As the encoding of a characters uses a sequence of 1
+      to 4 octets, a token may be long as 1020 octets.
+
+
+2. The "trace" profile of "Stringprep"
+
+  This section defines the "trace" profile of [StringPrep].  This
+  profile is designed for use with the SASL ANONYMOUS Mechanism.
+  Specifically, the client MUST prepare the <message> production in
+  accordance with this profile.
+
+  The character repertoire of this profile is Unicode 3.2 [Unicode].
+
+  No mapping is required by this profile.
+
+  No Unicode normalization is required by this profile.
+
+  The list of unassigned code points for this profile is that provided
+  in appendix A of [RFC 3454].  Unassigned code points are not
+  prohibited.
+
+  Characters from the following tables of [StringPrep] are prohibited:
+      - C.2.1 (ASCII control characters)
+      - C.2.2 (Non-ASCII control characters)
+      - C.3 (Private use characters)
+      - C.4 (Non-character code points)
+      - C.5 (Surrogate codes)
+      - C.6 (Inappropriate for plain text)
+      - C.8 (Change display properties are deprecated)
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 3]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+      - C.9 (Tagging characters)
+
+  No additional characters are prohibited.
+
+  This profile requires bidirectional character checking per Section 6
+  of [StringPrep].
+
+
+3. Example
+
+  Here is a sample ANONYMOUS login between an IMAP client and server.
+  In this example, "C:" and "S:" indicate lines sent by the client and
+  server respectively.  If such lines are wrapped without a new "C:" or
+  "S:" label, then the wrapping is for editorial clarity and is not part
+  of the command.
+
+  Note that this example uses the IMAP profile [IMAP4] of SASL.  The
+  base64 encoding of challenges and responses, as well as the "+ "
+  preceding the responses are part of the IMAP4 profile, not part of
+  SASL itself.  Newer profiles of SASL will include the client message
+  with the AUTHENTICATE command itself so the extra round trip below
+  (the server response with an empty "+ ") can be eliminated.
+
+  In this example, the user's opaque identification token is "sirhc".
+
+      S: * OK IMAP4 server ready
+      C: A001 CAPABILITY
+      S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=DIGEST-MD5 AUTH=ANONYMOUS
+      S: A001 OK done
+      C: A002 AUTHENTICATE ANONYMOUS
+      S: +
+      C: c2lyaGM=
+      S: A003 OK Welcome, trace information has been logged.
+
+
+4. Security Considerations
+
+  The ANONYMOUS mechanism grants access to information by anyone.  For
+  this reason it should be disabled by default so the administrator can
+  make an explicit decision to enable it.
+
+  If the anonymous user has any write privileges, a denial of service
+  attack is possible by filling up all available space.  This can be
+  prevented by disabling all write access by anonymous users.
+
+  If anonymous users have read and write access to the same area, the
+  server can be used as a communication mechanism to anonymously
+  exchange information.  Servers which accept anonymous submissions
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 4]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  should implement the common "drop box" model which forbids anonymous
+  read access to the area where anonymous submissions are accepted.
+
+  If the anonymous user can run many expensive operations (e.g., an IMAP
+  SEARCH BODY command), this could enable a denial of service attack.
+  Servers are encouraged to reduce the priority of anonymous users or
+  limit their resource usage.
+
+  While servers may impose a limit on the number of anonymous users, it
+  is noted that such limits enable denial of service attacks and should
+  be used with caution.
+
+  The trace information is not authenticated so it can be falsified.
+  This can be used as an attempt to get someone else in trouble for
+  access to questionable information.  Administrators trying to trace
+  abuse need to realize this information may be falsified.
+
+  A client which uses the user's correct email address as trace
+  information without explicit permission may violate that user's
+  privacy.  Information about who accesses an anonymous archive on a
+  sensitive subject (e.g., sexual abuse) has strong privacy needs.
+  Clients should not send the email address without explicit permission
+  of the user and should offer the option of supplying no trace token --
+  thus only exposing the source IP address and time.  Anonymous proxy
+  servers could enhance this privacy, but would have to consider the
+  resulting potential denial of service attacks.
+
+  Anonymous connections are susceptible to man in the middle attacks
+  which view or alter the data transferred.  Clients and servers are
+  encouraged to support external integrity and encryption mechanisms.
+
+  Protocols which fail to require an explicit anonymous login are more
+  susceptible to break-ins given certain common implementation
+  techniques.  Specifically, Unix servers which offer user login may
+  initially start up as root and switch to the appropriate user id after
+  an explicit login command.  Normally such servers refuse all data
+  access commands prior to explicit login and may enter a restricted
+  security environment (e.g., the Unix chroot(2) function) for anonymous
+  users.  If anonymous access is not explicitly requested, the entire
+  data access machinery is exposed to external security attacks without
+  the chance for explicit protective measures.  Protocols which offer
+  restricted data access should not allow anonymous data access without
+  an explicit login step.
+
+  General [SASL] security considerations apply to this mechanism.
+
+  [StringPrep] security considerations as well as [Unicode] security
+  considerations discussed in [StringPrep] apply to this mechanism.
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 5]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  [UTF-8] security considerations also apply.
+
+
+5. IANA Considerations
+
+  It is requested that the SASL Mechanism registry [IANA-SASL] entry for
+  the ANONYMOUS mechanism be updated to reflect that this document now
+  provides its technical specification.
+
+      To: iana@iana.org
+      Subject: Updated Registration of SASL mechanism ANONYMOUS
+
+      SASL mechanism name: ANONYMOUS
+      Security considerations: See RFC XXXX.
+      Published specification (optional, recommended): RFC XXXX
+      Person & email address to contact for further information:
+           Kurt Zeilenga <kurt@openldap.org>
+           Chris Neuman <chris.newman@innosoft.com>
+      Intended usage: COMMON
+      Author/Change controller: IESG <iesg@ietf.org>
+      Note: Updates existing entry for ANONYMOUS
+
+
+  It is requested that the [Stringprep] profile "trace", first defined
+  in this RFC, be registered:
+
+      To: iana@iana.org
+      Subject: Initial Registration of Stringprep "trace" profile
+
+      Stringprep profile: trace
+      Published specification: RFC XXXX
+      Person & email address to contact for further information:
+          Kurt Zeilenga <kurt@openldap.org>
+
+
+6. Acknowledgment
+
+  This document is a revision of RFC 2245 by Chris Newman.  Portions of
+  the grammar defined in Section 1 were borrowed from [UTF-8] by
+  Francois Yergeau.
+
+  This document is a product of the IETF SASL WG.
+
+
+7. Normative References
+
+  [ABNF]        Crocker, D. and P. Overell, "Augmented BNF for Syntax
+                Specifications: ABNF", RFC 2234, November 1997.
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 6]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  [IMAIL]       Crocker, D., "Standard for the Format of Arpa Internet
+                Text Messages", STD 11, RFC 822, August 1982.
+
+  [Keywords]    Bradner, S., "Key words for use in RFCs to Indicate
+                Requirement Levels", BCP 14, RFC 2119, March 1997
+
+  [SASL]        Myers, J., "Simple Authentication and Security Layer
+                (SASL)", draft-myers-saslrev-xx.txt, a work in progress.
+
+  [StringPrep]  Hoffman P. and M. Blanchet, "Preparation of
+                Internationalized Strings ('stringprep')", RFC 3454,
+                December 2002.
+
+  [Unicode]     The Unicode Consortium, "The Unicode Standard, Version
+                3.2.0" is defined by "The Unicode Standard, Version 3.0"
+                (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5),
+                as amended by the "Unicode Standard Annex #27: Unicode
+                3.1" (http://www.unicode.org/reports/tr27/) and by the
+                "Unicode Standard Annex #28: Unicode 3.2"
+                (http://www.unicode.org/reports/tr28/).
+
+                [UTF-8]       Yergeau, F., "UTF-8, a transformation
+                format of ISO 10646", draft-yergeau-rfc2279bis, a work
+                in progress.
+
+
+8. Informative References
+
+  [IMAP4]       Crispin, M., "Internet Message Access Protocol - Version
+                4rev1", RFC 2060, December 1996.
+
+  [IANA-SASL]   IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL)
+                MECHANISMS", http://www.iana.org/assignments/sasl-
+                mechanisms.
+
+
+9. Editor's Address
+
+  Kurt Zeilenga
+  OpenLDAP Foundation
+
+  Email: kurt@OpenLDAP.org
+
+
+Appendix A.  Changes since RFC 2245
+
+  This appendix is non-normative.
+
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 7]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  RFC 2245 allows the client to send optional trace information in the
+  form of a human readable string.  RFC 2245 restricted this string to
+  US-ASCII.  As the Internet is international, this document uses a
+  string restricted to UTF-8 encoded Unicode characters.  A "stringprep"
+  profile is defined to precisely define which Unicode characters are
+  allowed in this string.  While the string remains restricted to 255
+  characters, the encoded length of each character may now range from 1
+  to 4 octets.
+
+  Additionally, a number of editorial changes were made.
+
+
+
+Intellectual Property Rights
+
+  The IETF takes no position regarding the validity or scope of any
+  intellectual property or other rights that might be claimed to pertain
+  to the implementation or use of the technology described in this
+  document or the extent to which any license under such rights might or
+  might not be available; neither does it represent that it has made any
+  effort to identify any such rights.  Information on the IETF's
+  procedures with respect to rights in standards-track and
+  standards-related documentation can be found in BCP-11.  Copies of
+  claims of rights made available for publication and any assurances of
+  licenses to be made available, or the result of an attempt made to
+  obtain a general license or permission for the use of such proprietary
+  rights by implementors or users of this specification can be obtained
+  from the IETF Secretariat.
+
+  The IETF invites any interested party to bring to its attention any
+  copyrights, patents or patent applications, or other proprietary
+  rights which may cover technology that may be required to practice
+  this standard.  Please address the information to the IETF Executive
+  Director.
+
+
+
+Full Copyright
+
+  Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implmentation may be prepared, copied, published and
+  distributed, in whole or in part, without restriction of any kind,
+  provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 8]
+\f
+INTERNET-DRAFT         draft-ietf-sasl-anon-02.txt          30 June 2003
+
+
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the  purpose of
+  developing Internet standards in which case the procedures for
+  copyrights defined in the Internet Standards process must be followed,
+  or as required to translate it into languages other than English.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zeilenga                Anonymous SASL Mechanism                [Page 9]
+\f
diff --git a/doc/draft-ietf-sasl-crammd5-xx.txt b/doc/draft-ietf-sasl-crammd5-xx.txt
new file mode 100644 (file)
index 0000000..85bda72
--- /dev/null
@@ -0,0 +1,434 @@
+
+
+Network Working Group                               L. Nerenberg, Editor
+Internet Draft: The CRAM-MD5 SASL Mechanism              Orthanc Systems
+Document: draft-ietf-sasl-crammd5-01.txt                   November 2003
+
+
+
+                      The CRAM-MD5 SASL Mechanism
+
+
+Status of this Memo
+
+     This document is an Internet Draft and is in full conformance with
+     all provisions of Section 10 of RFC 2026.
+
+     Internet Drafts are working documents of the Internet Engineering
+     Task Force (IETF), its areas, and its working groups.  Note that
+     other groups may also distribute working documents as Internet
+     Drafts.
+
+     Internet Drafts are draft documents valid for a maximum of six
+     months and may be updated, replaced, or obsoleted by other docu-
+     ments at any time.  It is inappropriate to use Internet Drafts as
+     reference material or to cite them other than as "work in
+     progress."
+
+     The list of current Internet Drafts can be accessed at
+     http://www.ietf.org/ietf/1id-abstracts.txt The list of Internet
+     Draft Shadow Directories can be accessed at
+     http://www.ietf.org/shadow.html.
+
+     Copyright 2003, The Internet Society.  All Rights Reserved.
+
+     Please see the Copyright section near the end of this document for
+     more information.
+
+Abstract
+
+     This document defines a simple challenge-response authentication
+     mechanism, using a keyed-hash digest, for use with the Simple
+     Authentication and Security Layer (SASL).
+
+1.  Conventions Used in this Document
+
+     The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+     in this document are to be interpreted as defined in [KEYWORD].
+
+
+2.  CRAM-MD5 Authentication Mechanism
+
+     This document defines a simple challenge-response [SASL] authenti-
+     cation mechanism, using a [KEYED-MD5] digest, for use with [SASL].
+     The mechanism name associated with CRAM-MD5 is 'CRAM-MD5'.
+
+     This mechanism does not provide a security layer.
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 1]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+     The data encoded in the challenge contains a presumptively arbi-
+     trary string of random digits, a time-stamp, and the fully-quali-
+     fied primary host name of the server.
+
+     The client makes note of the data and then responds with a string
+     consisting of the user name, a space, and a "digest."  The latter
+     is computed by applying the keyed MD5 algorithm from [KEYED-MD5]
+     where the key is a shared secret and the digested text is the chal-
+     lenge (including angle-brackets). The client MUST NOT interpret or
+     attempt to validate the contents of the challenge in any way.
+
+     This shared secret is a string known only to the client and server.
+     The "digest" parameter itself is a 16-octet value which is sent in
+     hexadecimal format, using lower-case US-ASCII characters.
+
+     When the server receives this client response, it verifies the
+     digest provided.  Since the user name may contain the space charac-
+     ter, the server MUST scan the client response from right to left;
+     the first space character encountered separates the digest from the
+     user name.  If the digest is correct, the server should consider
+     the client authenticated and respond appropriately.
+
+     The client MUST prepare the user name and shared secret strings
+     using the [SASLPrep] profile of the [StringPrep] algorithm.  The
+     resulting values MUST be encoded as UTF-8 [UTF8].
+
+
+2.1.  Formal Syntax
+
+     The following syntax specification uses the augmented Backus-Naur
+     Form (ABNF) as specified in [ABNF], and incorporates by reference
+     the Core Rules defined in that document.
+
+     challenge  = "<" 1*DIGIT "." 1*DIGIT "@" hostname ">"
+
+     digest     = 32(DIGIT / %x61-66)
+                  ; A hexadecimal string using only lower-case
+                  ; letters
+
+     hostname   = 1*(ALPHA / DIGIT) *("." / "-" / ALPHA / DIGIT)
+
+     response   = user SP digest
+
+     user       = 1*OCTET
+
+
+2.2.  Examples
+
+     The examples in this section do NOT form part of the specification.
+     Where conflicts exist between the examples and the formal grammar
+     or specification text, the latter are authoritative.
+
+     These examples show the use of the CRAM-MD5 mechanism with the
+     IMAP4 AUTHENTICATE command [IMAP4].  The base64 encoding of the
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 2]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+     challenges and responses is part of the IMAP4 AUTHENTICATE command,
+     not part of the CRAM-MD5 specification itself.
+
+     S: * OK [CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED AUTH=CRAM-MD5]
+     C: A0001 AUTHENTICATE CRAM-MD5
+     S: + PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
+     C: dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
+     S: A0001 OK CRAM-MD5 authentication successful
+
+     In this example, the shared secret is the string
+
+          tanstaaftanstaaf
+
+     Hence, the Keyed MD5 digest is produced by calculating
+
+          MD5((tanstaaftanstaaf XOR opad),
+               MD5((tanstaaftanstaaf XOR ipad),
+               <1896.697170952@postoffice.example.net>))
+
+     where ipad and opad are as defined in [KEYED-MD5] and the string
+     shown in the challenge is the base64 encoding of
+     <1896.697170952@postoffice.reston.mci.net>. The shared secret is
+     null-padded to a length of 64 bytes. If the shared secret is longer
+     than 64 bytes, the MD5 digest of the shared secret is used as a 16
+     byte input to the keyed MD5 calculation.
+
+     This produces a digest value (in hexadecimal) of
+
+          b913a602c7eda7a495b4e6e7334d3890
+
+     The user name is then prepended to it, forming
+
+          tim b913a602c7eda7a495b4e6e7334d3890
+
+     Which is then base64 encoded to meet the requirements of the IMAP4
+     AUTHENTICATE command (or the similar POP3 AUTH command), yielding
+
+          dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
+
+
+
+3.  References
+
+3.1.  Normative References
+
+[ABNF]
+     Crocker, D., P. Overell, "Augmented BNF for Syntax Specifications:
+     ABNF", RFC2234, Internet Mail Consortium and Demon Internet Ltd.,
+     November 1997.
+
+[KEYED-MD5]
+     Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for Message
+     Authentication", RFC 2104, IBM and UCSD, February 1997.
+
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 3]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+[KEYWORD]
+     Bradner, S., "Key words for use in RFCs to Indicate Requirement
+     Levels", BCP 14, RFC2119, Harvard University, March 1997.
+
+[MD5]
+     Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321, MIT Labo-
+     ratory for Computer Science and RSA Data Security, Inc., April
+     1992.
+
+[SASL]
+     Myers, J., "Simple Authentication and Security Layer (SASL)," RFC
+     2222, Netscape Communications, October 1997.
+
+[SASLPrep]
+     Zeilenga, K., "SASL String Preparation Profiles", draft-ietf-sasl-
+     saslprep (work in progress)
+
+[StringPrep]
+     Hoffman, P., M. Blanchet, "Preparation of Internationalized Strings
+     (stringprep)", RFC 3454, IMC and Viagenie, December 2002.
+
+[UTF8]
+     Yergeau, F., "UTF-8, a transformation format of ISO 10646", RFC
+     2279, Alis Technologies, January 1998.
+
+3.2.  Informative References
+
+[IMAP4]
+     Crispin, M., "Internet Message Access Protocol - Version 4rev1,"
+     RFC 3501, University of Washington, March 2003.
+
+
+4.  Security Considerations
+
+     It is conjectured that use of the CRAM-MD5 authentication mechanism
+     provides replay protection for a session.
+
+     This mechanism does not obscure the user name in any way.  Accord-
+     ingly, a server that implements both a clear-text password command
+     and this authentication type should not allow both methods of
+     access for a given user name.
+
+     Keyed MD5 is chosen for this application because of the greater
+     security imparted to authentication of short messages. In addition,
+     the use of the techniques described in [KEYED-MD5] for pre-computa-
+     tion of intermediate results make it possible to avoid explicit
+     clear-text storage of the shared secret on the server system by
+     instead storing the intermediate results which are known as "con-
+     texts."  While the saving, on the server, of the MD5 "context" is
+     marginally better than saving the shared secrets in clear-text, it
+     is not sufficient to protect the secrets if the server itself is
+     compromised.  Consequently, servers that store the secrets or con-
+     texts must both be protected to a level appropriate to the poten-
+     tial information value in the data and services protected by this
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 4]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+     mechanism.  In other words, techniques like this one involve a
+     trade-off between vulnerability to network sniffing and I/O buffer
+     snooping and vulnerability of the server host's databases.  If one
+     believes that the host and its databases are subject to compromise,
+     and the network is not, this technique (and all others like it) is
+     unattractive.  It is perhaps even less attractive than clear-text
+     passwords, which are typically stored on hosts in one-way hash
+     form.  On the other hand, if the server databases are perceived as
+     reasonably secure, and one is concerned about client-side or net-
+     work interception of the passwords (secrets), then this (and simi-
+     lar) techniques are preferable to clear-text passwords by a wide
+     margin.
+
+     As the length of the shared secret increases, so does the diffi-
+     culty of deriving it.
+
+     While there are now suggestions in the literature that the use of
+     MD5 and keyed MD5 in authentication procedures probably has a lim-
+     ited effective lifetime, the technique is now widely deployed and
+     widely understood.  It is believed that this general understanding
+     may assist with the rapid replacement, by CRAM-MD5, of the current
+     uses of permanent clear-text passwords in many protocols.  This
+     document has been deliberately written to permit easy upgrading to
+     use SHA (or whatever alternatives emerge) when they are considered
+     to be widely available and adequately safe.
+
+     Even with the use of CRAM-MD5, users are still vulnerable to active
+     attacks.  An example of an increasingly common active attack is
+     'TCP Session Hijacking' as described in CERT Advisory CA-95:01.
+
+     CRAM-MD5 does not authenticate the server and does not include a
+     client-supplied nonce.  As a result, it is possible to construct a
+     server with a fixed challenge string that has pre-computed the
+     hashes for all possible passwords up to a certain length (or from a
+     dictionary).  Such a server could then immediately determine the
+     user's password if it is sufficiently short.
+
+
+5.  IANA Considerations
+
+     The SASL Mechanism Registry entry for CRAM-MD5 must be updated to
+     reference this specification.
+
+
+6.  Contributors
+
+     The CRAM-MD5 mechanism was originally specified in RFC 2095,
+     IMAP/POP AUTHorize Extension for Simple Challenge/Response.  The
+     authors of that document -- John C. Klensin, Paul Krumviede, and
+     Randy Catoe -- are to be credited with the design and specification
+     of CRAM-MD5. This memo serves only to re-state CRAM-MD5 within the
+     formal context of SASL, which specification it preceded by several
+     months.
+
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 5]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+7.  Intellectual Property
+
+     The IETF takes no position regarding the validity or scope of any
+     intellectual property or other rights that might be claimed to per-
+     tain to the implementation or use of the technology described in
+     this document or the extent to which any license under such rights
+     might or might not be available; neither does it represent that it
+     has made any effort to identify any such rights.  Information on
+     the IETF's procedures with respect to rights in standards-track and
+     standards-related documentation can be found in BCP-11.  Copies of
+     claims of rights made available for publication and any assurances
+     of licenses to be made available, or the result of an attempt made
+     to obtain a general license or permission for the use of such pro-
+     prietary rights by implementers or users of this specification can
+     be obtained from the IETF Secretariat.
+
+     The IETF invites any interested party to bring to its attention any
+     copyrights, patents or patent applications, or other proprietary
+     rights which may cover technology that may be required to practice
+     this standard.  Please address the information to the IETF Execu-
+     tive Director.
+
+
+8.  Editors' Address
+
+     Lyndon Nerenberg
+     Orthanc Systems
+     1606 - 10770 Winterburn Road
+     Edmonton, Alberta
+     Canada T5S 1T6
+     Email: lyndon+rfc-crammd5@orthanc.ca
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 6]
+\f
+Internet Draft           CRAM-MD5 SASL Mechanism           November 2003
+
+
+9.  Full Copyright Statement
+
+     Copyright 2003, The Internet Society. All Rights Reserved.
+
+     This document and translations of it may be copied and furnished to
+     others, and derivative works that comment on or otherwise explain
+     it or assist in its implementation may be prepared, copied, pub-
+     lished and distributed, in whole or in part, without restriction of
+     any kind, provided that the above copyright notice and this para-
+     graph are included on all such copies and derivative works.  How-
+     ever, this document itself may not be modified in any way, such as
+     by removing the copyright notice or references to the Internet
+     Society or other Internet organizations, except as needed for the
+     purpose of developing Internet standards in which case the proce-
+     dures for copyrights defined in the Internet Standards process must
+     be followed, or as required to translate it into languages other
+     than English.  The limited permissions granted above are perpetual
+     and will not be revoked by the Internet Society or its successors
+     or assigns.
+
+     This document and the information contained herein is provided on
+     an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGI-
+     NEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+     INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+     INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WAR-
+     RANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Nerenberg            draft-ietf-sasl-crammd5-01.txt             [Page 7]
+\f
+
diff --git a/doc/draft-ietf-sasl-gssapi-xx.txt b/doc/draft-ietf-sasl-gssapi-xx.txt
new file mode 100644 (file)
index 0000000..bc37a49
--- /dev/null
@@ -0,0 +1,841 @@
+
+
+SASL Working Group                                           A. Melnikov
+Internet-Draft                                                     Isode
+Expires: May 22, 2004                                  November 22, 2003
+
+
+                         SASL GSSAPI mechanisms
+                       draft-ietf-sasl-gssapi-00
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups.  Note that
+   other groups may also distribute working documents as Internet-
+   Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at http://
+   www.ietf.org/ietf/1id-abstracts.txt.
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   This Internet-Draft will expire on May 22, 2004.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+Abstract
+
+   The Simple Authentication and Security Layer [SASL] is a method for
+   adding authentication support to connection-based protocols.  This
+   document describes the method for using the Generic Security Service
+   Application Program Interface [GSSAPI] in the Simple Authentication
+   and Security Layer [SASL].
+
+   This document replaces section 7.2 of RFC 2222 [SASL], the definition
+   of the "GSSAPI" SASL mechanism.
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 1]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+Table of Contents
+
+   1.  Conventions Used in this Document  . . . . . . . . . . . . . .  3
+   2.  Introduction and Overview  . . . . . . . . . . . . . . . . . .  4
+   2.1 Example  . . . . . . . . . . . . . . . . . . . . . . . . . . .  4
+   3.  SPNEGO . . . . . . . . . . . . . . . . . . . . . . . . . . . .  5
+   4.  Specification common to all GSSAPI mechanisms  . . . . . . . .  6
+   4.1 Client side of authentication protocol exchange  . . . . . . .  6
+   4.2 Server side of authentication protocol exchange  . . . . . . .  7
+   4.3 Security layer . . . . . . . . . . . . . . . . . . . . . . . .  8
+   5.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . .  9
+   6.  Security Considerations  . . . . . . . . . . . . . . . . . . . 11
+   7.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 12
+       Normative References . . . . . . . . . . . . . . . . . . . . . 13
+       Informative References . . . . . . . . . . . . . . . . . . . . 14
+       Author's Address . . . . . . . . . . . . . . . . . . . . . . . 14
+       Full Copyright Statement . . . . . . . . . . . . . . . . . . . 15
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 2]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+1. Conventions Used in this Document
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [KEYWORDS].
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 3]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+2. Introduction and Overview
+
+   Each and every GSSAPI mechanism used within SASL is implicitly
+   registered by this specification.
+
+   For backwards compatibility with existing implementations of Kerberos
+   V5 and SPNEGO under SASL, the SASL mechanism name for the Kerberos V5
+   GSSAPI mechanism [KRB5GSS] is "GSSAPI" and the SASL mechanism for the
+   SPNEGO GSSAPI mechanism [SPNEGO] is "GSS-SPNEGO".  The SASL mechanism
+   name for any other GSSAPI mechanism is the concatenation of "GSS-"
+   and the Base32 [BASE-ENCODING] encoding of the first ten bytes of the
+   MD5 hash [MD5] of the ASN.1 DER encoding [ASN1] of the GSSAPI
+   mechanism's OID.  The Base32 rules on padding characters and
+   characters outside of the base32 alphabet are not relevant to this
+   use of Base32.
+
+   SASL mechanism names starting with "GSS-" are reserved for SASL
+   mechanisms which conform to this document.
+
+   The specification of all SASL mechanisms conforming to this document
+   is in the "Specification common to all GSSAPI mechanisms" section of
+   this document.
+
+   The IESG is considered to be the owner of all SASL mechanisms which
+   conform to this document.  This does NOT necessarily imply that the
+   IESG is considered to be the owner of the underlying GSSAPI
+   mechanism.
+
+2.1 Example
+
+   The OID for the SPKM-1 mechanism [SPKM1] is 1.3.6.1.5.5.1.  The ASN.1
+   DER encoding of this OID is 06 06 2b 06 01 05 05 01.  The MD5 hash of
+   the ASN.1 DER encoding is 57 ee 81 82 4e ac 4d b0 e6 50 9f 60 1f 46
+   8a 30.  The Base32 encoding of the first ten bytes of this is
+   "K7XIDASOVRG3BZSQ".  Thus the SASL mechanism name for the SPKM-1
+   GSSAPI mechanism is "GSS-K7XIDASOVRG3BZSQ".
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 4]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+3. SPNEGO
+
+   Use of the Simple and Protected GSS-API Negotiation Mechanism
+   [SPNEGO] underneath SASL introduces subtle interoperability problems
+   and security considerations.  To address these, this section places
+   additional requirements on implementations which support SPNEGO
+   underneath SASL.
+
+   A client which supports, for example, the Kerberos V5 GSSAPI
+   mechanism only underneath SPNEGO underneath the "GSS-SPNEGO" SASL
+   mechanism will not interoperate with a server which supports the
+   Kerberos V5 GSSAPI mechanism only underneath the "GSSAPI" SASL
+   mechanism.
+
+   Since SASL is capable of negotiating amongst GSSAPI mechanisms, the
+   only reason for a server or client to support the "GSS-SPNEGO"
+   mechanism is to allow a policy of only using mechanisms below a
+   certain strength if those mechanism's negotiation is protected.  In
+   such a case, a client or server would only want to negotiate those
+   weaker mechanisms through SPNEGO.  In any case, there is no down-
+   negotiation security consideration with using the strongest mechanism
+   and set of options the implementation supports, so for
+   interoperability that mechanism and set of options MUST be negotiable
+   without using the "GSS-SPNEGO" mechanism.
+
+   If a client's policy is to first prefer GSSAPI mechanism X, then non-
+   GSSAPI mechanism Y, then GSSAPI mechanism Z, and if a server supports
+   mechanisms Y and Z but not X, then if the client attempts to
+   negotiate mechanism X by using the "GSS-SPNEGO" SASL mechanism, it
+   may end up using mechanism Z when it should have used mechanism Y.
+   For this reason, implementations MUST exclude from SPNEGO those
+   GSSAPI mechanisms which are weaker than the strongest non-GSSAPI SASL
+   mechanism advertised by the server.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 5]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+4. Specification common to all GSSAPI mechanisms
+
+   Each SASL mechanism which uses a GSSAPI mechanism uses the following
+   specification.
+
+   The implementation MAY set any GSSAPI flags or arguments not
+   mentioned in this specification as is necessary for the
+   implementation to enforce its security policy.
+
+4.1 Client side of authentication protocol exchange
+
+   The client calls GSS_Init_sec_context, passing in
+   input_context_handle of 0 (initially), mech_type of the GSSAPI
+   mechanism for which this SASL mechanism is registered, chan_binding
+   of NULL, and targ_name equal to output_name from GSS_Import_Name
+   called with input_name_type of GSS_C_NT_HOSTBASED_SERVICE and
+   input_name_string of "service@hostname" where "service" is the
+   service name specified in the protocol's profile, and "hostname" is
+   the fully qualified host name of the server.  If the client will be
+   requesting a security layer, it MUST also supply to the
+   GSS_Init_sec_context a mutual_req_flag of TRUE, a sequence_req_flag
+   of TRUE, and an integ_req_flag of TRUE.  If the client will be
+   requesting a security layer providing confidentiality protection, it
+   MUST also supply to the GSS_Init_sec_context a conf_req_flag of TRUE.
+   The client then responds with the resulting output_token.  If
+   GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED, then the client
+   should expect the server to issue a token in a subsequent challenge.
+   The client must pass the token to another call to
+   GSS_Init_sec_context, repeating the actions in this paragraph.
+
+   When GSS_Init_sec_context returns GSS_S_COMPLETE, the client examines
+   the context to ensure that it provides a level of protection
+   permitted by the client's security policy.  If the context is
+   acceptable, the client takes the following actions: If the last call
+   to GSS_Init_sec_context returned an output_token, then the client
+   responds with the output_token, otherwise the client responds with no
+   data.  The client should then expect the server to issue a token in a
+   subsequent challenge.  The client passes this token to GSS_Unwrap and
+   interprets the first octet of resulting cleartext as a bit-mask
+   specifying the security layers supported by the server and the second
+   through fourth octets as the network byte order maximum size
+   output_message to send to the server (if the resulting cleartext is
+   not 4 octets long, the client fails the negotiation).  The client
+   then constructs data, with the first octet containing the bit-mask
+   specifying the selected security layer, the second through fourth
+   octets containing in network byte order the maximum size
+   output_message the client is able to receive, and the remaining
+   octets containing the authorization identity, encoded according to
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 6]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+   the application profile specification.  The authorization identity is
+   not NUL-terminated.  The client passes the data to GSS_Wrap with
+   conf_flag set to FALSE, and responds with the generated
+   output_message.  The client can then consider the server
+   authenticated.
+
+4.2 Server side of authentication protocol exchange
+
+   The server passes the initial client response to
+   GSS_Accept_sec_context as input_token, setting input_context_handle
+   to 0 (initially), mech_type of the GSSAPI mechanism for which this
+   SASL mechanism is registered, chan_binding of NULL, and
+   acceptor_cred_handle equal to output_cred_handle from
+   GSS_Acquire_cred called with desired_name equal to output_name from
+   GSS_Import_name with input_name_type of GSS_C_NT_HOSTBASED_SERVICE
+   and input_name_string of "service@hostname" where "service" is the
+   service name specified in the protocol's profile, and "hostname" is
+   the fully qualified host name of the server.  If
+   GSS_Accept_sec_context returns GSS_S_CONTINUE_NEEDED, the server
+   returns the generated output_token to the client in challenge and
+   passes the resulting response to another call to
+   GSS_Accept_sec_context, repeating the actions in this paragraph.
+
+   When GSS_Accept_sec_context returns GSS_S_COMPLETE, the server
+   examines the context to ensure that it provides a level of protection
+   permitted by the server's security policy.  If the context is
+   acceptable, the server takes the following actions: If the last call
+   to GSS_Accept_sec_context returned an output_token, the server
+   returns it to the client in a challenge and expects a reply from the
+   client with no data.  Whether or not an output_token was returned
+   (and after receipt of any response from the client to such an
+   output_token), the server then constructs 4 octets of data, with the
+   first octet containing a bit-mask specifying the security layers
+   supported by the server and the second through fourth octets
+   containing in network byte order the maximum size output_token the
+   server is able to receive.  The server must then pass the plaintext
+   to GSS_Wrap with conf_flag set to FALSE and issue the generated
+   output_message to the client in a challenge.  The server must then
+   pass the resulting response to GSS_Unwrap and interpret the first
+   octet of resulting cleartext as the bit-mask for the selected
+   security layer, the second through fourth octets as the network byte
+   order maximum size output_message to send to the client, and the
+   remaining octets as the authorization identity.  The server must
+   verify that the src_name is authorized to authenticate as the
+   authorization identity.  After these verifications, the
+   authentication process is complete.
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 7]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+4.3 Security layer
+
+   The security layers and their corresponding bit-masks are as follows:
+
+         1 No security layer
+         2 Integrity protection.
+           Sender calls GSS_Wrap with conf_flag set to FALSE
+         4 Confidentiality protection.
+           Sender calls GSS_Wrap with conf_flag set to TRUE
+
+   Other bit-masks may be defined in the future; bits which are not
+   understood must be negotiated off.
+
+   Note that SASL negotiates the maximum size of the output_message to
+   send.  Implementations can use the GSS_Wrap_size_limit call to
+   determine the corresponding maximum size input_message.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 8]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+5. IANA Considerations
+
+   The IANA is advised that SASL mechanism names starting with "GSS-"
+   are reserved for SASL mechanisms which conform to this document.  The
+   IANA is directed to place a statement to that effect in the sasl-
+   mechanisms registry.
+
+   Family of SASL mechanisms: YES
+
+   Prefix: GSS-
+
+   Security considerations: RFC [THIS-DOC]
+
+   Published Specification: RFC [THIS-DOC]
+
+   Person & email address to contact for further information: Alexey
+      Melnikov <Alexey.Melnikov@isode.com>
+
+   Intended usage: COMMON
+
+   Author/Change controller: iesg@ietf.org
+
+   The IANA is directed to modify the existing registration for "GSSAPI"
+   as follows.
+
+   Family of SASL mechanisms: NO
+
+   SASL mechanism name: GSSAPI
+
+   Security considerations: ?
+
+   Published Specification: RFC [THIS-DOC]
+
+   Person & email address to contact for further information: Alexey
+      Melnikov <Alexey.Melnikov@isode.com>
+
+   Intended usage: COMMON
+
+   Author/Change controller: iesg@ietf.org
+
+   Additional Information: This mechanism is for the Kerberos V5
+      mechanism of GSSAPI.  Other GSSAPI mechanisms use other SASL
+      mechanism names, as described in this mechanism's published
+      specification.
+
+   The IANA is directed to modify the existing registration for "GSS-
+   SPNEGO" as follows.
+
+
+
+
+Melnikov                  Expires May 22, 2004                  [Page 9]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+   Family of SASL mechanisms: NO
+
+   SASL mechanism name: GSS-SPNEGO
+
+   Security considerations: See the "SPNEGO" section of RFC [THIS-DOC].
+
+   Published Specification: RFC [THIS-DOC]
+
+   Person & email address to contact for further information: Alexey
+      Melnikov <Alexey.Melnikov@isode.com>
+
+   Intended usage: LIMITED USE
+
+   Author/Change controller: iesg@ietf.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 10]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+6. Security Considerations
+
+   Security issues are discussed throughout this memo.
+
+   When a server or client supports multiple authentication mechanisms,
+   each of which has a different security strength, it is possible for
+   an active attacker to cause a party to use the least secure mechanism
+   supported.  To protect against this sort of attack, a client or
+   server which supports mechanisms of different strengths should have a
+   configurable minimum strength that it will use.  It is not sufficient
+   for this minimum strength check to only be on the server, since an
+   active attacker can change which mechanisms the client sees as being
+   supported, causing the client to send authentication credentials for
+   its weakest supported mechanism.
+
+   The client's selection of a SASL mechanism is done in the clear and
+   may be modified by an active attacker.  It is important for any new
+   SASL mechanisms to be designed such that an active attacker cannot
+   obtain an authentication with weaker security properties by modifying
+   the SASL mechanism name and/or the challenges and responses.
+
+   [SPNEGO] has protection against many of these down-negotiation
+   attacks, SASL does not itself have such protection.  The section
+   titled "SPNEGO" mentions considerations of choosing negotiation
+   through SASL versus SPNEGO.
+
+   The integrity protection provided by the security layer is useless to
+   the client unless the client also requests mutual authentication.
+   Therefore, a client wishing to benefit from the integrity protection
+   of a security layer MUST pass to the GSS_Init_sec_context call a
+   mutual_req_flag of TRUE.
+
+   When constructing the input_name_string, the client should not
+   canonicalize the server's fully qualified domain name using an
+   insecure or untrusted directory service.
+
+   Additional security considerations are in the [SASL] and [GSSAPI]
+   specifications.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 11]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+7. Acknowledgements
+
+   This document is a revision of RFC 2222 written by John G.  Myers.
+   He also contributed significantly to this revision.
+
+   Thank you to Lawrence Greenfield for converting text of this draft to
+   XML format.
+
+   Contributions of many members of the SASL mailing list are gratefully
+   acknowledged.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 12]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+Normative References
+
+   [ASN1]           International Organization for Standardization,
+                    "Information Processing Systems - Open Systems
+                    Interconnection - Specification of Abstract Syntax
+                    Notation One (ASN.1)", ISO Standard 8824, December
+                    1990.
+
+   [BASE-ENCODING]  Josefsson, S., "The Base16, Base32, and Base64 Data
+                    Encodings", RFC 3548, July 2003.
+
+   [GSSAPI]         Linn, J., "Generic Security Service Application
+                    Program Interface Version 2, Update 1", RFC 2743,
+                    January 2000.
+
+   [KEYWORDS]       Bradner, S., "Key words for use in RFCs to Indicate
+                    Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [KRB5GSS]        Linn, J., "The Kerberos Version 5 GSS-API
+                    Mechanism", RFC 1964, June 1996.
+
+   [MD5]            Rivest, R., "The MD5 Message-Digest Algorithm", RFC
+                    1321, April 1992.
+
+   [SASL]           Myers, J., "Simple Authentication and Security Layer
+                    (SASL)", RFC 2222, October 1997.
+
+   [SASL(rev)]      Melnikov, A., "Simple Authentication and Security
+                    Layer (SASL)", draft-ietf-sasl-rfc2222bis (work in
+                    progress), October 2003.
+
+   [SPNEGO]         Baize, E. and D. Pinkas, "The Simple and Protected
+                    GSS-API Negotiation Mechanism", RFC 2478, December
+                    1998.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 13]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+Informative References
+
+   [SPKM1]  Adams, C., "The Simple Public-Key GSS-API Mechanism (SPKM)",
+            RFC 2025, October 1996.
+
+   [UTF8]   Yergeau, F., "UTF-8, a transformation format of ISO 10646",
+            RFC 2279, January 1998.
+
+
+Author's Address
+
+   Alexey Melnikov (Ed.)
+   Isode Limited
+   5 Castle Business Village
+   36 Station Road
+   Hampton, Middlesex  TW12 2BX
+   UK
+
+   EMail: Alexey.Melnikov@isode.com
+   URI:   http://www.melnikov.ca/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 14]
+\f
+Internet-Draft           SASL GSSAPI mechanisms            November 2003
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Melnikov                  Expires May 22, 2004                 [Page 15]
+\f
+
diff --git a/doc/draft-ietf-sasl-plain-xx.txt b/doc/draft-ietf-sasl-plain-xx.txt
new file mode 100644 (file)
index 0000000..fa1fbce
--- /dev/null
@@ -0,0 +1,507 @@
+
+
+
+
+
+
+INTERNET-DRAFT                           Editor: Kurt D. Zeilenga
+Intended Category: Standards Track            OpenLDAP Foundation
+Expires in six months                             27 October 2003
+Updates: RFC 2595
+
+
+                         The Plain SASL Mechanism
+                      <draft-ietf-sasl-plain-03.txt>
+
+
+Status of Memo
+
+  This document is an Internet-Draft and is in full conformance with all
+  provisions of Section 10 of RFC2026.
+
+  This document is intended to be, after appropriate review and
+  revision, submitted to the RFC Editor as a Standards Track document.
+  Distribution of this memo is unlimited.  Technical discussion of this
+  document will take place on the IETF SASL mailing list
+  <ietf-sasl@imc.org>.  Please send editorial comments directly to the
+  document editor <Kurt@OpenLDAP.org>.
+
+  Internet-Drafts are working documents of the Internet Engineering Task
+  Force (IETF), its areas, and its working groups.  Note that other
+  groups may also distribute working documents as Internet-Drafts.
+  Internet-Drafts are draft documents valid for a maximum of six months
+  and may be updated, replaced, or obsoleted by other documents at any
+  time.  It is inappropriate to use Internet-Drafts as reference
+  material or to cite them other than as ``work in progress.''
+
+  The list of current Internet-Drafts can be accessed at
+  <http://www.ietf.org/ietf/1id-abstracts.txt>. The list of
+  Internet-Draft Shadow Directories can be accessed at
+  <http://www.ietf.org/shadow.html>.
+
+  Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+  Please see the Full Copyright section near the end of this document
+  for more information.
+
+
+Abstract
+
+  This document defines a simple clear-text user/password Simple
+  Authentication and Security Layer (SASL) mechanism called the PLAIN
+  mechanism.  The PLAIN mechanism is intended to be used, in combination
+  with data confidentiality services provided by a lower layer, in
+  protocols which lack a simple password authentication command.
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 1]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+Conventions
+
+  The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+  "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+  document are to be interpreted as described in [Keywords].
+
+
+1. Background and Intended Usage
+
+  Clear-text passwords are simple, interoperate with almost all existing
+  operating system authentication databases, and are useful for a smooth
+  transition to a more secure password-based authentication mechanism.
+  The drawback is that they are unacceptable for use over an unencrypted
+  network connection.
+
+  This document defines the PLAIN Simple Authentication and Security
+  Layer ([SASL]) mechanism for use in protocols with no clear-text login
+  command (e.g., [ACAP] or [SMTP-AUTH]).
+
+  The name associated with this mechanism is "PLAIN".
+
+  The PLAIN SASL mechanism does not provide a security layer.  This
+  mechanism MUST NOT be used without adequate security protection as the
+  mechanism affords no integrity nor confidentiality protection itself.
+  The PLAIN SASL mechanism MUST NOT be advertised unless a strong
+  encryption layer, such as provided by Transport Layer Security
+  ([TLS]), is active or backwards compatibility dictates otherwise.
+
+  This document updates RFC 2595, replacing Section 6.  Changes since
+  RFC 2595 are detailed in Appendix A.
+
+
+2. PLAIN SASL mechanism
+
+  The mechanism consists of a single message from the client to the
+  server.  The client sends the authorization identity (identity to
+  login as), followed by a NUL (U+0000) character, followed by the
+  authentication identity (identity whose password will be used),
+  followed by a NUL (U+0000) character, followed by the clear-text
+  password.   The client leaves the authorization identity empty if it
+  wishes the server to derive the authorization identity from the
+  authentication identity.
+
+  The formal grammar for the client message using Augmented BNF [ABNF]
+  follows.
+
+      message   = [authzid] NUL authcid NUL passwd
+      authcid   = 1*SAFE ; MUST accept up to 255 octets
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 2]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+      authzid   = 1*SAFE ; MUST accept up to 255 octets
+      passwd    = 1*SAFE ; MUST accept up to 255 octets
+      NUL       = %x00
+
+      SAFE      = UTF1 / UTF2 / UTF3 / UTF4
+                  ;; any UTF-8 encoded Unicode character except NUL
+
+      UTF1      = %x01-7F ;; except NULL
+      UTF2      = %xC2-DF UTF0
+      UTF3      = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
+                  %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
+      UTF4      = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
+                  %xF4 %x80-8F 2(UTF0)
+      UTF0      = %x80-BF
+
+  The authorization identity (authzid), authentication identity
+  (authcid) and password (passwd) SHALL be transferred as [UTF-8]
+  encoded strings of [Unicode] characters.  As NUL (U+0000) is used as a
+  deliminator, the NUL (U+0000) MUST NOT appear in authzid, authcid, or
+  passwd productions.
+
+  The form of the authzid production is specific to the
+  application-level protocol's SASL profile [SASL].  The authcid and
+  passwd productions are form-free.  Use of non-visible characters or
+  characters which a user may be unable to enter on some keyboards is
+  discouraged.
+
+  Servers MUST be capable of accepting authzid, authcid, and passwd
+  productions up to and including 255 octets.  It is noted that the
+  UTF-8 encoding of a Unicode character may be as long as 4 octets.
+
+  Upon receipt of the message, the server will verify the presented
+  authentication identity (authcid) and password (passwd) with the
+  system authentication database and verify the authentication
+  credentials permit the client to login as the (presented or derived)
+  authorization identity.  If both steps succeed, the user is
+  authenticated.
+
+  The presented authentication identity and password strings are not to
+  be compared directly with stored strings.  The server SHALL first
+  prepare authentication identity and password strings using the
+  [SASLPrep] profile of the [StringPrep] algorithm.  If preparation
+  fails or results in an empty string, verification SHALL fail.  If the
+  server stores only the hash of expected string, that string MUST be
+  prepared before generation of the hash.
+
+  When the no authorization identity is provided, the server SHALL
+  derive the authorization identity from the prepared representation of
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 3]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+  the provided authentication identity string.  This ensures that the
+  derivation of different representations of the authentication identity
+  produce the same authorization identity.
+
+  The verification function (using hashed password) can be written (in
+  pseudo-code):
+
+      boolean Verify(string authzid, string authcid, string passwd) {
+        string pAuthcid = SASLprep(authcid); # prepare authcid
+        string pPasswd = SASLprep(passwd);   # prepare passwd
+        if (pAuthcid == NULL || pPasswd == NULL) {
+          return false;     # preparation failed
+        }
+        if (pAuthcid == "" || pPasswd == "") {
+          return false;     # empty prepared string
+        }
+
+        storedHash = FetchPasswordHash(pAuthcid);
+        if (storedHash == NULL || storedHash == "") {
+          return false;     # error or unknown authcid
+        }
+
+        if (!Compare(storedHash, Hash(pPassword))) {
+          return false;     # incorrect password
+        }
+
+        if (authzid == NULL) {
+          authzid = DeriveAuthzid(pAuthcid);
+          if (authzid == NULL || authzid == "") {
+              return false; # could not derive authzid
+          }
+        }
+
+        if (!Authorize(pAuthcid, authzid)) {
+          return false;     # not authorized
+        }
+
+        return true;
+      }
+
+  Also note that the second parameter provided to the Authorize function
+  is not prepared by this code.  The application-level SASL profile
+  should be consulted to determine what, if any, preparation is
+  necessary.
+
+  The server MAY also use the credentials to initialize any new
+  authentication database, such as one suitable for [CRAM-MD5] or
+  [DIGEST-MD5].
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 4]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+4. Example
+
+  Here is an example of how this might be used to initialize a CRAM-MD5
+  authentication database using the Application Configuration Access
+  Protocol ([ACAP]).  "C:" and "S:" indicate lines sent by the client
+  and server respectively and <NUL> represents a single NUL (U+0000)
+  character.
+
+      S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
+      C: a001 AUTHENTICATE "CRAM-MD5"
+      S: + "<1896.697170952@postoffice.reston.mci.net>"
+      C: "tim b913a602c7eda7a495b4e6e7334d3890"
+      S: a001 NO (TRANSITION-NEEDED)
+         "Please change your password, or use TLS to login"
+      C: a002 STARTTLS
+      S: a002 OK "Begin TLS negotiation now"
+      <TLS negotiation, further commands are under TLS layer>
+      S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL")
+      C: a003 AUTHENTICATE "PLAIN" {21+}
+      C: <NUL>tim<NUL>tanstaaftanstaaf
+      S: a003 OK CRAM-MD5 password initialized
+
+
+
+5. Security Considerations
+
+  The PLAIN mechanism relies on the TLS encryption layer for security.
+  When used without TLS, it is vulnerable to a common network
+  eavesdropping attack.  Therefore PLAIN MUST NOT be advertised or used
+  unless a suitable TLS encryption layer is active or backwards
+  compatibility dictates otherwise.
+
+  When the PLAIN mechanism is used, the server gains the ability to
+  impersonate the user to all services with the same password regardless
+  of any encryption provided by TLS or other network privacy mechanisms.
+  While many other authentication mechanisms have similar weaknesses,
+  stronger SASL mechanisms address this issue.  Clients are encouraged
+  to have an operational mode where all mechanisms which are likely to
+  reveal the user's password to the server are disabled.
+
+  General SASL security considerations apply to this mechanism.
+  "stringprep" and Unicode [StringPrep] security considerations also
+  apply, as do [UTF-8] security considerations.
+
+
+6. IANA Considerations
+
+  It is requested that the SASL Mechanism registry [IANA-SASL] entry for
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 5]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+  the PLAIN mechanism be updated to reflect that this document now
+  provides its technical specification.
+
+      To: iana@iana.org
+      Subject: Updated Registration of SASL mechanism PLAIN
+
+      SASL mechanism name: PLAIN
+      Security considerations: See RFC XXXX.
+      Published specification (optional, recommended): RFC XXXX
+      Person & email address to contact for further information:
+          Kurt Zeilenga <kurt@openldap.org>
+           IETF SASL WG <ietf-sasl@imc.org>
+      Intended usage: COMMON
+      Author/Change controller: IESG <iesg@ietf.org>
+      Note: Updates existing entry for PLAIN
+
+
+7. Acknowledgment
+
+  This document is a revision of RFC 2595 by Chris Newman.  Portions of
+  the grammar defined in Section 2 were borrowed from [UTF-8] by
+  Francois Yergeau.
+
+  This document is a product of the IETF SASL WG.
+
+
+8. Normative References
+
+  [ABNF]        Crocker, D. and P. Overell, "Augmented BNF for Syntax
+                Specifications: ABNF", RFC 2234, November 1997.
+
+  [Keywords]    Bradner, S., "Key words for use in RFCs to Indicate
+                Requirement Levels", BCP 14, RFC 2119, March 1997
+
+  [SASL]        Melnikov, A. (Editor), "Simple Authentication and
+                Security Layer (SASL)",
+                draft-ietf-sasl-rfc2222bis-xx.txt, a work in progress.
+
+  [StringPrep]  Hoffman P. and M. Blanchet, "Preparation of
+                Internationalized Strings ('stringprep')",
+                draft-hoffman-rfc3454bis-xx.txt, a work in progress.
+
+  [Unicode]     The Unicode Consortium, "The Unicode Standard, Version
+                3.2.0" is defined by "The Unicode Standard, Version 3.0"
+                (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5),
+                as amended by the "Unicode Standard Annex #27: Unicode
+                3.1" (http://www.unicode.org/reports/tr27/) and by the
+                "Unicode Standard Annex #28: Unicode 3.2"
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 6]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+                (http://www.unicode.org/reports/tr28/).
+
+  [UTF-8]       Yergeau, F., "UTF-8, a transformation format of ISO
+                10646", draft-yergeau-rfc2279bis-xx.txt, a work in
+                progress.
+
+  [TLS]         Dierks, T. and, E. Rescorla, "The TLS Protocol Version
+                1.1", draft-ietf-tls-rfc2246-bis-xx.txt, a work in
+                progress.
+
+
+9. Informative References
+
+  [ACAP]        Newman, C. and J. Myers, "ACAP -- Application
+                Configuration Access Protocol", RFC 2244, November 1997.
+  [CRAM-MD5]    Nerenberg, L., "The CRAM-MD5 SASL Mechanism",
+                draft-ietf-sasl-crammd5-xx.txt, a work in progress.
+
+  [DIGEST-MD5]  Leach, P., C. Newman, and A. Melnikov, "Using Digest
+                Authentication as a SASL Mechanism",
+                draft-ietf-sasl-rfc2831bis-xx.txt, a work in progress.
+
+  [IANA-SASL]   IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL)
+                MECHANISMS", http://www.iana.org/assignments/sasl-
+                mechanisms.
+
+  [SMTP-AUTH]   Myers, J., "SMTP Service Extension for Authentication",
+                RFC 2554, March 1999.
+
+
+
+10. Editor's Address
+
+  Kurt Zeilenga
+  OpenLDAP Foundation
+
+  Email: kurt@OpenLDAP.org
+
+
+Appendix A.  Changes since RFC 2595
+
+  This appendix is non-normative.
+
+  This document replaces Section 6 of RFC 2595.
+
+  The specification details how the server is to compare client-provided
+  character strings with stored character strings.
+
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 7]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+  The ABNF grammar was updated.  In particular, the grammar now allows
+  LINE FEED (U+000A) and CARRIAGE RETURN (U+000D) characters in the
+  authzid, authcid, passwd productions.   However, whether these control
+  characters may be used depends on the string preparation rules
+  applicable to the production.   For passwd and authcid productions,
+  control characters are prohibited.  For authzid, one must consult the
+  application-level SASL profile.
+
+
+
+Intellectual Property Rights
+
+  The IETF takes no position regarding the validity or scope of any
+  intellectual property or other rights that might be claimed to pertain
+  to the implementation or use of the technology described in this
+  document or the extent to which any license under such rights might or
+  might not be available; neither does it represent that it has made any
+  effort to identify any such rights.  Information on the IETF's
+  procedures with respect to rights in standards-track and
+  standards-related documentation can be found in BCP-11.  Copies of
+  claims of rights made available for publication and any assurances of
+  licenses to be made available, or the result of an attempt made to
+  obtain a general license or permission for the use of such proprietary
+  rights by implementors or users of this specification can be obtained
+  from the IETF Secretariat.
+
+  The IETF invites any interested party to bring to its attention any
+  copyrights, patents or patent applications, or other proprietary
+  rights which may cover technology that may be required to practice
+  this standard.  Please address the information to the IETF Executive
+  Director.
+
+
+
+Full Copyright
+
+  Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implmentation may be prepared, copied, published and
+  distributed, in whole or in part, without restriction of any kind,
+  provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the  purpose of
+  developing Internet standards in which case the procedures for
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 8]
+\f
+INTERNET-DRAFT        draft-ietf-sasl-plain-03.txt       27 October 2003
+
+
+  copyrights defined in the Internet Standards process must be followed,
+  or as required to translate it into languages other than English.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zeilenga                  Plain SASL Mechanism                  [Page 9]
+\f
diff --git a/doc/draft-ietf-sasl-rfc2222bis-xx.txt b/doc/draft-ietf-sasl-rfc2222bis-xx.txt
new file mode 100644 (file)
index 0000000..ecadd4b
--- /dev/null
@@ -0,0 +1,1320 @@
+
+
+
+
+
+
+Network Working Group                                        A. Melnikov
+Internet Draft                                                    Editor
+Document: draft-ietf-sasl-rfc2222bis-03.txt                 October 2003
+                                                   Expires in six months
+
+
+            Simple Authentication and Security Layer (SASL)
+
+Status of this Memo
+
+   This document is an Internet Draft and is in full conformance with
+   all provisions of Section 10 of RFC 2026.
+
+   Internet Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its Areas, and its Working Groups.  Note that
+   other groups may also distribute working documents as Internet
+   Drafts. Internet Drafts are draft documents valid for a maximum of
+   six months.  Internet Drafts may be updated, replaced, or obsoleted
+   by other documents at any time.  It is not appropriate to use
+   Internet Drafts as reference material or to cite them other than as
+   ``work in progress''.
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+   A revised version of this draft document will be submitted to the RFC
+   editor as a Draft Standard for the Internet Community.  Discussion
+   and suggestions for improvement are requested.  Distribution of this
+   draft is unlimited.
+
+   When published as an RFC this document will obsolete RFC 2222.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A. Melnikov                                             FORMFEED[Page i]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+1.    Abstract
+
+   The Simple Authentication and Security Layer (SASL) provides a method
+   for adding authentication support with an optional security layer to
+   connection-based protocols.  It also describes a structure for
+   authentication mechanisms.  The result is an abstraction layer
+   between protocols and authentication mechanisms such that any SASL-
+   compatible authentication mechanism can be used with any SASL-
+   compatible protocol.
+
+   This document describes how a SASL authentication mechanism is
+   structured, describes how a protocol adds support for SASL, defines
+   the protocol for carrying a security layer over a connection, and
+   defines the EXTERNAL SASL authentication mechanism.
+
+2.    Organization of this document
+
+2.1.  How to read this document
+
+   This document is written to serve two different audiences, protocol
+   designers using this specification to support authentication in their
+   protocol, and implementors of clients or servers for those protocols
+   using this specification.
+
+   The sections "Overview", "Authentication Mechanisms", "Protocol
+   Profile Requirements", "Specific Issues", and "Security
+   Considerations" cover issues that protocol designers need to
+   understand and address in profiling this specification for use in a
+   specific protocol.
+
+   Implementors of a protocol using this specification need the
+   protocol-specific profiling information in addition to the
+   information in this document.
+
+2.2.  Conventions used in this document
+
+   In examples, "C:" and "S:" indicate lines sent by the client and
+   server respectively.
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [KEYWORDS].
+
+   Character names in this document use the notation for code points and
+   names from the Unicode Standard [Unicode].  For example, the letter
+   "a" may be represented as either <U+0061> or <LATIN SMALL LETTER A>.
+
+
+
+
+
+A. Melnikov                                             FORMFEED[Page 2]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+3.    Overview
+
+   The Simple Authentication and Security Layer (SASL) is a method for
+   adding authentication support to connection-based protocols.
+
+   The SASL specification has three layers, as indicated in the diagram
+   below.  At the top, a protocol definition using SASL specifies a
+   profile, including a command for identifying and authenticating a
+   user to a server and for optionally negotiating a security layer for
+   subsequent protocol interactions.  At the bottom, a SASL mechanism
+   definition specifies an authentication mechanism.  The SASL
+   framework, specified by this document, constrains the behavior of
+   protocol profiles and mechanisms, separating protocol from mechanism
+   and defining how they interact.
+
+                SMTP Protocol     LDAP Protocol          Etc
+                   Profile           Profile            . . .
+                          -----        |       -----//
+                                       |      //
+                                 SASL framework
+                                /       |      \
+                          /-----        |       -----\
+                   EXTERNAL         DIGEST-MD5           Etc
+                SASL mechanism    SASL mechanism        . . .
+
+   This separation between the definition of protocols and the
+   definition of authentication mechanisms is crucial.  It permits an
+   authentication mechanism to be defined once, making it usable by any
+   SASL protocol profile.  In many implementations, the same SASL
+   mechanism code is used for multiple protocols.
+
+4.    Authentication mechanisms
+
+   SASL mechanisms are named by strings, from 1 to 20 characters in
+   length, consisting of upper-case ASCII [ASCII] letters, digits,
+   hyphens, and/or underscores.  SASL mechanism names must be registered
+   with the Internet Assigned Numbers Authority (IANA). IETF standards
+   track documents may direct the IANA to reserve a portion of the SASL
+   mechanism namespace and may specify different registration criteria
+   for the reserved portion; the GSSAPI mechanism specification [SASL-
+   GSSAPI] does this. Procedures for registering new SASL mechanisms are
+   given in the section 8.
+
+   The "sasl-mech" rule below defines the syntax of a SASL mechanism
+   name.  This uses the Augmented Backus-Naur Form (ABNF) notation as
+   specified in [ABNF] and the ABNF core rules as specified in Appendix
+   A of the ABNF specification [ABNF].
+
+
+
+
+A. Melnikov                                             FORMFEED[Page 3]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   sasl-mech    = 1*20mech-char
+   mech-char    = %x41-5A / DIGIT / "-" / "_"
+                  ; mech names restricted to uppercase ASCII letters,
+                  ; digits, "-" and "_"
+
+
+4.1.  Authentication protocol exchange
+
+   A SASL mechanism is responsible for conducting an authentication
+   protocol exchange.  This consists of a series of server challenges
+   and client responses, the contents of which are specific to and
+   defined by the mechanism.  To the protocol, the challenges and
+   responses are opaque binary tokens of arbitrary length.  The
+   protocol's profile then specifies how these binary tokens are then
+   encoded for transfer over the connection.
+
+   After receiving an authentication command or any client response, a
+   server mechanism may issue a challenge, indicate failure, or indicate
+   completion.  The server mechanism may return additional data with a
+   completion indication.  The protocol's profile specifies how each of
+   these is then represented over the connection.
+
+   After receiving a challenge, a client mechanism may issue a response
+   or abort the exchange.  The protocol's profile specifies how each of
+   these is then represented over the connection.
+
+   During the authentication protocol exchange, the mechanism performs
+   authentication, transmits an authorization identity (frequently known
+   as a userid) from the client to server, and negotiates the use of a
+   mechanism-specific security layer.  If the use of a security layer is
+   agreed upon, then the mechanism must also define or negotiate the
+   maximum security layer buffer size that each side is able to receive.
+
+4.2.  Authorization identities and proxy authentication
+
+   An authorization identity is a string of zero or more ISO 10646
+   [ISO-10646] coded characters.  The NUL <U+0000> character is not
+   permitted in authorization identities. The meaning of an
+   authorization identity of the empty string (zero length) is defined
+   below in this section. The authorization identity is used by the
+   server as the primary identity for making access policy decisions.
+
+   The character encoding scheme used (see [CHARSET-POLICY] for IETF
+   policy regarding character sets in IETF protocols) for transmitting
+   an authorization identity over protocol is specified in each
+   authentication mechanism (with the authentication mechanism's data
+   being further restricted/encoded by the protocol profile).
+   Authentication mechanisms SHOULD encode these and other strings in
+
+
+
+A. Melnikov                                             FORMFEED[Page 4]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   UTF-8 [UTF-8]. While some legacy mechanisms are incapable of
+   transmitting an authorization identity other than the empty string,
+   newly defined mechanisms are expected to be capable of carrying the
+   entire Unicode repertoire (with the exception of the NUL character).
+   An authorization identity of the empty string and an absent
+   authorization identity MUST be treated as equivalent.  However,
+   mechanisms SHOULD NOT allow both. That is, a mechanism which provides
+   an optional field for an authorization identity, SHOULD NOT allow
+   that field, when present, to be empty.
+
+   The identity derived from the client's authentication credentials is
+   known as the "authentication identity".  With any mechanism,
+   transmitting an authorization identity of the empty string directs
+   the server to derive an authorization identity from the client's
+   authentication identity.
+
+   If the authorization identity transmitted during the authentication
+   protocol exchange is not the empty string, this is typically referred
+   to as "proxy authentication".  This feature permits agents such as
+   proxy servers to authenticate using their own credentials, yet
+   request the access privileges of the identity for which they are
+   proxying.
+
+   The server makes an implementation defined policy decision as to
+   whether the authentication identity is permitted to have the access
+   privileges of the authorization identity and whether the
+   authorization identity is permitted to receive service.  If it is
+   not, the server indicates failure of the authentication protocol
+   exchange.
+
+   As a client might not have the same information as the server,
+   clients SHOULD NOT derive authorization identities from
+   authentication identities. Instead, clients SHOULD provide no (or
+   empty) authorization identity when the user has not provided an
+   authorization identity.
+
+   The server MUST verify that a received authorization identity is in
+   the correct form. Profiles whose authorization identities are simple
+   user names (e.g. IMAP [RFC 3501]) SHOULD use "SASLPrep" profile
+   [SASLPrep] of the "stringprep" algorithm [StringPrep] to prepare
+   these names for matching. The profiles MAY use a stringprep profile
+   that is more strict than "SASLPrep". If the preparation of the
+   authorization identity fails or results in an empty string, the
+   server MUST fail the authentication exchange. The only exception to
+   this rule is when the received authorization identity is already the
+   empty string.
+
+
+
+
+
+A. Melnikov                                             FORMFEED[Page 5]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+4.3.  Security layers
+
+   If use of a security layer is negotiated by the authentication
+   protocol exchange, the security layer is applied to all subsequent
+   data sent over the connection (until another security layer or no
+   security layer is negotiated; see also section 6.3). The security
+   layer takes effect immediately following the last response of the
+   authentication exchange for data sent by the client and the
+   completion indication for data sent by the server.
+
+   Once the security layer is in effect, the protocol stream is
+   processed by the security layer into buffers of security encoded
+   data.  Each buffer of security encoded data is transferred over the
+   connection as a stream of octets prepended with a four octet field in
+   network byte order that represents the length of the following
+   buffer.  The length of the security encoded data buffer MUST be no
+   larger than the maximum size that was either defined in the mechanism
+   specification or negotiated by the other side during the
+   authentication protocol exchange.  Upon the receipt of a data buffer
+   which is larger than the defined/negotiated maximal buffer size, the
+   receiver SHOULD close the connection.  This might be a sign of an
+   attack or a buggy implementation.
+
+4.4.  Character string issues
+
+   Authentication mechanisms SHOULD encode character strings in UTF-8
+   [UTF-8] (see [CHARSET-POLICY] for IETF policy regarding character
+   sets in IETF protocols).  In order to avoid noninteroperability due
+   to differing normalizations, when a mechanism specifies that a string
+   authentication identity or password used as input to a cryptographic
+   function (or used for comparison) it SHOULD specify that the string
+   first be prepared using the "SASLPrep" profile [SASLPrep] of the
+   "stringprep" algorithm [StringPrep].  There are three entities that
+   has to deal with this issue: a client (upon getting user input or
+   retrieving a value from configuration), a server (upon receiving the
+   value from the client) and a utility that is able to store
+   passwords/hashes in a database that can be later used by the server.
+   The preparation must be done by the client and the utility and may be
+   done by the server. If preparation fails or results in an empty
+   string, the entity doing the preparation SHALL fail the
+   authentication exchange.
+
+
+5.    Protocol profile requirements
+
+   In order to use this specification, a protocol definition MUST supply
+   the following information:
+
+
+
+
+A. Melnikov                                             FORMFEED[Page 6]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   A service name, to be selected from the IANA registry of "service"
+   elements for the GSSAPI host-based service name form [GSSAPI]. This
+   service name is made available to the authentication mechanism.
+
+   The registry is available at the URL
+   <http://www.iana.org/assignments/gssapi-service-names>.
+
+   A definition of the command to initiate the authentication protocol
+   exchange.  This command must have as a parameter the name of the
+   mechanism being selected by the client.
+
+   The command SHOULD have an optional parameter giving an initial
+   response.  This optional parameter allows the client to avoid a round
+   trip when using a mechanism which is defined to have the client send
+   data first.  When this initial response is sent by the client and the
+   selected mechanism is defined to have the server start with an
+   initial challenge, the command fails.  See section 6.1 of this
+   document for further information.
+
+   A definition of the method by which the authentication protocol
+   exchange is carried out, including how the challenges and responses
+   are encoded, how the server indicates completion or failure of the
+   exchange, how the client aborts an exchange, and how the exchange
+   method interacts with any line length limits in the protocol.
+
+   The exchange method SHOULD allow the server to include an optional
+   data ("optional challenge") with a success notification.  This allows
+   the server to avoid a round trip when using a mechanism which is
+   defined to have the server send additional data along with the
+   indication of successful completion.  See section 6.2 of this
+   document for further information.
+
+   In addition, a protocol profile SHOULD specify a mechanism through
+   which a client may obtain the names of the SASL mechanisms available
+   to it.  This is typically done through the protocol's extensions or
+   capabilities mechanism.
+
+   Identification of the octet where any negotiated security layer
+   starts to take effect, in both directions.
+
+   Specify if the protocol supports "multiple authentications" (see
+   section 6.3).
+
+   If both TLS and SASL security layer are allowed to be negotiated by
+   the protocol, the protocol profile MUST define in which order they
+   are applied to a cleartext data sent over the connection.
+
+   A protocol profile MAY further refine the definition of an
+
+
+
+A. Melnikov                                             FORMFEED[Page 7]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   authorization identity by adding additional syntactic restrictions
+   and protocol-specific semantics. A protocol profile MUST specify the
+   form of the authorization identity (since it is protocol specific, as
+   opposed to the authentication identity, which is mechanism specific)
+   and how authorization identities are to be compared. Profiles whose
+   authorization identities are simple user names (e.g. IMAP [RFC 3501])
+   SHOULD use "SASLPrep" profile [SASLPrep] of the "stringprep"
+   algorithm [StringPrep] to prepare these names for matching. The
+   profiles MAY use a stringprep profile that is more strict than
+   SASLPrep.
+
+   A protocol profile SHOULD NOT attempt to amend the definition of
+   mechanisms or make mechanism-specific encodings.  This breaks the
+   separation between protocol and mechanism that is fundamental to the
+   design of SASL. Likewise, SASL mechanisms SHOULD be profile neutral.
+
+6.    Specific issues
+
+6.1.  Client sends data first
+
+   Some mechanisms specify that the first data sent in the
+   authentication protocol exchange is from the client to the server.
+
+   If a protocol's profile permits the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, this parameter SHOULD be used with such mechanisms.
+
+   If the initial client response parameter is not given, or if a
+   protocol's profile does not permit the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, then the server issues a challenge with no data.  The
+   client's response to this challenge is then used as the initial
+   client response.  (The server then proceeds to send the next
+   challenge, indicates completion, or indicates failure.)
+
+6.2.  Server returns success with additional data
+
+   Some mechanisms may specify that additional data be sent to the
+   client along with an indication of successful completion of the
+   exchange.  This data would, for example, authenticate the server to
+   the client.
+
+   If a protocol's profile does not permit this additional data to be
+   returned with a success indication, then the server issues the data
+   as a server challenge, without an indication of successful
+   completion.  The client then responds with no data.  After receiving
+   this empty response, the server then indicates successful completion
+   (with no additional data).
+
+
+
+A. Melnikov                                             FORMFEED[Page 8]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   Client implementors should be aware of an additional failure case
+   that might occur when the profile supports sending the additional
+   data with success. Imagine that an active attacker is trying to
+   impersonate the server and sends faked data, which should be used to
+   authenticate the server to the client, with success.  (A similar
+   situation can happen when either the server and/or the client has a
+   bug and they calculate different responses.) After checking the data,
+   the client will think that the authentication exchange has failed,
+   however the server will think that the authentication exchange has
+   completed successfully.  At this point the client can not abort the
+   authentication exchange, it SHOULD close the connection instead.
+   However, if the profile did not support sending of additional data
+   with success, the client could have aborted the exchange at the very
+   last step of the authentication exchange.
+
+6.3.  Multiple authentications
+
+   Unless otherwise stated by the protocol's profile, only one
+   successful SASL negotiation may occur in a protocol session.  In this
+   case, once an authentication protocol exchange has successfully
+   completed, further attempts to initiate an authentication protocol
+   exchange fail.
+
+   If a profile explicitly permits multiple successful SASL negotiations
+   to occur, then in no case may multiple security layers be
+   simultaneously in effect.  If a security layer is in effect and a
+   subsequent SASL negotiation selects a second security layer, then the
+   second security layer replaces the first. If a security layer is in
+   effect and a subsequent SASL negotiation selects no security layer,
+   the original security layer MUST be removed. The next paragraphs
+   explain why this is important.
+
+   Let's assume that the protected resources on a server are partitioned
+   into a set of protection spaces, each with its own authentication
+   mechanisms and/or authorization database. Let's use the term "realm"
+   to reference any such protected space. Conceptually, realm is a named
+   collection of user's accounts. For example, a proxy/frontend can use
+   different realms for different servers/backends it represents.
+
+   Now consider the following scenario. A client has already
+   authenticated and established a security layer with "Realm A" which
+   is managed by the server AA.  Now the same client authenticates to
+   "Realm B" (managed by the server BB) without negotiating a new
+   security layer, while the security layer negotiated with "Realm A"
+   remains in effect. The server BB is now able observe how known
+   cleartext is encrypted. This scenario enables the server BB to make
+   guesses about previously observed ciphertext between the client and
+   the server AA using the server's SASL engine as an oracle.  This
+
+
+
+A. Melnikov                                             FORMFEED[Page 9]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   scenario is illustrated below:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 10]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+              +---------+                   +---------+
+              |         |                   |         |
+              | Realm B |                   | Realm A |
+              |         |                   |         |
+              +---------+                   +---------+
+                  |  ^                           |
+                  |  :      +-----------+        |
+     Traffic from |  :      | Encryption|        | Traffic from A
+      B to client +-------->| end point |<-------+ to client
+                     :      | (SSL/SASL)|
+                     :      +-----------+
+                     :            |
+                     :            |
+                     :          +---+
+                     :          |   |
+                     :          |   |
+                     :          |   | Encryption tunnel, e.g. SASL or SSL,
+                     :          |   | between the server
+       (1) Recording +---------:|   | and a single client only.
+           encrypted            |   | Separate tunnels to different
+           traffic between      |   | clients.
+           Realm A and client   +---+
+                                  |
+                                  |
+                                  +-----------> Traffic to clients
+
+7.    The EXTERNAL mechanism
+
+   The mechanism name associated with external authentication is
+   "EXTERNAL".
+
+   The client sends an initial response with the UTF-8 encoding of the
+   authorization identity. The form of the authorization identity is
+   further restricted by the application-level protocol's SASL profile.
+
+   The server uses information, external to SASL, to determine whether
+   the client is authorized to authenticate as the authorization
+   identity.  If the client is so authorized, the server indicates
+   successful completion of the authentication exchange; otherwise the
+   server indicates failure.
+
+   The system providing this external information may be, for example,
+   IPSec or TLS. However, the client can make no assumptions as to what
+   information the server can use in determining client authorization.
+   E.g., just because TLS was established, doesn't mean that the server
+   will use the information provided by TLS.
+
+   If the client sends the empty string as the authorization identity
+
+
+
+A. Melnikov                                            FORMFEED[Page 11]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   (thus requesting that the authorization identity be derived from the
+   client's authentication credentials), the authorization identity is
+   to be derived from authentication credentials which exist in the
+   system that is providing the external authentication.
+
+7.1.  Formal syntax
+
+   The following syntax specification uses the augmented Backus-Naur
+   Form (BNF) notation as specified in [ABNF].  This uses the ABNF core
+   rules as specified in Appendix A of the ABNF specification [ABNF].
+   Non-terminals referenced but not defined below are as defined by
+   [UTF-8].
+
+   The "extern-init-resp" rule below defines the initial response sent
+   from client to server.
+
+   extern-init-resp  = *( UTF8-char-no-nul )
+
+   UTF8-char-no-nul  = UTF8-1-no-nul / UTF8-2 / UTF8-3 / UTF8-4
+
+   UTF8-1-no-nul     = %x01-7F
+
+
+7.2.  Example
+
+   The following is an example of an EXTERNAL authentication in the SMTP
+   protocol [SMTP].  In this example, the client is proxy
+   authenticating, sending the authorization id "fred".  The server has
+   determined the client's identity through IPsec and has a security
+   policy that permits that identity to proxy authenticate as any other
+   identity.
+
+   To the protocol profile, the four octet sequence "fred" is an opaque
+   binary data. The SASL protocol profile for SMTP [SMTP-AUTH] specifies
+   that server challenges and client responses are encoded in BASE64
+   [BASE64]; the BASE64 encoding of "fred" is "ZnJlZA==".
+
+      S: 220 smtp.example.com ESMTP server ready
+      C: EHLO jgm.example.com
+      S: 250-smtp.example.com
+      S: 250 AUTH DIGEST-MD5 EXTERNAL
+      C: AUTH EXTERNAL ZnJlZA==
+      S: 235 Authentication successful.
+
+8.    IANA Considerations
+
+
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 12]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+8.1.  Guidelines for IANA
+
+
+   It is requested that IANA updates the SASL mechanisms registry as
+   follows:
+
+
+      Change the "Intended usage" of the KERBEROS_V4 and SKEY mechanism
+      registrations to OBSOLETE.  Change the "Published specification"
+      of the EXTERNAL mechanism to this document. Updated registration
+      is provided in Section 8.6.
+
+8.2.  Registration procedure
+
+
+   Registration of a SASL mechanism is done by filling in the template
+   in section 8.5 and sending it via electronic mail to <iana@iana.org>.
+   IANA has the right to reject obviously bogus registrations, but will
+   perform no review of claims made in the registration form.  SASL
+   mechanism registrations are currently available at the URL
+   <http://www.iana.org/assignments/sasl-mechanisms>.
+
+   There is no naming convention for SASL mechanisms; any name that
+   conforms to the syntax of a SASL mechanism name can be registered.
+   An IETF Standards Track document may reserve a portion of the SASL
+   mechanism namespace ("family of SASL mechanisms") for its own use,
+   amending the registration rules for that portion of the namespace.
+   Each family of SASL mechanisms MUST be identified by a prefix.
+
+   While the registration procedures do not require it, authors of SASL
+   mechanisms are encouraged to seek community review and comment
+   whenever that is feasible.  Authors may seek community review by
+   posting a specification of their proposed mechanism as an Internet-
+   Draft.  SASL mechanisms intended for widespread use should be
+   standardized through the normal IETF process, when appropriate.
+
+8.3.  Comments on SASL mechanism registrations
+
+   Comments on registered SASL mechanisms should first be sent to the
+   "owner" of the mechanism and/or to the SASL WG mailing list.
+   Submitters of comments may, after a reasonable attempt to contact the
+   owner, request IANA to attach their comment to the SASL mechanism
+   registration itself.  If IANA approves of this, the comment will be
+   made accessible in conjunction with the SASL mechanism registration
+   itself.
+
+
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 13]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+8.4.  Change control
+
+   Once a SASL mechanism registration has been published by IANA, the
+   author may request a change to its definition.  The change request
+   follows the same procedure as the registration request.
+
+   The owner of a SASL mechanism may pass responsibility for the SASL
+   mechanism to another person or agency by informing IANA; this can be
+   done without discussion or review.
+
+   The IESG may reassign responsibility for a SASL mechanism. The most
+   common case of this will be to enable changes to be made to
+   mechanisms where the author of the registration has died, moved out
+   of contact or is otherwise unable to make changes that are important
+   to the community.
+
+   SASL mechanism registrations may not be deleted; mechanisms which are
+   no longer believed appropriate for use can be declared OBSOLETE by a
+   change to their "intended use" field; such SASL mechanisms will be
+   clearly marked in the lists published by IANA.
+
+   The IESG is considered to be the owner of all SASL mechanisms which
+   are on the IETF standards track.
+
+8.5.  Registration template
+
+
+     Subject: Registration of SASL mechanism X
+
+     Family of SASL mechanisms: (YES or NO)
+
+     SASL mechanism name (or prefix for the family):
+
+     Security considerations:
+
+     Published specification (optional, recommended):
+
+     Person & email address to contact for further information:
+
+     Intended usage:
+
+     (One of COMMON, LIMITED USE or OBSOLETE)
+
+     Owner/Change controller:
+
+     (Any other information that the author deems interesting may be
+     added below this line.)
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 14]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+8.6.  The EXTERNAL mechanism registration
+
+   It is requested that the SASL Mechanism registry [IANA-SASL] entry
+   for the EXTERNAL mechanism be updated to reflect that this document
+   now provides its technical specification.
+
+
+      Subject: Updated Registration of SASL mechanism EXTERNAL
+
+      Family of SASL mechanisms: NO
+
+      SASL mechanism name: EXTERNAL
+
+      Security considerations: See RFC XXXX, section 9.
+
+      Published specification (optional, recommended): RFC XXXX
+
+      Person & email address to contact for further information:
+        Alexey Melnikov <Alexey.Melnikov@isode.com>
+
+      Intended usage: COMMON
+
+      Owner/Change controller: IESG <iesg@ietf.org>
+
+      Note: Updates existing entry for EXTERNAL
+
+9.   Security considerations
+
+   Security issues are discussed throughout this memo.
+
+   The mechanisms that support integrity protection are designed such
+   that the negotiation of the security layer and authorization identity
+   is integrity protected.  When the client selects a security layer
+   with at least integrity protection, this protects against an active
+   attacker hijacking the connection and modifying the authentication
+   exchange to negotiate a plaintext connection.
+
+   When a server or client supports multiple authentication mechanisms,
+   each of which has a different security strength, it is possible for
+   an active attacker to cause a party to use the least secure mechanism
+   supported.  To protect against this sort of attack, a client or
+   server which supports mechanisms of different strengths should have a
+   configurable minimum strength that it will use.  It is not sufficient
+   for this minimum strength check to only be on the server, since an
+   active attacker can change which mechanisms the client sees as being
+   supported, causing the client to send authentication credentials for
+   its weakest supported mechanism.
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 15]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   The client's selection of a SASL mechanism is done in the clear and
+   may be modified by an active attacker.  It is important for any new
+   SASL mechanisms to be designed such that an active attacker cannot
+   obtain an authentication with weaker security properties by modifying
+   the SASL mechanism name and/or the challenges and responses.
+
+   Any protocol interactions prior to authentication are performed in
+   the clear and may be modified by an active attacker.  In the case
+   where a client selects integrity protection, it is important that any
+   security-sensitive protocol negotiations be performed after
+   authentication is complete.  Protocols should be designed such that
+   negotiations performed prior to authentication should be either
+   ignored or revalidated once authentication is complete.
+
+   When use of a security layer is negotiated by the authentication
+   protocol exchange, the receiver should handle gracefully any security
+   encoded data buffer larger than the defined/negotiated maximal size.
+   In particular, it must not blindly allocate the amount of memory
+   specified in the buffer size field, as this might cause the "out of
+   memory" condition. If the receiver detects a large block, it SHOULD
+   close the connection.
+
+   "stringprep" and Unicode security considerations apply to
+   authentication identities, authorization identities and passwords.
+
+   The EXTERNAL mechanism provides no security protection; it is
+   vulnerable to spoofing by either client or server, active attack, and
+   eavesdropping.  It should only be used when external security
+   mechanisms are present and have sufficient strength.
+
+10.    References
+
+10.1.  Normative References
+
+   [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications:
+   ABNF", RFC 2234, November 1997
+
+   [ASCII] American National Standards Institute, "Code Extension
+   Techniques for Use with the 7-bit Coded Character Set of American
+   National Standard Code (ASCII) for Information Interchange", FIPS PUB
+   35, 1974
+
+   [CHARSET-POLICY] Alvestrand, "IETF Policy on Character Sets and
+   Languages", RFC 2277, January 1998
+
+   [GSSAPI] Linn, "Generic Security Service Application Program
+   Interface, Version 2, Update 1", RFC 2743, January 2000
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 16]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   [ISO-10646] "Universal Multiple-Octet Coded Character Set (UCS) -
+   Architecture and Basic Multilingual Plane", ISO/IEC 10646-1 : 1993.
+
+   [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate
+   Requirement Levels", RFC 2119, March 1997
+
+   [Unicode] The Unicode Consortium, "The Unicode Standard, Version
+   3.2.0" is defined by "The Unicode Standard, Version 3.0" (Reading,
+   MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), as amended by the
+   "Unicode Standard Annex #27: Unicode 3.1"
+   (http://www.unicode.org/reports/tr27/) and by the "Unicode Standard
+   Annex #28: Unicode 3.2" (http://www.unicode.org/reports/tr28/).
+
+   [Stringprep] P. Hoffman, M. Blanchet, "Preparation of
+   Internationalized Strings ("stringprep")", RFC 3454, December 2002.
+
+   [SASLPrep] Zeilenga, K., "SASLprep: Stringprep profile for user names
+   and passwords", Work in progress, draft-ietf-sasl-saslprep-XX.txt.
+
+   [UTF-8] Yergeau, "UTF-8, a transformation format of ISO 10646", work
+   in progress (draft-yergeau-rfc2279bis-XX) that replaces RFC 2279,
+   Janyary 1998
+
+10.2.  Informative References
+
+   <<Update the reference below>> [SASL-GSSAPI] Myers, J., "SASL GSSAPI
+   mechanisms", work in progress, draft-ietf-cat-sasl-gssapi-XX.txt,
+   September 2000
+
+   [SASL-DIGEST] Leach, P., Newman, C., Melnikov, A., "Using Digest
+   Authentication as a SASL Mechanism", work in progress, draft-ietf-
+   sasl-rfc2831bis-XX.txt, replaces RFC 2831
+
+   [SASL-OTP] Newman, C., "The One-Time-Password SASL Mechanism", RFC
+   2444, October 1998
+
+   [SMTP] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821, April
+   2001
+
+   [SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication",
+   RFC 2554, March 1999
+
+   [BASE64] Josefsson, S., "The Base16, Base32, and Base64 Data
+   Encodings", RFC 3548, July 2003
+
+   [RFC-INSTRUCTIONS] Postel, Reynolds, "Instructions to RFC Authors",
+   RFC 2223, October 1997
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 17]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   [IANA-SASL]  IANA, "SIMPLE AUTHENTICATION AND SECURITY LAYER (SASL)
+   MECHANISMS", http://www.iana.org/assignments/sasl-mechanisms.
+
+11.   Editor's Address
+
+     Alexey Melnikov
+     Isode
+
+     Email: Alexey.Melnikov@isode.com
+
+12.   Acknowledgments
+
+   This document is a revision of RFC 2222 written by John G. Myers.  He
+   also contributed significantly to this revision.
+
+   Magnus Nystrom provided the ASCII art used in Section 6.3.
+
+   Definition of realm was extracted from RFC 2617 ("HTTP
+   Authentication: Basic and Digest Access Authentication").
+
+   Contributions of many members of the SASL mailing list are gratefully
+   acknowledged, in particular Kurt D. Zeilenga, Peter Saint-Andre, Rob
+   Siemborski, Jeffrey Hutzelman and  Hallvard B Furuseth for
+   proofreading the document and various editorial suggestions.
+
+
+13.   Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+
+
+
+A. Melnikov                                            FORMFEED[Page 18]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+Appendix A. Relation of SASL to transport security
+
+   Questions have been raised about the relationship between SASL and
+   various services (such as IPsec and TLS) which provide a secured
+   connection.
+
+   Two of the key features of SASL are:
+
+      The separation of the authorization identity from the identity in
+      the client's credentials.  This permits agents such as proxy
+      servers to authenticate using their own credentials, yet request
+      the access privileges of the identity for which they are proxying.
+
+      Upon successful completion of an authentication exchange, the
+      server knows the authorization identity the client wishes to use.
+      This allows servers to move to a "user is authenticated" state in
+      the protocol.
+
+   These features are extremely important to some application protocols,
+   yet Transport Security services do not always provide them.  To
+   define SASL mechanisms based on these services would be a very messy
+   task, as the framing of these services would be redundant with the
+   framing of SASL and some method of providing these important SASL
+   features would have to be devised.
+
+   Sometimes it is desired to enable within an existing connection the
+   use of a security service which does not fit the SASL model.  (TLS is
+   an example of such a service.)  This can be done by adding a command,
+   for example "STARTTLS", to the protocol.  Such a command is outside
+   the scope of SASL, and should be different from the command which
+   starts a SASL authentication protocol exchange.
+
+   In certain situations, it is reasonable to use SASL underneath one of
+   these Transport Security services.  The transport service would
+   secure the connection, either service would authenticate the client,
+   and SASL would negotiate the authorization identity.  The SASL
+   negotiation would be what moves the protocol from "unauthenticated"
+
+
+
+A. Melnikov                                            FORMFEED[Page 19]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   to "authenticated" state.  The "EXTERNAL" SASL mechanism is
+   explicitly intended to handle the case where the transport service
+   secures the connection and authenticates the client and SASL
+   negotiates the authorization identity.
+
+Appendix B. Changes since RFC 2222
+
+   The GSSAPI mechanism was removed.  It is now specified in a separate
+   document [SASL-GSSAPI].
+
+   The "KERBEROS_V4" mechanism defined in RFC 2222 is obsolete and has
+   been removed.
+
+   The "SKEY" mechanism described in RFC 2222 is obsolete and has been
+   removed.  It has been replaced by the OTP mechanism [SASL-OTP].
+
+   The overview has been substantially reorganized and clarified.
+
+   Clarified the definition and semantics of the authorization identity.
+
+   Prohibited the NUL character in authorization identities.
+
+   Added a section on character string issues.
+
+   The word "must" in the first paragraph of the "Protocol profile
+   requirements" section was changed to "MUST".
+
+   Specified that protocol profiles SHOULD provide a way for clients to
+   discover available SASL mechanisms.
+
+   Made the requirement that protocol profiles specify the semantics of
+   the authorization identity optional to the protocol profile.
+   Clarified that such a specification is a refinement of the definition
+   in the base SASL spec.
+
+   Added a requirement discouraging protocol profiles from breaking the
+   separation between protocol and mechanism.
+
+   Mentioned that standards track documents may carve out their own
+   portions of the SASL mechanism namespace and may amend registration
+   rules for the portion. However registration of individual SASL
+   mechanisms is still required.
+
+   Specified that the authorization identity in the EXTERNAL mechanism
+   is encoded in UTF-8.
+
+   Added a statement that a protocol profile SHOULD allow challenge data
+   to be sent with a success indication.
+
+
+
+A. Melnikov                                            FORMFEED[Page 20]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   Added a security consideration for the EXTERNAL mechansim.
+
+   Clarified sections concerning success with additional data.
+
+   Cleaned up IANA considerations/registrations and assembled them in
+   one place.
+
+   Updated references and split them into Informative and Normative.
+
+   Added text to the Security Considerations section regarding handling
+   of extremely large SASL blocks.
+
+   Replaced UTF-8 ABNF with the reference to the UTF-8 document.
+
+   Added text about SASLPrep for authentication identities and
+   passwords.  Described where SASLPrep preparation should take place.
+
+   Added paragraph about verifying authorization identities.
+
+   This document requires to drop a security layer on reauthentication
+   when no security layer is negotiated. This differs from RFC 2222,
+   which required to keep the last security layer in this case.
+
+   Added a protocol profile requirement to specify interaction between
+   SASL and TLS security layers.
+
+   Added a protocol profile requirement to specify if it supports
+   reauthentication.
+
+   Removed the text that seemed to suggest that SASL security layer must
+   not be used when TLS is available.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A. Melnikov                                            FORMFEED[Page 21]
+
+
+
+
+
+Internet DRAFT                    SASL                   18 October 2003
+
+
+   Status of this Memo .......................................... i
+   1.    Abstract ............................................... 2
+   2.    Organization of this document .......................... 2
+   2.1.  How to read this document .............................. 2
+   2.2.  Conventions used in this document ...................... 2
+   3.    Overview ............................................... 3
+   4.    Authentication mechanisms .............................. 3
+   4.1.  Authentication protocol exchange ....................... 4
+   4.2.  Authorization identities and proxy authentication ...... 4
+   4.3.  Security layers ........................................ 6
+   4.4.  Character string issues ................................ 6
+   5.    Protocol profile requirements .......................... 6
+   6.    Specific issues ........................................ 8
+   6.1.  Client sends data first ................................ 8
+   6.2.  Server returns success with additional data ............ 8
+   6.3.  Multiple authentications ............................... 9
+   7.    The EXTERNAL mechanism ................................ 11
+   7.1.  Formal syntax ......................................... 12
+   7.2.  Example ............................................... 12
+   8.    IANA Considerations ................................... 12
+   8.1.  Guidelines for IANA ................................... 13
+   8.2.  Registration procedure ................................ 13
+   8.3.  Comments on SASL mechanism registrations .............. 13
+   8.4.  Change control ........................................ 14
+   8.5.  Registration template ................................. 14
+   8.6.  The EXTERNAL mechanism registration ................... 15
+   9.   Security considerations ................................ 15
+   10.    References ........................................... 16
+   10.1.  Normative References ................................. 16
+   10.2.  Informative References ............................... 17
+   11.   Editor's Address ...................................... 18
+   12.   Acknowledgments ....................................... 18
+   13.   Full Copyright Statement .............................. 18
+   Appendix A. Relation of SASL to transport security .......... 19
+   Appendix B. Changes since RFC 2222 .......................... 20
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A. Melnikov                                            FORMFEED[Page ii]
+
+
diff --git a/doc/draft-ietf-sasl-rfc2831bis-xx.txt b/doc/draft-ietf-sasl-rfc2831bis-xx.txt
new file mode 100644 (file)
index 0000000..dd3b9b0
--- /dev/null
@@ -0,0 +1,2340 @@
+
+
+
+
+
+
+INTERNET-DRAFT                                                  P. Leach
+Obsoletes: 2831                                                Microsoft
+Intended category: Standards track                             C. Newman
+                                                        Sun Microsystems
+                                                             A. Melnikov
+                                                                   Isode
+                                                               June 2003
+
+            Using Digest Authentication as a SASL Mechanism
+                   draft-ietf-sasl-rfc2831bis-02.txt
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC 2026.
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that other
+   groups may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time. It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+Abstract
+
+   This specification defines how HTTP Digest Authentication [Digest]
+   can be used as a SASL [RFC 2222] mechanism for any protocol that has
+   a SASL profile. It is intended both as an improvement over CRAM-MD5
+   [RFC 2195] and as a convenient way to support a single authentication
+   mechanism for web, mail, LDAP, and other protocols.
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 1]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+Table of Contents
+
+   1 INTRODUCTION.....................................................3
+    1.1 CONVENTIONS AND NOTATION......................................3
+    1.2 REQUIREMENTS..................................................4
+   2 AUTHENTICATION...................................................5
+    2.1 INITIAL AUTHENTICATION........................................5
+     2.1.1 Step One...................................................5
+     2.1.2 Step Two...................................................9
+     2.1.3 Step Three................................................16
+    2.2 SUBSEQUENT AUTHENTICATION....................................17
+     2.2.1 Step one..................................................17
+     2.2.2 Step Two..................................................17
+    2.3 INTEGRITY PROTECTION.........................................18
+    2.4 CONFIDENTIALITY PROTECTION...................................18
+   3 SECURITY CONSIDERATIONS.........................................21
+    3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........21
+    3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................21
+    3.3 REPLAY ATTACKS...............................................21
+    3.4 ONLINE DICTIONARY ATTACKS....................................22
+    3.5 OFFLINE DICTIONARY ATTACKS...................................22
+    3.6 MAN IN THE MIDDLE............................................22
+    3.7 CHOSEN PLAINTEXT ATTACKS.....................................22
+    3.8 CBC MODE ATTACKS.............................................
+    3.9 SPOOFING BY COUNTERFEIT SERVERS..............................23
+    3.10 STORING PASSWORDS...........................................23
+    3.11 MULTIPLE REALMS.............................................24
+    3.12 SUMMARY.....................................................24
+   4 EXAMPLE.........................................................24
+   5 REFERENCES......................................................26
+    5.1 NORMATIVE REFERENCES.........................................26
+    5.2 INFORMATIVE REFERENCES.......................................27
+   6 AUTHORS' ADDRESSES..............................................28
+   7 ABNF............................................................29
+    7.1 AUGMENTED BNF................................................29
+    7.2 BASIC RULES..................................................31
+   8 SAMPLE CODE.....................................................33
+   9 INTEROPERABILITY CONSIDERATIONS.................................34
+    9.1 Implementing DES cipher in CBC mode..........................34
+   10  ACKNOWLEDGEMENTS..............................................34
+   11 FULL COPYRIGHT STATEMENT.......................................35
+   Appendix A: Changes from 2831.....................................36
+   Appendix B: Open Issues...........................................37
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 2]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+1  Introduction
+
+   This specification describes the use of HTTP Digest Access
+   Authentication as a SASL mechanism. The authentication type
+   associated with the Digest SASL mechanism is "DIGEST-MD5".
+
+   This specification is intended to be upward compatible with the
+   "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication
+   specified in [Digest]. The only difference in the "md5-sess"
+   algorithm is that some directives not needed in a SASL mechanism have
+   had their values defaulted.
+
+   There is one new feature for use as a SASL mechanism: integrity
+   protection on application protocol messages after an authentication
+   exchange.
+
+   Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext
+   attacks, and permits the use of third party authentication servers,
+   mutual authentication, and optimized reauthentication if a client has
+   recently authenticated to a server.
+
+1.1  Conventions and Notation
+
+   This specification uses the same ABNF notation and lexical
+   conventions as HTTP/1.1 specification; see section 7.
+
+   Let { a, b, ... } be the concatenation of the octet strings a, b, ...
+
+   Let ** denote the power operation.
+
+   Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.
+
+   Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string
+   k, a colon and the string s.
+
+   Let HEX(n) be the representation of the 16 octet MD5 hash n as a
+   string of 32 hex digits (with alphabetic characters always in lower
+   case, since MD5 is case sensitive).
+
+   Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet
+   string s using the octet string k as a key.
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 3]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   Let unq(X) be the value of the quoted-string X without the
+   surrounding quotes and with all escape characters "\\" removed. For
+   example for the quoted-string "Babylon" the value of unq("Babylon")
+   is Babylon; for the quoted string "ABC\"123\\" the value of
+   unq("ABC\"123\\") is ABC"123\.
+
+   The value of a quoted string constant as an octet string does not
+   include any terminating null character.
+
+1.2  Requirements
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in RFC 2119 [RFC 2119].
+
+   An implementation is not compliant if it fails to satisfy one or more
+   of the MUST level requirements for the protocols it implements. An
+   implementation that satisfies all the MUST level and all the SHOULD
+   level requirements for its protocols is said to be "unconditionally
+   compliant"; one that satisfies all the MUST level requirements but
+   not all the SHOULD level requirements for its protocols is said to be
+   "conditionally compliant."
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 4]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+2  Authentication
+
+   The following sections describe how to use Digest as a SASL
+   authentication mechanism.
+
+2.1  Initial Authentication
+
+   If the client has not recently authenticated to the server, then it
+   must perform "initial authentication", as defined in this section. If
+   it has recently authenticated, then a more efficient form is
+   available, defined in the next section.
+
+2.1.1  Step One
+
+   The server starts by sending a challenge. The data encoded in the
+   challenge contains a string formatted according to the rules for a
+   "digest-challenge" defined as follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 5]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   digest-challenge  =
+         1#( realm | nonce | qop-options | stale | server_maxbuf | charset
+               algorithm | cipher-opts | auth-param )
+
+        realm             = "realm" "=" <"> realm-value <">
+        realm-value       = qdstr-val
+        nonce             = "nonce" "=" <"> nonce-value <">
+        nonce-value       = *qdtext
+        qop-options       = "qop" "=" <"> qop-list <">
+        qop-list          = 1#qop-value
+        qop-value         = "auth" | "auth-int" | "auth-conf" |
+                             token
+        stale             = "stale" "=" "true"
+        server_maxbuf     = "maxbuf" "=" maxbuf-value
+        maxbuf-value      = 1*DIGIT
+        charset           = "charset" "=" "utf-8"
+        algorithm         = "algorithm" "=" "md5-sess"
+        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
+        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
+                            "rc4-56" | "aes" | token
+        auth-param        = token "=" ( token | quoted-string )
+
+   The meanings of the values of the directives used above are as
+   follows:
+
+   realm
+      Mechanistically, a string which can enable users to know which
+      username and password to use, in case they might have different
+      ones for different servers. Conceptually, it is the name of a
+      collection of accounts that might include the user's account. This
+      string should contain at least the name of the host performing the
+      authentication and might additionally indicate the collection of
+      users who might have access. An example might be
+      "registered_users@gotham.news.example.com".  This directive is
+      optional; if not present, the client SHOULD solicit it from the
+      user or be able to compute a default; a plausible default might be
+      the realm supplied by the user when they logged in to the client
+      system.  Multiple realm directives are allowed, in which case the
+      user or client must choose one as the realm for which to supply to
+      username and password.
+
+      If at least one realm is present and the charset directive is also
+      specified (which means that realm(s) are encoded as UTF-8), the
+      client should prepare each instance of realm using the "SASLPrep"
+      profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If
+      preparation of a realm instance fails or results in an empty
+      string, the client should abort the authentication exchange.
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 6]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   nonce
+      A server-specified data string which MUST be different each time a
+      digest-challenge is sent as part of initial authentication.  It is
+      recommended that this string be base64 or hexadecimal data. Note
+      that since the string is passed as a quoted string, the
+      double-quote character is not allowed unless escaped (see section
+      7.2). The contents of the nonce are implementation dependent. The
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. The nonce
+      is opaque to the client. This directive is required and MUST
+      appear exactly once; if not present, or if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   qop-options
+      A quoted string of one or more tokens indicating the "quality of
+      protection" values supported by the server.  The value "auth"
+      indicates authentication; the value "auth-int" indicates
+      authentication with integrity protection; the value "auth-conf"
+      indicates authentication with integrity protection and encryption.
+      This directive is optional; if not present it defaults to "auth".
+      The client MUST ignore unrecognized options; if the client
+      recognizes no option, it should abort the authentication exchange.
+
+   stale
+      The "stale" directive is not used in initial authentication. See
+      the next section for its use in subsequent authentications. This
+      directive may appear at most once; if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   server_maxbuf ("maximal ciphertext buffer size")
+      A number indicating the size of the largest buffer the server is
+      able to receive when using "auth-int" or "auth-conf". The value
+      MUST be bigger than 16 and smaller or equal to 16777215 (i.e.
+      2**24-1). If this directive is missing, the default value is
+      65536. This directive may appear at most once; if multiple
+      instances are present, the client MUST abort the authentication
+      exchange.
+
+      Let call "maximal cleartext buffer size" (or "maximal sender
+      size") the maximal size of a cleartext buffer that, after being
+      transformed by integrity (section 2.3) or confidentiality (section
+      2.4) protection function, will produce a SASL block of the maxbuf
+      size.  As it should be clear from the name, the sender MUST never
+      pass a block of data bigger than the "maximal sender size" through
+      the selected protection function.  This will guaranty that the
+      receiver will never get a block bigger than the maxbuf.
+
+
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 7]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   charset
+      This directive, if present, specifies that the server supports
+      UTF-8 [UTF-8] encoding for the username, realm and password. If
+      present, the username, realm and password are in Unicode, prepared
+      using the "SASLPrep" profile [SASLPrep] of the "stringprep"
+      algorithm [StringPrep] and than encoded as UTF-8 [UTF-8].  If not
+      present, the username, realm and password MUST be encoded in ISO
+      8859-1 [ISO-8859] (of which US-ASCII [USASCII] is a subset). The
+      directive is needed for backwards compatibility with HTTP Digest,
+      which only supports ISO 8859-1.  This directive may appear at most
+      once; if multiple instances are present, the client should abort
+      the authentication exchange.
+
+      Note, that this directive doesn't affect authorization id
+      ("authzid").
+
+   algorithm
+      This directive is required for backwards compatibility with HTTP
+      Digest, which supports other algorithms. This directive is
+      required and MUST appear exactly once; if not present, or if
+      multiple instances are present, the client should abort the
+      authentication exchange.
+
+   cipher-opts
+      A list of ciphers that the server supports. This directive must be
+      present exactly once if "auth-conf" is offered in the
+      "qop-options" directive, in which case the "3des" cipher is
+      mandatory-to-implement. The client MUST ignore unrecognized
+      options; if the client recognizes no option, it should abort the
+      authentication exchange. See section 2.4 for more detailed
+      description of the ciphers.
+
+      des
+         the Data Encryption Standard (DES) cipher [FIPS] in cipher
+         block chaining (CBC) mode with a 56 bit key.
+
+      3des
+         the "triple DES" cipher in CBC mode with EDE
+         (Encrypt,Decrypt,Encrypt) with the same key for each E stage
+         (aka "two keys mode") for a total key length of 112 bits.
+
+      rc4, rc4-40, rc4-56
+         the RC4 cipher with a 128 bit, 40 bit, and 56 bit key,
+         respectively.
+
+      aes
+         the Advanced Encryption Standard (AES) cipher [AES] in cipher
+         block chaining (CBC) mode with a 128 bit key. This mode
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 8]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+         requires an Initialization Vector (IV) that has the same size
+         as the block size.
+
+   auth-param
+      This construct allows for future extensions; it may appear more
+      than once. The client MUST ignore any unrecognized directives.
+
+   For use as a SASL mechanism, note that the following changes are made
+   to "digest-challenge" from HTTP: the following Digest options (called
+   "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent,
+   and MUST be ignored if received):
+
+    opaque
+    domain
+
+   The size of a digest-challenge MUST be less than 2048 bytes.
+
+2.1.2  Step Two
+
+   The client makes note of the "digest-challenge" and then responds
+   with a string formatted and computed according to the rules for a
+   "digest-response" defined as follows:
+
+   digest-response  = 1#( username | realm | nonce | cnonce |
+                          nonce-count | qop | digest-uri | response |
+                          client_maxbuf | charset | cipher | authzid |
+                          auth-param )
+
+       username         = "username" "=" <"> username-value <">
+       username-value   = qdstr-val
+       cnonce           = "cnonce" "=" <"> cnonce-value <">
+       cnonce-value     = *qdtext
+       nonce-count      = "nc" "=" nc-value
+       nc-value         = 8LHEX
+       client_maxbuf    = "maxbuf" "=" maxbuf-value
+       qop              = "qop" "=" qop-value
+       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
+       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
+       serv-type        = 1*ALPHA
+       serv-name        = host
+       response         = "response" "=" response-value
+       response-value   = 32LHEX
+       LHEX             = "0" | "1" | "2" | "3" |
+                          "4" | "5" | "6" | "7" |
+                          "8" | "9" | "a" | "b" |
+                          "c" | "d" | "e" | "f"
+       cipher           = "cipher" "=" cipher-value
+       authzid          = "authzid" "=" <"> authzid-value <">
+
+
+
+Leach & Newman           Expires: December 2003                 [Page 9]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+       authzid-value    = qdstr-val
+
+   The 'host' non-terminal is defined in [RFC 2732] as
+
+       host          = hostname | IPv4address | IPv6reference
+       ipv6reference = "[" IPv6address "]"
+
+   where IPv6address and IPv4address are defined in [RFC 2373]
+   and 'hostname' is defined in [RFC 2396].
+
+   username
+      The user's name in the specified realm, encoded according to the
+      value of the "charset" directive. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+      Upon the receipt of this value and if the charset directive is
+      also specified (which means that the username is encoded as
+      UTF-8), the server MUST prepare the username using the "SASLPrep"
+      profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If
+      preparation of the username fails or results in an empty string,
+      the server MUST fail the authentication exchange.
+
+   realm
+      The realm containing the user's account, encoded according to the
+      value of the "charset" directive. This directive is required if
+      the server provided any realms in the
+      "digest-challenge", in which case it may appear exactly once and
+      its value SHOULD be one of those realms. If the directive is
+      missing, "realm-value" will set to the empty string when computing
+      A1 (see below for details).
+
+      If realm was provided by the client and if the charset directive
+      was also specified (which means that the realm is encoded as
+      UTF-8), the server MUST prepare the realm using the "SASLPrep"
+      profile [SASLPrep] of the "stringprep" algorithm [StringPrep]. If
+      preparation of the realm fails or results in an empty string, the
+      server MUST fail the authentication exchange.
+
+   nonce
+      The server-specified data string received in the preceding digest-
+      challenge.  This directive is required and MUST be present exactly
+      once; otherwise, authentication fails.
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 10]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   cnonce
+      A client-specified data string which MUST be different each time a
+      digest-response is sent as part of initial authentication. The
+      cnonce-value is an opaque quoted string value provided by the
+      client and used by both client and server to avoid chosen
+      plaintext attacks, and to provide mutual authentication. The
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. This
+      directive is required and MUST be present exactly once; otherwise,
+      authentication fails.
+
+   nonce-count
+      The nc-value is the hexadecimal count of the number of requests
+      (including the current request) that the client has sent with the
+      nonce value in this request.  For example, in the first request
+      sent in response to a given nonce value, the client sends
+      "nc=00000001".  The purpose of this directive is to allow the
+      server to detect request replays by maintaining its own copy of
+      this count - if the same nc-value is seen twice, then the request
+      is a replay. See the description below of the construction of the
+      response value. This directive is required and MUST be present
+      exactly once; otherwise, authentication fails.
+
+   qop
+      Indicates what "quality of protection" the client accepted. If
+      present, it may appear exactly once and  its value MUST be one of
+      the alternatives in qop-options. If not present, it defaults to
+      "auth".  These values affect the computation of the response. Note
+      that this is a single token, not a quoted list of alternatives.
+
+   serv-type
+      Indicates the type of service, such as "http" for web service,
+      "ftp" for FTP service, "smtp" for mail delivery service, etc. The
+      service name as defined in the SASL profile for the protocol see
+      section 4 of [RFC 2222], registered in the IANA registry of
+      "service" elements for the GSSAPI host-based service name form
+      [RFC 2078].
+
+   host
+      The DNS host name or IP (IPv4 or IPv6) address for the service
+      requested.  The DNS host name must be the fully-qualified
+      canonical name of the host.  The DNS host name is the preferred
+      form; see notes on server processing of the digest-uri.
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 11]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   serv-name
+      Indicates the name of the service if it is replicated. The service
+      is considered to be replicated if the client's service-location
+      process involves resolution using standard DNS lookup operations,
+      and if these operations involve DNS records (such as SRV [RFC
+      2052], or MX) which resolve one DNS name into a set of other DNS
+      names. In this case, the initial name used by the client is the
+      "serv-name", and the final name is the "host" component. For
+      example, the incoming mail service for "example.com" may be
+      replicated through the use of MX records stored in the DNS, one of
+      which points at an SMTP server called "mail3.example.com"; it's
+      "serv-name" would be "example.com", it's "host" would be
+      "mail3.example.com". If the service is not replicated, or the
+      serv-name is identical to the host, then the serv-name component
+      MUST be omitted.
+
+   digest-uri
+      Indicates the principal name of the service with which the client
+      wishes to connect, formed from the serv-type, host, and serv-name.
+      For example, the FTP service on "ftp.example.com" would have a
+      "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from
+      the example above would have a "digest-uri" value of
+      "SMTP/mail3.example.com/example.com".
+
+   Servers SHOULD check that the supplied value is correct. This will
+   detect accidental connection to the incorrect server, as well as some
+   redirection attacks. It is also so that clients will be trained to
+   provide values that will work with implementations that use a shared
+   back-end authentication service that can provide server
+   authentication.
+
+   The serv-type component should match the service being offered. The
+   host component should match one of the host names of the host on
+   which the service is running, or it's IP address. Servers SHOULD NOT
+   normally support the IP address form, because server authentication
+   by IP address is not very useful; they should only do so if the DNS
+   is unavailable or unreliable. The serv-name component should match
+   one of the service's configured service names.
+
+   This directive may appear at most once; if multiple instances are
+   present, the client should abort the authentication exchange.
+
+   Note: In the HTTP use of Digest authentication, the digest-uri is the
+   URI (usually a URL) of the resource requested -- hence the name of
+   the directive.
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 12]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   response
+      A string of 32 hex digits computed as defined below, which proves
+      that the user knows a password. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+   client_maxbuf
+      A number indicating the size of the largest ciphertext buffer the
+      client is able to receive when using "auth-int" or "auth-conf". If
+      this directive is missing, the default value is 65536. This
+      directive may appear at most once; if multiple instances are
+      present, the server MUST abort the authentication exchange. If the
+      value is less or equal to 16 or bigger than 16777215 (i.e.
+      2**24-1), the server MUST abort the authentication exchange.
+
+      Upon processing/sending of the client_maxbuf value both the server
+      and the client calculate their "maximal ciphertext buffer size" as
+      the minimum of the server_maxbuf (Step One) and the client_maxbuf
+      (Step Two).  The "maximal sender size" can be calculated by
+      subtracting 16 from the calculated "maximal ciphertext buffer
+      size".
+
+      When sending a block of data the client/server MUST NOT pass more
+      than the "maximal sender size" bytes of data to the selected
+      protection function (2.3 or 2.4).
+
+   charset
+      This directive, if present, specifies that the client has used
+      UTF-8 [UTF-8] encoding for the username, realm and password. If
+      present, the username, realm and password are in Unicode, prepared
+      using the "SASLPrep" profile [SASLPrep] of the "stringprep"
+      algorithm [StringPrep] and than encoded as UTF-8 [UTF-8].  If not
+      present, the username and password must be encoded in ISO 8859-1
+      [ISO-8859] (of which
+      US-ASCII [USASCII] is a subset). The client should send this
+      directive only if the server has indicated it supports UTF-8
+      [UTF-8]. The directive is needed for backwards compatibility with
+      HTTP Digest, which only supports ISO 8859-1.
+
+      Note, that this directive doesn't affect authorization id
+      ("authzid").
+
+   LHEX
+      32 hex digits, where the alphabetic characters MUST be lower case,
+      because MD5 is not case insensitive.
+
+   cipher
+      The cipher chosen by the client. This directive MUST appear
+      exactly once if "auth-conf" is negotiated; if required and not
+
+
+
+Leach & Newman           Expires: December 2003                [Page 13]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+      present, authentication fails.
+
+   authzid
+      The "authorization ID" directive is optional. If present, and the
+      authenticating user has sufficient privilege, and the server
+      supports it, then after authentication the server will use this
+      identity for making all accesses and access checks. If the client
+      specifies it, and the server does not support it, then the
+      response-value calculated on the server will not match the one
+      calculated on the client and authentication will fail.
+
+      The authzid MUST NOT be an empty string.
+
+      The authorization identifier MUST NOT be converted to ISO 8859-1
+      even if the authentication identifier ("username") is converted
+      for compatibility as directed by "charset" directive.
+
+      The server SHOULD verify the correctness of an authzid as
+      specified by the corresponding SASL protocol profile.
+
+   The size of a digest-response MUST be less than 4096 bytes.
+
+2.1.2.1   Response-value
+
+   The definition of "response-value" above indicates the encoding for
+   its value -- 32 lower case hex characters. The following definitions
+   show how the value is computed.
+
+   Although qop-value and components of digest-uri-value may be
+   case-insensitive, the case which the client supplies in step two is
+   preserved for the purpose of computing and verifying the
+   response-value.
+
+      response-value  =
+         HEX( KD ( HEX(H(A1)),
+                 { nonce-value, ":" nc-value, ":",
+                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
+
+   If authzid is specified, then A1 is
+
+
+      A1 = { H( { unq(username-value), ":", unq(realm-value), ":", passwd } ),
+           ":", nonce-value, ":", cnonce-value, ":", unq(authzid-value) }
+
+   If authzid is not specified, then A1 is
+
+
+      A1 = { H( { unq(username-value), ":", unq(realm-value), ":", passwd } ),
+
+
+
+Leach & Newman           Expires: December 2003                [Page 14]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+           ":", nonce-value, ":", cnonce-value }
+
+   where
+
+         passwd   = *OCTET
+
+   The "username-value", "realm-value" and "passwd" are encoded
+   according to the value of the "charset" directive. If "charset=UTF-8"
+   is present, and all the characters of "username-value" are, after
+   preparing using the "SASLPrep" profile [SASLPrep] of the "stringprep"
+   algorithm [StringPrep], in the ISO 8859-1 character set, then it must
+   be converted to ISO 8859-1 before being hashed. The same
+   transformation has to be done for "realm-value" and "passwd". This is
+   so that authentication databases that store the hashed username,
+   realm and password (which is common) can be shared compatibly with
+   HTTP, which specifies ISO 8859-1. A sample implementation of this
+   conversion is in section 8.
+
+   If the "qop" directive's value is "auth", then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 15]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   If the "qop" value is "auth-int" or "auth-conf" then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value,
+               ":00000000000000000000000000000000" }
+
+   Note that "AUTHENTICATE:" must be in upper case, and the second
+   string constant is a string with a colon followed by 32 zeros.
+
+   These apparently strange values of A2 are for compatibility with
+   HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and
+   the hash of the entity body to zero in the HTTP digest calculation of
+   A2.
+
+   Also, in the HTTP usage of Digest, several directives in the
+   "digest-challenge" sent by the server have to be returned by the
+   client in the "digest-response". These are:
+
+    opaque
+    algorithm
+
+   These directives are not needed when Digest is used as a SASL
+   mechanism (i.e., MUST NOT be sent, and MUST be ignored if received).
+
+2.1.3  Step Three
+
+   The server receives and validates the "digest-response". The server
+   checks that the nonce-count is "00000001". If it supports subsequent
+   authentication (see section 2.2), it saves the value of the nonce and
+   the nonce-count. It sends a message formatted as follows:
+
+    response-auth = "rspauth" "=" response-value
+
+   where response-value is calculated as above, using the values sent in
+   step two, except that if qop is "auth", then A2 is
+
+       A2 = { ":", digest-uri-value }
+
+   And if qop is "auth-int" or "auth-conf" then A2 is
+
+       A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
+
+   Compared to its use in HTTP, the following Digest directives in the
+   "digest-response" are unused:
+
+       nextnonce
+       qop
+       cnonce
+       nonce-count
+
+
+
+Leach & Newman           Expires: December 2003                [Page 16]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+2.2  Subsequent Authentication
+
+   If the client has previously authenticated to the server, and
+   remembers the values of username, realm, nonce, nonce-count, cnonce,
+   and qop that it used in that authentication, and the SASL profile for
+   a protocol permits an initial client response, then it MAY perform
+   "subsequent authentication", as defined in this section.
+
+2.2.1  Step one
+
+   The client uses the values from the previous authentication and sends
+   an initial response with a string formatted and computed according to
+   the rules for a "digest-response", as defined above, but with a
+   nonce-count one greater than used in the last "digest-response".
+
+2.2.2  Step Two
+
+   The server receives the "digest-response". If the server does not
+   support subsequent authentication, then it sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication. If the server has no saved nonce and nonce-count from
+   a previous authentication, then it sends a "digest-challenge", and
+   authentication proceeds as in initial authentication. Otherwise, the
+   server validates the "digest-response", checks that the nonce-count
+   is one greater than that used in the previous authentication using
+   that nonce, and saves the new value of nonce-count.
+
+   If the response is invalid, then the server sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication (and should be configurable to log an authentication
+   failure in some sort of security audit log, since the failure may be
+   a symptom of an attack). The nonce-count MUST NOT be incremented in
+   this case: to do so would allow a denial of service attack by sending
+   an out-of-order nonce-count.
+
+   If the response is valid, the server MAY choose to deem that
+   authentication has succeeded. However, if it has been too long since
+   the previous authentication, or for any o including the next
+   subsequent authentication, between the client and the server MUST be
+   integrity protected. Using as a base session key the value of H(A1)
+   as defined above the client and server calculate a pair of message
+   integrity keys as follows.
+
+   The key for integrity protecting messages from client to server is:
+
+   Kic = MD5({H(A1),
+   "Digest session key to client-to-server signing key magic constant"})
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 17]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   The key for integrity protecting messages from server to client is:
+
+   Kis = MD5({H(A1),
+   "Digest session key to server-to-client signing key magic constant"})
+
+   where MD5 is as specified in [RFC 1321]. If message integrity is
+   negotiated, a MAC block for each message is appended to the message.
+   The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. The message type is to allow for future extensions such as
+   rekeying.
+
+   MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
+   SeqNum)
+
+   where Ki is Kic for messages sent by the client and Kis for those
+   sent by the server. The sequence number (SeqNum) is an unsigned
+   number initialized to zero after initial or subsequent
+   authentication, and incremented by one for each message
+   sent/successfully verified. (Note, that there are two independent
+   counters for sending and receiving.) The sequence number wraps around
+   to 0 after 2**32-1.
+
+   Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the
+   received value; the message is discarded if they differ. The
+   receiver's sequence counter is incremented if they match.
+
+2.4   Confidentiality Protection
+
+   If the server sent a "cipher-opts" directive and the client responded
+   with a "cipher" directive, then subsequent messages between the
+   client and the server MUST be confidentiality protected. Using as a
+   base session key the value of H(A1) as defined above the client and
+   server calculate a pair of message integrity keys as follows.
+
+   The key for confidentiality protecting messages from client to server
+   is:
+
+   Kcc = MD5({H(A1)[0..n-1],
+   "Digest H(A1) to client-to-server sealing key magic constant"})
+
+   The key for confidentiality protecting messages from server to client
+   is:
+
+   Kcs = MD5({H(A1)[0..n-1],
+   "Digest H(A1) to server-to-client sealing key magic constant"})
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 18]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5;
+   for "rc4-56" n is 7; for the rest n is 16. The key for the "rc4-*"
+   and "aes" ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is
+   the first 7 bytes; the key for "3des" is the first 14 bytes.
+
+   The IV used to send/receive the initial buffer of security encoded
+   data for "des" and "3des" is the last 8 bytes of Kcc or Kcs. For all
+   subsequent buffers the last 8 bytes of the ciphertext of the buffer
+   NNN is used as the IV for the buffer (NNN + 1).
+
+   The IV for the "aes" cipher in CBC mode for messages going from the
+   client to the server (IVc) consists of 16 bytes calculated as
+   follows:
+
+   IVc = MD5({Kcc, "aes-128"})
+
+   The IV for the "aes" cipher in CBC mode for messages going from the
+   server to the client (IVs) consists of 16 bytes calculated as
+   follows:
+
+   IVs = MD5({Kcs, "aes-128"})
+
+   The IV is XOR'd with the first plaintext block before it is encrypted
+   with "aes".  Then for successive blocks, the previous ciphertext
+   block is XOR'd with the current plaintext, before it is encrypted.
+
+   rc4 cipher state MUST NOT be reset before sending/receiving a next
+   buffer of security encoded data.
+
+   The MAC block is a variable length padding prefix followed by 16
+   bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. If the blocksize of the chosen cipher is not 1 byte, the
+   padding prefix is one or more octets each containing the number of
+   padding bytes, such that total length of the encrypted part of the
+   message is a multiple of the blocksize. The padding and first 10
+   bytes of the MAC block are encrypted with the chosen cipher along
+   with the message.
+
+   SEAL(Ki, Kc, SeqNum, msg) =
+         {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9]}), 0x0001,
+          SeqNum}
+
+   where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for
+   messages sent by the client and Kis and Kcs for those sent by the
+   server. The sequence number (SeqNum) is an unsigned number
+   initialized to zero after initial or subsequent authentication, and
+
+
+
+Leach & Newman           Expires: December 2003                [Page 19]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   incremented by one for each message sent/successfully verified.
+   (Note, that there are two independent counters for sending and
+   receiving.) The sequence number wraps around to 0 after 2**32-1.
+
+   Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is
+   computed and compared with the received value; the padding is
+   verified.  The message is discarded if the received and the
+   calculated HMACs differ and/or the padding is invalid. See also
+   section 3.8 for important information about MAC and padding
+   verification. The receiver's sequence counter is then compared with
+   the received SeqNum value; the message is discarded if they differ.
+   The receiver's sequence counter is incremented if they match.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 20]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+3  Security Considerations
+
+   General SASL security considerations apply to this mechanism.
+   "stringprep" and Unicode security considerations also apply.
+
+   Detailed discussion of other DIGEST-MD5 specific security issues is
+   below.
+
+3.1   Authentication of Clients using Digest Authentication
+
+   Digest Authentication does not provide a strong authentication
+   mechanism, when compared to public key based mechanisms, for example.
+   However, since it prevents chosen plaintext attacks, it is stronger
+   than (e.g.) CRAM-MD5, which has been proposed for use with ACAP [RFC
+   2244], POP and IMAP [RFC 2195]. It is intended to replace the much
+   weaker and even more dangerous use of plaintext passwords; however,
+   since it is still a password based mechanism it avoids some of the
+   potential deployabilty issues with public-key, OTP or similar
+   mechanisms.
+
+   Digest Authentication offers no confidentiality protection beyond
+   protecting the actual password. All of the rest of the challenge and
+   response are available to an eavesdropper, including the user's name
+   and authentication realm.
+
+3.2   Comparison of Digest with Plaintext Passwords
+
+   The greatest threat to the type of transactions for which these
+   protocols are used is network snooping. This kind of transaction
+   might involve, for example, online access to a mail service whose use
+   is restricted to paying subscribers. With plaintext password
+   authentication an eavesdropper can obtain the password of the user.
+   This not only permits him to access anything in the database, but,
+   often worse, will permit access to anything else the user protects
+   with the same password.
+
+3.3   Replay Attacks
+
+   Replay attacks are defeated if the client or the server chooses a
+   fresh nonce for each authentication, as this specification requires.
+
+   As a security precaution, the server, when verifying a response from
+   the client, must use the original server nonce ("nonce") it sent, not
+   the one returned by the client in the response, as it might have been
+   modified by an attacker.
+
+   To prevent some redirection attacks it is recommended that the server
+   verifies that the "serv-type" part of the "digest-uri" matches the
+
+
+
+Leach & Newman           Expires: December 2003                [Page 21]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   service name and that the hostname/IP address belongs to the server.
+
+3.4  Online dictionary attacks
+
+   If the attacker can eavesdrop, then it can test any overheard
+   nonce/response pairs against a (potentially very large) list of
+   common words. Such a list is usually much smaller than the total
+   number of possible passwords. The cost of computing the response for
+   each password on the list is paid once for each challenge.
+
+   The server can mitigate this attack by not allowing users to select
+   passwords that are in a dictionary.
+
+3.5  Offline dictionary attacks
+
+   If the attacker can choose the challenge, then it can precompute the
+   possible responses to that challenge for a list of common words. Such
+   a list is usually much smaller than the total number of possible
+   passwords. The cost of computing the response for each password on
+   the list is paid just once.
+
+   Offline dictionary attacks are defeated if the client chooses a fresh
+   nonce for each authentication, as this specification requires.
+
+3.6  Man in the Middle
+
+   Digest authentication is vulnerable to "man in the middle" (MITM)
+   attacks. Clearly, a MITM would present all the problems of
+   eavesdropping. But it also offers some additional opportunities to
+   the attacker.
+
+   A possible man-in-the-middle attack would be to substitute a weaker
+   qop scheme for the one(s) sent by the server; the server will not be
+   able to detect this attack. For this reason, the client should always
+   use the strongest scheme that it understands from the choices
+   offered, and should never choose a scheme that does not meet its
+   minimum requirements.
+
+   A man-in-the-middle attack may also make the client and the server
+   that agreed to use confidentiality protection to use different (and
+   possibly weaker) cipher's. This is because the chosen cipher is not
+   used in the shared secret calculation.
+
+3.7  Chosen plaintext attacks
+
+   A chosen plaintext attack is where a MITM or a malicious server can
+   arbitrarily choose the challenge that the client will use to compute
+   the response. The ability to choose the challenge is known to make
+
+
+
+Leach & Newman           Expires: December 2003                [Page 22]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   cryptanalysis much easier [MD5].
+
+   However, Digest does not permit the attack to choose the challenge as
+   long as the client chooses a fresh nonce for each authentication, as
+   this specification requires.
+
+3.8  CBC Mode attacks
+
+   The following attack can be launched when the connection uses
+   Confidentiality protection with ciphers in CBC mode. If bad padding
+   is treated differently from bad MACs when decrypting a DIGEST-MD5
+   buffer of security encoded data, the attacker may be able to launch
+   Vaudenay's attack on padding.
+
+   An error logfile will suffice to launch the attack if it reveals the
+   type of error -- even if file permissions prevent the attacker from
+   actually reading the file (the file length increase cause by the
+   attack is likely to reveal which of the two errors occured).
+
+   A different approach to distinguish these two error cases and launch
+   the attack is to examine the timing of error responses: if the MAC
+   verification is skipped when bad padding has been found, the error
+   will appear quicker in the case of incorrect block cipher padding
+   than in the case of an incorrect MAC.
+
+   A countermeasure is to compute a MAC of the plaintext anyway, even if
+   the usual padding removal step fails because of incorrect padding, to
+   obtain (nearly) uniform timing.
+
+3.9  Spoofing by Counterfeit Servers
+
+   If a user can be led to believe that she is connecting to a host
+   containing information protected by a password she knows, when in
+   fact she is connecting to a hostile server, then the hostile server
+   can obtain challenge/response pairs where it was able to partly
+   choose the challenge. There is no known way that this can be
+   exploited.
+
+3.10  Storing passwords
+
+   Digest authentication requires that the authenticating agent (usually
+   the server) store some data derived from the user's name and password
+   in a "password file" associated with a given realm. Normally this
+   might contain pairs consisting of username and H({ username-value,
+   ":", realm-value, ":", passwd }), which is adequate to compute H(A1)
+   as described above without directly exposing the user's password.
+
+   The security implications of this are that if this password file is
+
+
+
+Leach & Newman           Expires: December 2003                [Page 23]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   compromised, then an attacker gains immediate access to documents on
+   the server using this realm. Unlike, say a standard UNIX password
+   file, this information need not be decrypted in order to access
+   documents in the server realm associated with this file. On the other
+   hand, decryption, or more likely a brute force attack, would be
+   necessary to obtain the user's password. This is the reason that the
+   realm is part of the digested data stored in the password file. It
+   means that if one Digest authentication password file is compromised,
+   it does not automatically compromise others with the same username
+   and password (though it does expose them to brute force attack).
+
+   There are two important security consequences of this. First the
+   password file must be protected as if it contained plaintext
+   passwords, because for the purpose of accessing documents in its
+   realm, it effectively does.
+
+   A second consequence of this is that the realm string should be
+   unique among all realms that any single user is likely to use. In
+   particular a realm string should include the name of the host doing
+   the authentication.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 24]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+3.11  Multiple realms
+
+   Use of multiple realms may mean both that compromise of a the
+   security database for a single realm does not compromise all
+   security, and that there are more things to protect in order to keep
+   the whole system secure.
+
+3.11  Summary
+
+   By modern cryptographic standards Digest Authentication is weak,
+   compared to (say) public key based mechanisms. But for a large range
+   of purposes it is valuable as a replacement for plaintext passwords.
+   Its strength may vary depending on the implementation.
+
+
+4  Example
+
+   This example shows the use of the Digest SASL mechanism with the
+   IMAP4 AUTHENTICATE command [RFC 3501].
+
+   In this example, "C:" and "S:" represent a line sent by the client or
+   server respectively including a CRLF at the end.  Linebreaks and
+   indentation within a "C:" or "S:" are editorial and not part of the
+   protocol. The password in this example was "secret".  Note that the
+   base64 encoding of the challenges and responses is part of the IMAP4
+   AUTHENTICATE command, not part of the Digest specification itself.
+
+    S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9
+    C: c CAPABILITY
+    S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA
+                UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN
+    S: c OK Completed
+    C: a AUTHENTICATE DIGEST-MD5
+    S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
+         RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
+         cnNldD11dGYtOA==
+    C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
+       QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
+       MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
+       ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
+       ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
+    S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
+    C:
+    S: a OK User logged in
+    ---
+
+    The base64-decoded version of the SASL exchange is:
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 25]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+    S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
+       digest-uri="imap/elwood.innosoft.com",
+       response=d388dad90d4bbd760a152321f2143af7,qop=auth
+    S: rspauth=ea40f60335c427b5527b84dbabcdfffd
+
+    The password in this example was "secret".
+
+   This example shows the use of the Digest SASL mechanism with the
+   ACAP, using the same notational conventions and password as in the
+   previous example. Note that ACAP does not base64 encode and uses
+   fewer round trips that IMAP4.
+
+    S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5"
+               "DIGEST-MD5" "PLAIN")
+    C: a AUTHENTICATE "DIGEST-MD5"
+    S: + {94}
+    S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: {206}
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m",
+       digest-uri="acap/elwood.innosoft.com",
+       response=6084c6db3fede7352c551284490fd0fc,qop=auth
+    S: a OK (SASL {40}
+    S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE
+    Completed"
+    ---
+
+   The server uses the values of all the directives, plus knowledge of
+   the users password (or the hash of the user's name, server's realm
+   and the user's password) to verify the computations above. If they
+   check, then the user has authenticated.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 26]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+5   References
+
+5.1   Normative references
+
+   [Digest]   Franks, J., et al., "HTTP Authentication: Basic and Digest
+              Access Authentication", RFC 2617, June 1999.
+
+   [ISO-8859] ISO-8859. International Standard--Information Processing--
+              8-bit Single-Byte Coded Graphic Character Sets --
+              Part 1: Latin alphabet No. 1, ISO-8859-1:1987.
+              Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.
+              Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.
+              Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.
+              Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.
+              Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.
+              Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.
+              Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.
+              Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.
+
+   [RFC 822]  Crocker, D., "Standard for The Format of ARPA Internet
+              Text Messages," STD 11, RFC 822, August 1982.
+
+   [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+              April 1992.
+
+   [RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the
+              location of services (DNS SRV)", RFC 2052, October 1996.
+
+   [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC: Keyed-
+              Hashing for  Message Authentication", RFC 2104, February
+              1997.
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC 2222] Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997.
+
+   [Stringprep] Hoffman, P., Blanchet, M., "Preparation of
+              Internationalized Strings ("stringprep")", RFC 3454,
+              December 2002.
+
+   [Unicode] The Unicode Consortium, "The Unicode Standard, Version
+              3.2.0", defined by: The Unicode Standard, Version 3.0
+              (Reading, MA, Addison-Wesley, 2000.  ISBN 0-201-61633-5),
+              as amended by the Unicode Standard Annex #28: Unicode 3.2
+              (http://www.unicode.org/reports/tr28/tr28-3.html).
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 27]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   [UTF-8] Yergeau, "UTF-8, a transformation format of ISO 10646", RFC
+              2279, Janyary 1998.
+
+   [USASCII]  US-ASCII. Coded Character Set - 7-Bit American Standard
+              Code for Information Interchange. Standard ANSI X3.4-1986,
+              ANSI, 1986.
+
+   [SASLPrep] Zeilenga, K., "SASLprep: Stringprep profile for user names
+              and passwords", Work in progress, draft-ietf-sasl-
+              saslprep-XX.txt.
+
+   [RFC 2732]  Hinden, R., Carpenter, B., Masinter, L., "Format for
+              Literal IPv6 Addresses in URL's", RFC 2732, December 1999.
+
+   [RFC 2373] Hinden, R., Deering, S., "IP Version 6 Addressing
+              Architecture", RFC 2373, July 1998.
+
+   [RFC 2396] Berners-Lee, T., Fielding, R., Masinter, L., "Uniform
+              Resource Identifiers (URI): Generic Syntax", RFC 2396,
+              August 1998.
+
+   [FIPS] National Institute of Standards and Technology, "DES Modes of
+              Operation", http://www.itl.nist.gov/fipspubs/fip81.htm,
+              December 1980.
+
+   [AES] Daemen, J., Rijmen, V., "The Rijndael Block Cipher",
+              http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf,
+              3rd September 1999.
+
+
+5.2   Informative references
+
+   [RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+              AUTHorize Extension for Simple Challenge/Response", RFC
+              2195, September 1997.
+
+   [MD5]  Kaliski, B.,Robshaw, M., "Message Authentication with MD5",
+              CryptoBytes, Sping 1995, RSA Inc,
+              (http://www.rsa.com/rsalabs/pubs/cryptobytes/spring95/md5.htm)
+
+   [RFC 2078] Linn, J., "Generic Security Service Application Program
+              Interface, Version 2", RFC 2078, January 1997.
+
+   [RFC 3501] Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 3501, March 2003.
+
+   [RFC 2244] Newman, C., Myers, J., "ACAP -- Application Configuration
+              Access Protocol", RFC 2244, November 1997.
+
+
+
+Leach & Newman           Expires: December 2003                [Page 28]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   [RFC 2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H.,
+              Masinter, L., Leach, P., Berners-Lee, T., "Hypertext
+              Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999.
+
+   [TLS-CBC] Moeller, B., "Security of CBC Ciphersuites in SSL/TLS:
+              Problems and Countermeasures",
+              http://www.openssl.org/~bodo/tls-cbc.txt.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 29]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+6  Authors' Addresses
+
+   Paul Leach
+   Microsoft
+   1 Microsoft Way
+   Redmond, WA 98052, USA
+
+   EMail: paulle@microsoft.com
+
+
+   Chris Newman
+   Sun Microsystems
+   1050 Lakes Drive
+   West Covina, CA 91790, USA
+
+   EMail: Chris.Newman@Sun.COM
+
+
+   Alexey Melnikov
+   Isode
+   28 Gloucester Road,
+   Teddington, Middlesex, TW11 0NU, UK
+
+   Email: mel@isode.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 30]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+7  ABNF
+
+   What follows is the definition of the notation as is used in the
+   HTTP/1.1 specification [RFC 2616] and the HTTP authentication
+   specification [Digest]; it is reproduced here for ease of reference.
+   Since it is intended that a single Digest implementation can support
+   both HTTP and SASL-based protocols, the same notation is used in both
+   to facilitate comparison and prevention of unwanted differences.
+   Since it is cut-and-paste from the HTTP specifications, not all
+   productions may be used in this specification. It is also not quite
+   legal ABNF; again, the errors were copied from the HTTP
+   specifications.
+
+7.1   Augmented BNF
+
+   All of the mechanisms specified in this document are described in
+   both prose and an augmented Backus-Naur Form (BNF) similar to that
+   used by RFC 822 [RFC 822]. Implementers will need to be familiar with
+   the notation in order to understand this specification.
+
+   The augmented BNF includes the following constructs:
+
+   name = definition
+      The name of a rule is simply the name itself (without any
+      enclosing "<" and ">") and is separated from its definition by the
+      equal "=" character. White space is only significant in that
+      indentation of continuation lines is used to indicate a rule
+      definition that spans more than one line. Certain basic rules are
+      in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle
+      brackets are used within definitions whenever their presence will
+      facilitate discerning the use of rule names.
+
+   "literal"
+      Quotation marks surround literal text. Unless stated otherwise,
+      the text is case-insensitive.
+
+   rule1 | rule2
+      Elements separated by a bar ("|") are alternatives, e.g., "yes |
+      no" will accept yes or no.
+
+   (rule1 rule2)
+      Elements enclosed in parentheses are treated as a single element.
+      Thus, "(elem (foo | bar) elem)" allows the token sequences
+      "elem foo elem" and "elem bar elem".
+
+   *rule
+      The character "*" preceding an element indicates repetition. The
+      full form is "<n>*<m>element" indicating at least <n> and at most
+
+
+
+Leach & Newman           Expires: December 2003                [Page 31]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+      <m> occurrences of element. Default values are 0 and infinity so
+      that "*(element)" allows any number, including zero; "1*element"
+      requires at least one; and "1*2element" allows one or two.
+
+   [rule]
+      Square brackets enclose optional elements; "[foo bar]" is
+      equivalent to "*1(foo bar)".
+
+   N rule
+      Specific repetition: "<n>(element)" is equivalent to
+      "<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
+      Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
+      alphabetic characters.
+
+   #rule
+      A construct "#" is defined, similar to "*", for defining lists of
+      elements. The full form is "<n>#<m>element" indicating at least
+      <n> and at most <m> elements, each separated by one or more commas
+      (",") and OPTIONAL linear white space (LWS). This makes the usual
+      form of lists very easy; a rule such as
+        ( *LWS element *( *LWS "," *LWS element ))
+      can be shown as
+        1#element
+      Wherever this construct is used, null elements are allowed, but do
+      not contribute to the count of elements present. That is,
+      "(element), , (element) " is permitted, but counts as only two
+      elements.  Therefore, where at least one element is required, at
+      least one non-null element MUST be present. Default values are 0
+      and infinity so that "#element" allows any number, including zero;
+      "1#element" requires at least one; and "1#2element" allows one or
+      two.
+
+   ; comment
+      A semi-colon, set off some distance to the right of rule text,
+      starts a comment that continues to the end of line. This is a
+      simple way of including useful notes in parallel with the
+      specifications.
+
+   implied *LWS
+      The grammar described by this specification is word-based. Except
+      where noted otherwise, linear white space (LWS) can be included
+      between any two adjacent words (token or quoted-string), and
+      between adjacent words and separators, without changing the
+      interpretation of a field. At least one delimiter (LWS and/or
+      separators) MUST exist between any two tokens (for the definition
+      of "token" below), since they would otherwise be interpreted as a
+      single token.
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 32]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+7.2   Basic Rules
+
+   The following rules are used throughout this specification to
+   describe basic parsing constructs. The US-ASCII coded character set
+   is defined by ANSI X3.4-1986 [USASCII].
+
+       OCTET          = <any 8-bit character>
+       CHAR           = <any US-ASCII character (octets 0 - 127)>
+       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
+       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
+       ALPHA          = UPALPHA | LOALPHA
+       DIGIT          = <any US-ASCII digit "0".."9">
+       CTL            = <any US-ASCII control character
+                        (octets 0 - 31) and DEL (127)>
+       CR             = <US-ASCII CR, carriage return (13)>
+       LF             = <US-ASCII LF, linefeed (10)>
+       SP             = <US-ASCII SP, space (32)>
+       HT             = <US-ASCII HT, horizontal-tab (9)>
+       <">            = <US-ASCII double-quote mark (34)>
+       TEXTCHAR       = <any OCTET except CTLs, but including HT>
+       CRLF           = CR LF
+
+   All linear white space, including folding, has the same semantics as
+   SP.  A recipient MAY replace any linear white space with a single SP
+   before interpreting the field value or forwarding the message
+   downstream.
+
+       LWS            = [CRLF] 1*( SP | HT )
+
+   The TEXT rule is only used for descriptive field contents and values
+   that are not intended to be interpreted by the message parser. Words
+   of TEXT contains characters either from ISO-8859-1 [ISO-8859]
+   character set or UTF-8 [UTF-8].
+
+       TEXT           = <any *OCTET except CTLs,
+                        but including LWS>
+
+   A CRLF is allowed in the definition of TEXT only as part of a header
+   field continuation. It is expected that the folding LWS will be
+   replaced with a single SP before interpretation of the TEXT value.
+
+   Hexadecimal numeric characters are used in several protocol elements.
+
+       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
+                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
+
+   Many HTTP/1.1 header field values consist of words separated by LWS
+   or special characters. These special characters MUST be in a quoted
+
+
+
+Leach & Newman           Expires: December 2003                [Page 33]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   string to be used within a parameter value.
+
+       token          = 1*TOKENCHAR
+       separators     = "(" | ")" | "<" | ">" | "@"
+                      | "," | ";" | ":" | "\" | <">
+                      | "/" | "[" | "]" | "?" | "="
+                      | "{" | "}" | SP | HT
+       TOKENCHAR      = <any CHAR except CTLs or separators>
+
+   A string of text is parsed as a single word if it is quoted using
+   double-quote marks.
+
+       quoted-string  = ( <"> qdstr-val <"> )
+       qdstr-val      = *( qdtext | quoted-pair )
+       qdtext         = <any TEXTCHAR except <"> and "\">
+
+   Note that LWS is NOT implicit between the double-quote marks (<">)
+   surrounding a qdstr-val and the qdstr-val; any LWS will be considered
+   part of the qdstr-val.  This is also the case for quotation marks
+   surrounding any other construct.
+
+   The backslash character ("\") MAY be used as a single-character
+   quoting mechanism only within qdstr-val and comment constructs.
+
+       quoted-pair    = "\" CHAR
+
+   The value of this construct is CHAR. Note that an effect of this rule
+   is that backslash itself MUST be quoted.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 34]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+8  Sample Code
+
+   The sample implementation in [Digest] also applies to DIGEST-MD5.
+
+   The following code implements the conversion from UTF-8 to 8859-1 if
+   necessary.
+
+    /* if the string is entirely in the 8859-1 subset of UTF-8, then
+     * translate to 8859-1 prior to MD5
+     */
+    void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base,
+        int len)
+    {
+        const unsigned char *scan, *end;
+        unsigned char cbuf;
+
+        end = base + len;
+        for (scan = base; scan < end; ++scan) {
+            if (*scan > 0xC3) break; /* abort if outside 8859-1 */
+            if (*scan >= 0xC0 && *scan <= 0xC3) {
+                if (++scan == end || *scan < 0x80 || *scan > 0xBF)
+                    break;
+            }
+        }
+        /* if we found a character outside 8859-1, don't alter string
+         */
+        if (scan < end) {
+            MD5Update(ctx, base, len);
+            return;
+        }
+
+        /* convert to 8859-1 prior to applying hash
+         */
+        do {
+            for (scan = base; scan < end && *scan < 0xC0; ++scan)
+                ;
+            if (scan != base) MD5Update(ctx, base, scan - base);
+            if (scan + 1 >= end) break;
+            cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
+            MD5Update(ctx, &cbuf, 1);
+            base = scan + 2;
+        } while (base < end);
+    }
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 35]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+9   Interoperability considerations
+
+   9.1 Implementing DES cipher in CBC mode
+
+   Several cryptographic libraries (Ebones, OpenSSL) provide a convenience
+   function des_cbc_encrypt for implementing DES cipher in CBC mode.
+   There is a documented bug in this function: the function doesn't update
+   IV before returning. If an implementation uses this function to implement
+   DES cipher in CBC mode, it MUST update IV by copying the last 8 bytes of
+   the des_cbc_encrypt's output to the IV buffer.
+   Note that the function des_ede2_cbc_encrypt that may be used to implement
+   3DES (in "two keys mode") in CBC mode works as expected.
+
+   Care must be taken when configuring the DES keys for most DES
+   libraries. This specification gives 56 bits for the DES key (or 112
+   bits for the 3DES key); libraries generally expect the key to be given
+   in a 64 bit (128 bit for 3DES) form.
+
+   The following C function can be used to convert a 56 bit DES key into a
+   form acceptable for the libraries. The low order bit in each byte
+   would contain parity information and will be corrected by the library.
+
+   /* slide the first 7 bytes of 'inbuf' into the high seven bits of the
+      first 8 bytes of 'keybuf'. 'keybuf' better be 8 bytes long or longer. */
+   void slidebits(unsigned char *keybuf, unsigned char *inbuf)
+   {
+       keybuf[0] = inbuf[0];
+       keybuf[1] = (inbuf[0]<<7) | (inbuf[1]>>1);
+       keybuf[2] = (inbuf[1]<<6) | (inbuf[2]>>2);
+       keybuf[3] = (inbuf[2]<<5) | (inbuf[3]>>3);
+       keybuf[4] = (inbuf[3]<<4) | (inbuf[4]>>4);
+       keybuf[5] = (inbuf[4]<<3) | (inbuf[5]>>5);
+       keybuf[6] = (inbuf[5]<<2) | (inbuf[6]>>6);
+       keybuf[7] = (inbuf[6]<<1);
+   }
+
+10  Acknowledgements
+
+   The following people had substantial contributions to the development
+   and/or refinement of this document:
+
+   Lawrence Greenfield John Gardiner Myers Simon Josefsson RL Bob Morgan
+   Jeff Hodges Claus Assmann Tony Hansen Sam Hartman
+
+   as well as other members of the SASL mailing list.
+
+   The text used is section 3.8 was taken from [TLS-CBC] by Bodo
+   Moeller.
+
+
+
+Leach & Newman           Expires: December 2003                [Page 36]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+11  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 37]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+Appendix A: Changes from 2831
+
+   1). Fixed various typos in formulas.
+
+   2). Dropped DES as mandatory to implement cipher (3DES is mandatory
+   to implement).
+
+   3). Tighten ABNF. Fixed some bugs.
+
+   4). Clarified nc-value verification and which side is aborting
+   exchange.
+
+   5). Added text saying that for interoperability
+   username/password/realm MUST be prepared using the "SASLPrep" profile
+   [SASLPrep] of the "stringprep" algorithm [StringPrep].
+
+   6). Clarified that unquoted version of the username, etc. used in A1
+   calculation.
+
+   7). Various cleanup to References section. Split all references to
+   Normative and Informative.
+
+   8). Added minimal and maximal limits on maxbuf. Clarified how to
+   calculate max sender size.
+
+   9). Change ABNF for host to allow for IPv6 addresses. ABNF now
+   references RFC 2373 and RFC 2396.
+
+   10). Added DES cipher interoperability section.
+
+   11). Added man-in-the-middle considerations for ciphers.
+
+   12). Clarified how sequence counters are modified.
+
+   13). Addition warnings about preventing reply/redirection attacks.
+
+   14). Specified that "charset" directive affects "realm" and doesn't
+   affect
+        "authzid".
+
+   15). Removed text that described that "authzid" is in Unicode in
+   Normalization
+        Form KC, encoded as UTF-8.
+
+   16). Clarified that rc4 state is not reset between two sent/received
+   buffers
+        of encoded data.
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 38]
+
+
+
+
+
+INTERNET DRAFT            Digest SASL Mechanism                June 2003
+
+
+   17). Clarified that for DES/3DES the IV for the next buffer of
+   encoded data is
+        the last 8 bytes of the ciphertext.
+
+   18). Clarified how "maximal sender size" is calculated.
+
+   19). Prohibit an empty authzid.
+
+   20). Added AES cipher defined in "AES Ciphersuite for DIGEST-MD5 SASL
+   mechanism"
+        document (expired draft-ietf-sasl-digest-aes-00.txt).
+
+   21). Minor text clarifications.
+
+Appendix B: Open Issues/ToDo List
+
+   1). The latest revision prohibits escaped characters in nonce/cnonce.
+   This is different
+       from HTTP Digest. Any objections?
+
+   2). Do we need/want a new stringprep profile for "realm"?
+
+   3). What to do about CBC mode attack that affects TLS document and
+   DIGEST-MD5 as well?
+
+   One of the proposals is to drop DES/3DES ciphers and define a new one
+   (e.g. AES) in such a way that is not susceptible to this kind of
+   attack.
+
+   AES cipher has to be fixed to prevent this attack.
+
+   4). Add reference to CBC mode attack:
+
+   This problem is described in LASEC Memo "Password Interception in a
+   SSL/TLS Channel" by Brice Canvel, published 2003-02-20:
+   http://lasecwww.epfl.ch/memo_ssl.shtml
+
+   5). Normative vs. Informative references must be carefully rechecked.
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman           Expires: December 2003                [Page 39]
+
+
diff --git a/doc/draft-ietf-sasl-saslprep-xx.txt b/doc/draft-ietf-sasl-saslprep-xx.txt
new file mode 100644 (file)
index 0000000..fd0f6b8
--- /dev/null
@@ -0,0 +1,339 @@
+
+
+
+
+
+
+INTERNET-DRAFT                                   Kurt D. Zeilenga
+Intended Category: Standards Track            OpenLDAP Foundation
+Expires in six months                             27 October 2003
+
+
+        SASLprep: Stringprep profile for user names and passwords
+                    <draft-ietf-sasl-saslprep-04.txt>
+
+
+Status of Memo
+
+  This document is an Internet-Draft and is in full conformance with all
+  provisions of Section 10 of RFC 2026.
+
+  This document is intended to be, after appropriate review and
+  revision, submitted to the RFC Editor as a Standards Track document.
+  Distribution of this memo is unlimited.  Technical discussion of this
+  document will take place on the IETF SASL mailing list
+  <ietf-sasl@imc.org>.  Please send editorial comments directly to the
+  document editor <Kurt@OpenLDAP.org>.
+
+  Internet-Drafts are working documents of the Internet Engineering Task
+  Force (IETF), its areas, and its working groups.  Note that other
+  groups may also distribute working documents as Internet-Drafts.
+  Internet-Drafts are draft documents valid for a maximum of six months
+  and may be updated, replaced, or obsoleted by other documents at any
+  time.  It is inappropriate to use Internet-Drafts as reference
+  material or to cite them other than as ``work in progress.''
+
+  The list of current Internet-Drafts can be accessed at
+  <http://www.ietf.org/ietf/1id-abstracts.txt>. The list of
+  Internet-Draft Shadow Directories can be accessed at
+  <http://www.ietf.org/shadow.html>.
+
+  Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+  Please see the Full Copyright section near the end of this document
+  for more information.
+
+
+Abstract
+
+  This document describes how to prepare Unicode strings representing
+  user names and passwords for comparison.  The document defines the
+  "SASLprep" profile of the "stringprep" algorithm to be used for both
+  user names and passwords.  This profile is intended to be used by
+  Simple Authentication and Security Layer (SASL) mechanisms (such as
+  PLAIN, CRAM-MD5, and DIGEST-MD5) as well as other protocols exchanging
+
+
+
+Zeilenga                        SASLprep                        [Page 1]
+\f
+INTERNET-DRAFT       draft-ietf-sasl-saslprep-04.txt     27 October 2003
+
+
+  user names and/or passwords.
+
+
+1. Introduction
+
+  The use of simple user names and passwords in authentication and
+  authorization is pervasive on the Internet.  To increase the
+  likelihood that user name and password input and comparison work in
+  ways that make sense for typical users throughout the world, this
+  document defines rules for preparing internationalized user names and
+  passwords for comparison.  For simplicity and implementation ease, a
+  single algorithm is defined for both user names and passwords.
+
+  This document defines the "SASLprep" profile of the "stringprep"
+  algorithm [StringPrep].
+
+  The profile is designed for use in Simple Authentication and Security
+  Layer ([SASL]) mechanisms such as [PLAIN].  It may be applicable
+  elsewhere simple user names and passwords are used.  This profile is
+  not intended to be used for arbitrary text.  This profile is also not
+  intended to be used to prepare identity strings which are not simple
+  user names (e.g., e-mail addresses, domain names, distinguished
+  names).
+
+
+2. The SASLprep profile
+
+  This section defines the "SASLprep" profile.  This profile is intended
+  to be used to prepare strings representing simple user names and
+  passwords.
+
+  This profile uses Unicode 3.2, as defined in [StringPrep, A.1].
+
+  Character names in this document use the notation for code points and
+  names from the Unicode Standard [Unicode].  For example, the letter
+  "a" may be represented as either <U+0061> or <LATIN SMALL LETTER A>.
+  In the lists of mappings and the prohibited characters, the "U+" is
+  left off to make the lists easier to read.  The comments for character
+  ranges are shown in square brackets (such as "[CONTROL CHARACTERS]")
+  and do not come from the standard.
+
+  Note: a glossary of terms used in Unicode can be found in [Glossary].
+  Information on the Unicode character encoding model can be found in
+  [CharModel].
+
+
+2.1. Mapping
+
+
+
+
+Zeilenga                        SASLprep                        [Page 2]
+\f
+INTERNET-DRAFT       draft-ietf-sasl-saslprep-04.txt     27 October 2003
+
+
+  This profile specifies:
+    - non-ASCII space characters [StringPrep, C.1.2] be mapped to SPACE
+      (U+0020), and
+
+    - the "commonly mapped to nothing" characters [StringPrep, B.1] be
+      mapped to nothing.
+
+
+
+2.2. Normalization
+
+  This profile specifies using Unicode normalization form KC, as
+  described in Section 4 of [StringPrep].
+
+
+2.3. Prohibited Output
+
+  This profile specifies the following characters:
+
+    - Non-ASCII space characters [StringPrep, C.1.2],
+    - ASCII control characters [StringPrep, C.2.1],
+    - Non-ASCII control characters [StringPrep, C.2.2],
+    - Private Use [StringPrep, C.3],
+    - Non-character code points [StringPrep, C.4],
+    - Surrogate code points [StringPrep, C.5],
+    - Inappropriate for plain text [StringPrep, C.6],
+    - Inappropriate for canonical representation [StringPrep, C.7],
+    - Change display properties or are deprecated [StringPrep, C.8], and
+    - Tagging characters [StringPrep, C.9].
+
+  are prohibited output.
+
+
+2.4. Bidirectional characters
+
+  This profile specifies checking bidirectional strings as described in
+  [StringPrep, Section 6].
+
+
+2.5. Unassigned Code Points
+
+  This profile specifies [StringPrep, A.1] table as its list of
+  unassigned code points.
+
+
+3. Security Considerations
+
+  This profile is intended to used to prepare simple user names and
+
+
+
+Zeilenga                        SASLprep                        [Page 3]
+\f
+INTERNET-DRAFT       draft-ietf-sasl-saslprep-04.txt     27 October 2003
+
+
+  passwords for comparison.  It is not intended to be used for to
+  prepare identities which are not simple user names (e.g.,
+  distinguished names and domain names).  Nor is the profile intended to
+  be used for simple user names which require different handling.
+  Protocols (or applications of those protocols) which have
+  application-specific identity forms and/or comparison algorithms
+  should use mechanisms specifically designed for these forms and
+  algorithms.
+
+  User names and passwords should be protected from eavesdropping.
+
+  General "stringprep" and Unicode security considerations apply.  Both
+  are discussed in [StringPrep].
+
+
+4. IANA Considerations
+
+  This document details the "SASLprep" profile of [StringPrep] protocol.
+  Upon Standards Action the profile should be registered in the
+  stringprep profile registry.
+
+      Name of this profile: SASLprep
+      RFC in which the profile is defined: This RFC
+      Indicator whether or not this is the newest version of the
+      profile: This is the first version of the SASPprep profile.
+
+
+5. Acknowledgment
+
+  This document borrows text from "Preparation of Internationalized
+  Strings ('stringprep')" and "Nameprep: A Stringprep Profile for
+  Internationalized Domain Names", both by Paul Hoffman and Marc
+  Blanchet.
+
+  This document is a product of the IETF SASL WG.
+
+
+6. Normative References
+
+  [StringPrep]  Hoffman P. and M. Blanchet, "Preparation of
+                Internationalized Strings ('stringprep')",
+                draft-hoffman-rfc3454bis-xx.txt, a work in progress.
+
+  [SASL]        Melnikov, A. (Editor), "Simple Authentication and
+                Security Layer (SASL)",
+                draft-ietf-sasl-rfc2222bis-xx.txt, a work in progress.
+
+  [Unicode]     The Unicode Consortium, "The Unicode Standard, Version
+
+
+
+Zeilenga                        SASLprep                        [Page 4]
+\f
+INTERNET-DRAFT       draft-ietf-sasl-saslprep-04.txt     27 October 2003
+
+
+                3.2.0" is defined by "The Unicode Standard, Version 3.0"
+                (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5),
+                as amended by the "Unicode Standard Annex #27: Unicode
+                3.1" (http://www.unicode.org/reports/tr27/) and by the
+                "Unicode Standard Annex #28: Unicode 3.2"
+                (http://www.unicode.org/reports/tr28/).
+
+
+7. Informative References
+
+  [Glossary]    The Unicode Consortium, "Unicode Glossary",
+                <http://www.unicode.org/glossary/>.
+
+  [CharModel]   Whistler, K. and M. Davis, "Unicode Technical Report
+                #17, Character Encoding Model", UTR17,
+                <http://www.unicode.org/unicode/reports/tr17/>, August
+                2000.
+
+  [CRAM-MD5]    Nerenberg, L., "The CRAM-MD5 SASL Mechanism",
+                draft-ietf-sasl-crammd5-xx.txt, a work in progress.
+
+  [DIGEST-MD5]  Leach, P., C. Newman, and A. Melnikov, "Using Digest
+                Authentication as a SASL Mechanism",
+                draft-ietf-sasl-rfc2831bis-xx.txt, a work in progress.
+
+  [PLAIN]       Zeilenga, K. (Editor), "The Plain SASL Mechanism",
+                draft-ietf-sasl-plain-xx.txt, a work in progress.
+
+
+8. Editor's Address
+
+  Kurt Zeilenga
+  OpenLDAP Foundation
+
+  Email: kurt@OpenLDAP.org
+
+
+Intellectual Property Rights
+
+  The IETF takes no position regarding the validity or scope of any
+  intellectual property or other rights that might be claimed to pertain
+  to the implementation or use of the technology described in this
+  document or the extent to which any license under such rights might or
+  might not be available; neither does it represent that it has made any
+  effort to identify any such rights.  Information on the IETF's
+  procedures with respect to rights in standards-track and
+  standards-related documentation can be found in BCP-11.  Copies of
+  claims of rights made available for publication and any assurances of
+
+
+
+Zeilenga                        SASLprep                        [Page 5]
+\f
+INTERNET-DRAFT       draft-ietf-sasl-saslprep-04.txt     27 October 2003
+
+
+  licenses to be made available, or the result of an attempt made to
+  obtain a general license or permission for the use of such proprietary
+  rights by implementors or users of this specification can be obtained
+  from the IETF Secretariat.
+
+  The IETF invites any interested party to bring to its attention any
+  copyrights, patents or patent applications, or other proprietary
+  rights which may cover technology that may be required to practice
+  this standard.  Please address the information to the IETF Executive
+  Director.
+
+
+Full Copyright
+
+  Copyright (C) The Internet Society (2003). All Rights Reserved.
+
+  This document and translations of it may be copied and furnished to
+  others, and derivative works that comment on or otherwise explain it
+  or assist in its implmentation may be prepared, copied, published and
+  distributed, in whole or in part, without restriction of any kind,
+  provided that the above copyright notice and this paragraph are
+  included on all such copies and derivative works.  However, this
+  document itself may not be modified in any way, such as by removing
+  the copyright notice or references to the Internet Society or other
+  Internet organizations, except as needed for the  purpose of
+  developing Internet standards in which case the procedures for
+  copyrights defined in the Internet Standards process must be followed,
+  or as required to translate it into languages other than English.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zeilenga                        SASLprep                        [Page 6]
+\f
diff --git a/doc/draft-murchison-sasl-login-xx.txt b/doc/draft-murchison-sasl-login-xx.txt
new file mode 100644 (file)
index 0000000..e6ffc29
--- /dev/null
@@ -0,0 +1,396 @@
+
+
+
+
+
+
+
+Internet Draft                                               K. Murchison
+Category: Informational                                        M. Crispin
+Expires: March 2, 2004                                     28 August 2003
+
+
+                          The LOGIN SASL Mechanism
+
+                     <draft-murchison-sasl-login-00.txt>
+
+
+Status of this Memo
+
+    This document is an Internet-Draft and is subject to all provisions
+    of Section 10 of RFC2026.
+
+    Internet-Drafts are working documents of the Internet Engineering
+    Task Force (IETF), its areas, and its working groups.  Note that
+    other groups may also distribute working documents as
+    Internet-Drafts.
+
+    Internet-Drafts are draft documents valid for a maximum of six months
+    and may be updated, replaced, or obsoleted by other documents at any
+    time.  It is inappropriate to use Internet-Drafts as reference
+    material or to cite them other than as "work in progress."
+
+    The list of current Internet-Drafts can be accessed at
+    http://www.ietf.org/1id-abstracts.html
+
+    The list of Internet-Draft Shadow Directories can be accessed at
+    http://www.ietf.org/shadow.html
+
+
+Copyright Notice
+
+    Copyright (C) The Internet Society 2003. All Rights Reserved.
+
+
+Abstract
+
+    This document documents the obsolete clear-text user/password Simple
+    Authentication and Security Layer (SASL) mechanism called the LOGIN
+    mechanism.  The LOGIN mechanism was intended to be used, in
+    combination with data confidentiality services provided by a lower
+    layer, in protocols which lack a simple password authentication
+    command.
+
+
+
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 1]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+
+Conventions Used in the Document
+
+    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+    "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+    document are to be interpreted as described in [KEYWORDS].
+
+
+1.  Background and Intended Usage
+
+    This document documents the obsolete LOGIN Simple Authentication and
+    Security Layer ([SASL]) mechanism which was in use in protocols with
+    no clear-text login command (e.g., [SMTP-AUTH]).
+
+    Note: The LOGIN SASL mechanism is obsoleted in favor of the PLAIN
+    SASL mechanism ([PLAIN]).  The LOGIN mechanism is documented here
+    only for the purpose of backwards compatibility with legacy software.
+    Clients SHOULD implement the PLAIN SASL mechanism and use it whenever
+    offered by a server.  The LOGIN SASL mechanism SHOULD NOT be used by
+    a client when other plaintext mechanisms are offered by a server.
+
+    The name associated with this mechanism is "LOGIN".
+
+    The LOGIN SASL mechanism does not provide a security layer.  This
+    mechanism MUST NOT be used without adequate security protection as
+    the mechanism affords no integrity nor confidentiality protection
+    itself.  The LOGIN SASL mechanism MUST NOT be advertised or used in
+    any configuration that prohibits the PLAIN mechanism or plaintext
+    LOGIN (or USER/PASS) command that sends passwords in the clear.
+
+
+2.  LOGIN SASL Mechanism
+
+    The authorization identity is the same string as the "username" in
+    the traditional (non-SASL) LOGIN or USER commands; the authorization
+    authenticator is the same string as the traditional "password".  The
+    authentication identity is the same as the authorization identity in
+    this mechanism.
+
+    Only US-ASCII printable characters SHOULD be used in the username and
+    password to permit maximal interoperability.  If non-US-ASCII
+    characters are used in a username, they MUST use UTF-8.  Passwords
+    MAY contain arbitrary binary data excluding NUL, CR and LF
+    characters.  However, if a password is supplied to the client as a
+    sequence of characters (e.g., a password dialog box), those
+    characters MUST be encoded as UTF-8.
+
+    The username MUST be less than 64 characters in length.
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 2]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+2.1.  Client side of authentication protocol exchange
+
+    The client expects the server to issue a challenge.  The client then
+    responds with the authorization identity.  The client then expects
+    the server to issue a second challenge.  The client then responds
+    with the authorization authenticator.  The contents of both
+    challenges SHOULD be ignored.
+
+
+2.2.  Server side of authentication protocol exchange
+
+    The server issues the string "User Name" in challenge, and receives a
+    client response.  This response is recorded as the authorization
+    identity.  The server then issues the string "Password" in challenge,
+    and receives a client response.  This response is recorded as the
+    authorization authenticator.  The server must verify that the
+    authorization authenticator permits login as the authorization
+    identity.
+
+    Note: There is at least one widely deployed client which requires
+    that the challenge strings transmitted by the server be "Username:"
+    and "Password:" respectively.  For this reason, server
+    implementations MAY send these challenge strings instead of those
+    listed above.
+
+
+2.3.  Example
+
+    This example shows the use of the LOGIN mechanism with the SMTP AUTH
+    command [SMTP-AUTH] under the protection of SMTP STARTTLS [SMTP-TLS].
+    The user name is "tim" and the password is "tanstaaftanstaaf".  The
+    base64 encoding of the challenges and responses is part of the SMTP
+    AUTH command, not part of the LOGIN specification itself.  "C:" and
+    "S:" indicate lines sent by the client and server respectively.
+
+    S: 220 smtp.example.com ESMTP server ready
+    C: EHLO test.example.com
+    S: 250-smtp.example.com
+    S: 250-STARTTLS
+    S: 250 AUTH CRAM-MD5
+    C: STARTTLS
+    S: 220 Ready to start TLS
+    <TLS negotiation, further commands are under TLS layer>
+    C: EHLO test.example.com
+    S: 250-smtp.example.com
+    S: 250 AUTH LOGIN CRAM-MD5
+    C: AUTH LOGIN
+    S: 334 VXNlciBOYW1lAA==
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 3]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+    C: dGlt
+    S: 334 UGFzc3dvcmQA
+    C: dGFuc3RhYWZ0YW5zdGFhZg==
+    S: 235 Authentication successful.
+
+
+3.
+    Security Considerations
+
+    The LOGIN mechanism relies upon an underlying encryption layer or
+    other secure channel for security.  When used without an encryption
+    layer or secure channel, it is vulnerable to a common network
+    eavesdropping attack.  Therefore the LOGIN mechanism MUST NOT be
+    advertised or used in any configuration that prohibits the PLAIN
+    mechanism or a plaintext LOGIN (or USER/PASS) command that sends
+    passwords in the clear.
+
+
+4.
+    IANA Considerations
+
+    The registration for the LOGIN SASL mechanism follows:
+
+    SASL mechanism name: LOGIN
+    Security Considerations: See section 3 of this memo
+    Published specification: this memo
+    Person & email address to contact for futher information:
+        See section 7 of this memo
+    Intended usage: OBSOLETE
+    Owner/Change controller: See section 7 of this memo
+
+
+5.
+    References
+
+
+5.1.
+    Normative References
+
+
+     [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+         Requirement Levels", Harvard University, RFC 2119, March 1997.
+
+
+     [SASL] Melnikov, A., Ed., "Simple Authentication and Security Layer
+         (SASL)", Isode, draft-ietf-sasl-rfc2222bis-xx.txt, Work In
+         Progress.
+
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 4]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+5.2.  Informative References
+
+
+     [PLAIN] Zeilenga, Kurt D., Ed., "The Plain SASL Mechanism",
+         OpenLDAP Foundation, draft-ietf-sasl-plain-xx.txt, Work In
+         Progress.
+
+
+     [SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication",
+         Netscape Communications, RFC 2554, March 1999.
+
+
+     [SMTP-TLS] Hoffman, P., "SMTP Service Extension for Secure SMTP
+         over Transport Layer Security", Internet Mail Consortium, RFC
+         3207, February 2002.
+
+
+
+6.  Acknowledgments
+
+    Thanks to Rob Siemborski for his input and feedback on this document.
+
+
+7.
+    Author's Address
+
+    Kenneth Murchison
+    Oceana Matrix Ltd.
+    21 Princeton Place
+    Orchard Park, NY  14127
+
+    Phone: (716) 662-8973
+
+    EMail: ken@oceana.com
+
+
+
+
+    Mark R. Crispin
+    Networks and Distributed Computing
+    University of Washington
+    4545 15th Avenue NE
+    Seattle, WA  98105-4527
+
+    Phone: (206) 543-5762
+
+    EMail: MRC@CAC.Washington.EDU
+
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 5]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+8.
+    Intellectual Property Considerations
+
+    The IETF takes no position regarding the validity or scope of any
+    intellectual property or other rights that might be claimed to
+    pertain to the implementation or use of the technology described in
+    this document or the extent to which any license under such rights
+    might or might not be available; neither does it represent that it has
+    made any effort to identify any such rights.  Information on the
+    IETF's procedures with respect to rights in standards-track and
+    standards-related documentation can be found in BCP-11.  Copies of
+    claims of rights made available for publication and any assurances of
+    licenses to be made available, or the result of an attempt made to
+    obtain a general license or permission for the use of such proprietary
+    rights by implementors or users of this specification can be obtained
+    from the IETF Secretariat.
+
+    The IETF invites any interested party to bring to its attention any
+    copyrights, patents or patent applications, or other proprietary
+    rights which may cover technology that may be required to practice
+    this standard.  Please address the information to the IETF Executive
+    Director.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 6]
+\f
+Internet Draft            LOGIN SASL Mechanism           August 28, 2004
+
+
+9.
+    Full Copyright Statement
+
+    Copyright (C) The Internet Society 2003. All Rights Reserved.
+
+    This document and translations of it may be copied and furnished to
+    others, and derivative works that comment on or otherwise explain it
+    or assist in its implmentation may be prepared, copied, published and
+    distributed, in whole or in part, without restriction of any kind,
+    provided that the above copyright notice and this paragraph are
+    included on all such copies and derivative works.  However, this
+    document itself may not be modified in any way, such as by removing
+    the copyright notice or references to the Internet Society or other
+    Internet organizations, except as needed for the  purpose of
+    developing Internet standards in which case the procedures for
+    copyrights defined in the Internet Standards process must be followed,
+    or as required to translate it into languages other than English.
+
+    The limited permissions granted above are perpetual and will not be
+    revoked by the Internet Society or its successors or assigns.
+
+    This document and the information contained herein is provided on an
+    "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET
+    ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+    INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+    INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+    WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires: March 2, 2004        Murchison                         [Page 7]
+\f
diff --git a/doc/draft-newman-sasl-c-api-xx.txt b/doc/draft-newman-sasl-c-api-xx.txt
new file mode 100644 (file)
index 0000000..1ad37dd
--- /dev/null
@@ -0,0 +1,1681 @@
+
+
+
+
+
+
+Network Working Group                                          C. Newman
+Internet Draft: SASL C API                                      Innosoft
+Document: draft-newman-sasl-c-api-01.txt                     A. Melnikov
+                                                         MessagingDirect
+                                                           February 2003
+                                                   Expires in six months
+
+
+             Simple Authentication and Security Layer C API
+
+
+Status of this memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026 [RFC2026].
+
+   Internet-Drafts are working documents of the Internet Engineering
+   Task Force (IETF), its areas, and its working groups. Note that other
+   groups may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six months
+   and may be updated, replaced, or obsoleted by other documents at any
+   time.  It is inappropriate to use Internet-Drafts as reference
+   material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+Abstract
+
+   Almost every protocol needs authentication.  However, there does not
+   exist an authentication mechanism suitable for all organizations, nor
+   is it likely that a small fixed set of authentication mechanisms will
+   remain suitable.  SASL [SASL] provides the on-the-wire framework for
+   authentication (and a security layer) which separates the design of
+   authentication mechanisms from the protocols in which they're used.
+
+   The SASL protocol model suggests a software architecture where
+   application protocols call a generic API to authenticate which in
+   turn calls a generic plug-in interface for extensible authentication
+   modules.  This memo documents the API used in one implementation of
+   this architecture in the hope that it will be useful to others.  An
+   associated memo documenting the plug-in interface is forthcoming.
+
+1.     Conventions Used in this Memo
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 1]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [KEYWORDS].
+
+   This assumes familiarity the SASL [SASL] specification.
+
+ 1.1.   Concepts
+
+   The following concepts are necessary to understand this
+   specification.
+
+realm
+     A realm is a name (usually a domain-style name) associated with a
+     set of users on a server.  One realm may span multiple servers.
+     Alternatively, a single server may have multiple realms.  Thus
+     there may be multiple users with the username "chris" on the same
+     server, each in a different realm.  Some authentication mechanisms
+     have a special field for the realm (e.g., DIGEST-MD5).  For other
+     mechanisms, a realm can be specified by the client by using the
+     syntax "username@realm" in the username field.
+
+service
+     A service is a basic function provided by one or more protocols.
+     The GSSAPI service name [GSSAPI] registry is available at:
+
+      <http://www.iana.org/numbers.html#G>
+
+     This registry is used by SASL and the SASL API. The service name
+     may be used for service-specific passwords for advanced users, or
+     advanced authentication mechanisms may restrict the services a
+     given server may offer.
+
+
+virtual domain
+     When a single server has multiple realms and there is a DNS server
+     entry for each realm pointing to the same server IP address, then
+     those realms are "virtual domains".  Virtual domains are extremely
+     popular with web hosting services and are becoming more popular
+     with POP mail services.  The key to providing virtual domain sup-
+     port is that the client informs the server of the domain it
+     believes it is speaking to either through a special protocol ele-
+     ment or by using a username of the form "user@realm".
+
+
+2.     Overview of the SASL C API
+
+   The SASL API is initialized once at process startup. The
+   sasl_server_init() and sasl_client_init() functions provide basic
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 2]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+   initialization.
+
+   When a network connection occurs where SASL will be used, a connec-
+   tion-specific context is created for authentication with
+   sasl_client_new() or sasl_server_new().  The API implementation must
+   support multi-threaded servers and clients by creating the connection
+   context in a thread-safe fashion permitting multiple contexts in a
+   given process.  At this point, the caller may adjust security policy
+   for the context, and the set of mechanisms which are enabled is
+   determined by requirements from the configuration or by the caller.
+
+   The server end of the API may request a list of enabled authentica-
+   tion mechanisms either in general or for a specific user.  The client
+   may either select a single mechanism or request a list from the
+   server (if the SASL profile for the protocol in question supports
+   that) and pass the list to the API for automated mechanism selection
+   by configured policy.
+
+   The SASL exchange begins with sasl_client_start() which determines if
+   one of the desired mechanisms is available on the client and may gen-
+   erate an initial client response.  The client then sends the appro-
+   priate protocol message to initiate the SASL exchange that the server
+   passes to sasl_server_start().
+
+   The SASL exchange continues with calls to sasl_client_step() and
+   sasl_server_step(), until the server indicates completion or the
+   client cancels the exchange.
+
+   The server queries the user name and user realm resulting from the
+   exchange with the sasl_getprop() routine.
+
+   A connection context is released with sasl_dispose() and process ter-
+   mination is indicated with sasl_done().
+
+   There are a number of utility functions and customization functions
+   available in the API for additional services.
+
+   Note, that all functions described in this documen can be implemented
+   as macroses, so an application using this API MUST NOT assume that
+   they are functions.
+
+   An application or library trying to use SASL API described in this
+   document must include "sasl.h" include file.
+
+3.     Basic SASL API Routines
+
+   This section describes the types and functions likely to be used by
+   every caller of the SASL API.
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 3]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+ 3.1.   Basic SASL API Data Structures
+
+   The following datastructures are basic to the SASL API.
+
+  3.1.1. sasl_callback_t
+
+   The sasl_callback_t structure is used for the caller of the SASL API
+   to provide services to both the core SASL API and SASL plug-ins via
+   callbacks.  The most important callback is the "getopt" callback (see
+   section 3.3.3) which is used to retrieve security policy option set-
+   tings from the caller's preferences.
+
+   typedef struct sasl_callback {
+       unsigned long id;
+       int (*proc)();
+       void *context;
+   } sasl_callback_t;
+
+   id is the label for the callback (XXX IANA registry needed), proc is
+   a function pointer whose exact type is determined by the id, and con-
+   text is a context variable which will be passed to the callback (usu-
+   ally as the first argument).  The last callback in the list of call-
+   backs is indicated with an id of SASL_CB_LIST_END.
+
+   If proc is NULL, this means that the application doesn't want to
+   specify a corresponding callback, but would provide the necessary
+   data via interaction.  See also section 3.1.4.
+
+  3.1.2. sasl_secret_t
+
+   The sasl_secret_t structure is used to hold text or binary passwords
+   for the client API.
+
+   typedef struct sasl_secret {
+       unsigned long len;
+       unsigned char data[1];
+   } sasl_secret_t;
+
+   The len field holds the length of the password, while the data field
+   holds the actual data.  The structure is variable sized: enough space
+   must be reserved after the data field to hold the desired password.
+   An additional that binary passwords are permitted to contain '\0'
+   characters.
+
+  3.1.3. sasl_conn_t
+
+   The sasl_conn_t data type is an opaque data type which reflects the
+   SASL context for a single server connection.  Only one SASL API call
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 4]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+   using a given sasl_conn_t as an argument may be active at a time.
+   However, each sasl_conn_t is independent and thus the SASL API may be
+   used in a true multi-processor multi-threaded environment.
+
+  3.1.4. sasl_interact_t
+
+   The sasl_interact_t structure is used by sasl_client_start and
+   sasl_client_step to request certain information from the application,
+   when the application did not provide corresponding callbacks. For
+   example, an application may choose to present a single dialog to the
+   user in order to collect all required information interactively.
+
+   typedef struct sasl_interact {
+       unsigned long id;
+       const char *challenge;
+       const char *prompt;
+       const char *defresult;
+       const void *result;
+       unsigned len;
+   } sasl_interact_t;
+
+   The id field holds the value of the callback ID. The prompt field
+   contains a string that should be presented to the user. If non-NULL,
+   challenge is a NUL-terminated string that will allow the user to pre-
+   sent a specific credential when prompted. This is different from the
+   prompt in that the prompt is more like a label for a text box (for
+   example "Response:" while challenge is a string that tells the user
+   what specifically is required by the response (for example, an OTP
+   challenge string). The defresult field contains a default value, if
+   any. Upon return from sasl_client_* the "result" field points to the
+   defresult. The client must present the information in the challenge
+   and the prompt to the user and store the result and its length in the
+   result and the len fields respectively.
+
+   For example, SASL_CB_PASS interaction may contain the following
+   information:
+    id - SASL_CB_PASS
+    challenge - NULL
+    prompt - "Password:"
+    defresult - NULL (no default).
+
+ 3.2.   Basic SASL API Client Routines
+
+   This section discusses the functions likely to be used by every
+   client caller of the SASL API.
+
+  3.2.1. sasl_client_init function
+
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 5]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_callback_t *callbacks
+
+Results:
+            SASL_OK        -- Success
+            SASL_NOMEM     -- Not enough memory
+            SASL_BADVERS   -- Mechanism version mismatch
+            SASL_BADPARAM  -- Error in config file
+
+      This function initializes the client routines for the SASL API.
+
+      The callbacks argument is the default list of callbacks (see sec-
+      tion 3.1.1 for definition of sasl_callback_t structure) and SHOULD
+      include the sasl_getopt_t callback (see section 3.3.3). The call-
+      backs may be NULL.  On success, SASL_OK is returned, and on fail-
+      ure a SASL C API error code such as the ones listed above is
+      returned.  This function may be called a second time to change the
+      default callbacks used for new connections, but the first call
+      must be made in a single-threaded environment.  The data refer-
+      enced by the sasl_callback_t structure must persist until
+      sasl_done() is called.
+
+  3.2.2. sasl_client_new function
+
+Arguments:
+            const char *service,
+            const char *server_name,
+            const char *iplocalport,
+            const char *ipremoteport,
+            const sasl_callback_t *prompt_supp,
+            unsigned int flags,
+            sasl_conn_t **pconn
+
+Results:
+            SASL_OK        -- Success
+            SASL_NOTINIT   -- SASL API not initialized
+            SASL_NOMECH    -- No mechanisms available
+            SASL_NOMEM     -- Not enough memory
+
+      This function creates a client connection context variable.  As
+      long as each thread uses its own connection context, the SASL C
+      API is thread-safe.
+
+      The service argument is an IANA registered GSSAPI service element
+      as defined in section 1.1.  It MUST NOT be NULL.
+
+      The server_name is the host name or IP address of the server to
+      which the client is connecting. NULL may be used for server_name,
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 6]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      but may result in advanced mechanisms such as Kerberos being
+      unavailable.
+
+      The iplocalport is the string with the client IPv4/IPv6 address,
+      followed by ":" and than by port number. An IPv6 address must be
+      enclosed in "[" and "]". NULL may be used for iplocalport, but may
+      result in mechanisms requiring IP address being unavailable.
+
+      The ipremoteport is the string with the server IPv4/IPv6 address,
+      followed by ":" and than by port number. An IPv6 address must be
+      enclosed in "[" and "]". NULL may be used for ipremoteport, but
+      may result in mechanisms requiring IP address being unavailable.
+
+      User input to the SASL C API may be provided in two ways: either
+      by supplying callbacks (prompt_supp) to this function, or by using
+      an interaction model with the sasl_client_start/sasl_client_step
+      functions. Callbacks are more convenient to obtain information
+      programmatically, such as pulling authentication information
+      directly from a configuration file. Interactions are more conve-
+      nient if one wants to get all the data in parallel, for example by
+      displaying a single dialog box instead of a separate popup for
+      authentication name, authorization, password, etc.
+
+      The prompt_supp is a list of supported user prompting callbacks
+      discussed in the section 3.1.1. The prompt_supp argument MAY be
+      NULL, which means that interactions (i.e. prompt_need parameter to
+      sasl_client_start (see 3.2.3) and sasl_client_step (see 3.2.4))
+      are used instead of callbacks. If prompt_supp is NULL, the
+      prompt_need argument to sasl_client_start (see 3.2.3) and
+      sasl_client_step (see 3.2.4) MUST NOT be NULL.
+
+      The flags argument represents client-supported security flags.
+      The only values currently supported are SASL_SECURITY_LAYER to
+      indicate the client supports the SASL security layer, or 0 to
+      indicate it doesn't.
+
+      The pconn argument is set to point to the newly created connection
+      context.  The sasl_conn_t type is opaque to the calling applica-
+      tion.
+
+  3.2.3. sasl_client_start function
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 7]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *mechlist,
+            sasl_interact_t **prompt_need,
+            const char **clientout,
+            unsigned int *clientoutlen,
+            const char **mech
+
+Results:
+            SASL_NOTINIT   -- SASL API not initialized
+            SASL_BADPARAM  -- conn or mechlist is NULL
+            SASL_NOMECH    -- No matching mechanisms available
+            SASL_NOMEM     -- Not enough memory
+            SASL_INTERACT  -- User interaction needed to continue
+                              (see prompt_need description below)
+            SASL_OK        -- Success
+
+      This selects an authentication mechanism to use and optionally
+      generates an initial client response.
+
+      The conn argument is the connection context from sasl_client_new.
+
+      The mechlist argument is a '\0' terminated string containing one
+      or more SASL mechanism names.  All characters in the string that
+      are not permitted in a SASL mechanism name [SASL] are ignored
+      except for the purposes of delimiting mechanism names (this per-
+      mits passing direct results from many protocol capability lists
+      unparsed).  Unknown mechanism names are ignored (although
+      SASL_NOMECH is returned if no known mechanisms are found).  Mecha-
+      nisms are tried in an implementation-dependent order. Implementa-
+      tions SHOULD try to use the most secure mechanism possible, within
+      the constraints specified by the application (e.g. SSF value).
+
+      For applications which support interactions, the prompt_need argu-
+      ment should initially point to a NULL pointer. If the selected
+      mechanism needs information from the user (for example, username
+      or password), then prompt_need will be set to point to an array of
+      sasl_interact_t structures (terminated by an entry with id equal
+      to SASL_CB_LIST_END), and sasl_client_start will return
+      SASL_INTERACT.  After that the client must fill in the requested
+      information and call this function again with the same parameters.
+
+      Applications that do not support interactions MUST pass NULL for
+      prompt_need.
+
+      The clientout and clientoutlen parameters are set to the initial
+      client response, if any.  If a protocol's SASL profile uses base64
+      encoding, this represents the data prior to the encoding (see
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 8]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      sasl_encode64).  If a protocol's SASL profile doesn't include an
+      optional initial client response, then these may be NULL and 0
+      respectively. The memory used by clientout is interally managed by
+      the SASL API and may be overwritten on the next call to
+      sasl_client_step or a call to sasl_dispose.
+
+      The mech argument is set to point to a '\0' terminated string
+      specifying the mechanism actually selected using all uppercase
+      letters.  It may be NULL if the client does not care which mecha-
+      nism was selected from mechlist.
+
+      If sasl_client_start is called a second time using the same con-
+      nection context, it will discard any cached information (e.g., the
+      username and password) and restart the exchange from the begin-
+      ning. <<???>>
+
+  3.2.4. sasl_client_step function
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *serverin,
+            unsigned int serverinlen,
+            sasl_interact_t **prompt_need,
+            const char **clientout,
+            unsigned int *clientoutlen
+
+Results:
+            SASL_NOTINIT     -- SASL API not initialized
+            SASL_NOMECH      -- sasl_client_start not called
+            SASL_BADPROT     -- server protocol incorrect/cancelled
+            SASL_BADSERV     -- server failed mutual auth
+            SASL_INTERACT    -- user interaction needed
+            SASL_OK          -- success
+
+      This routine performs one step in an authentication sequence.
+
+      The conn argument must be a connection context created by
+      sasl_client_new and used in a previous call to sasl_client_start.
+
+      The serverin and serverinlen parameters hold the SASL octet string
+      received from the server.  Note that for those SASL profiles which
+      base64 encode the exchange, this is the result after the removal
+      of the base64 encoding (see the sasl_decode64 routine below). The
+      serverin MUST have a terminating NUL character not counted by
+      serverinlen
+
+      The prompt_need argument is the same as for sasl_client_start.
+
+
+
+
+Newman et al.             Expires: August 2003          FORMFEED[Page 9]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      The clientout and clientoutlen parameters hold the SASL octet
+      string to encode (if necessary) and send to the server.
+
+ 3.3.   Basic SASL API Callback Routines
+
+      This section describes the basic callback functions needed for a
+      simple client implementation.  See the definition of sasl_call-
+      back_t in section 3.1.1 for a description of the basic callback
+      structure.
+
+  3.3.1. sasl_getsimple_t
+
+Arguments:
+            void *context,
+            int id,
+            const char **result,
+            unsigned *len
+
+Results:
+            SASL_OK          -- success
+            SASL_FAIL        -- error
+
+      This callback is used by the SASL API to request a simple constant
+      string from the application.  This is used with id SASL_CB_USER
+      for the username, SASL_CB_AUTHNAME for the authentication name (if
+      different), and SASL_CB_LANGUAGE for a comma separated list of RFC
+      1766 language tags.
+
+      The context is the context variable from the sasl_callback_t
+      structure, the id is the id from the sasl_callback_t structure,
+      and the callback is expected to set the result to a constant
+      string and the len to the length of that string.  The result and
+      len parameters are never NULL.
+
+  3.3.2. sasl_getsecret_t
+
+Arguments:
+            sasl_conn_t *conn,
+            void *context,
+            int id,
+            sasl_secret_t **psecret
+
+Results:
+            SASL_OK          -- success
+            SASL_FAIL        -- error
+
+      This callback is expected to create, prompt or locate a secret and
+      set it in the connection context with sasl_setprop.  The conn
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 10]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      argument is the connection context, the context and id parameters
+      are from the sasl_callback_t structure. The id SASL_CB_PASS is
+      used to request a clear text password.
+
+  3.3.3. sasl_getopt_t
+
+Arguments:
+            void *context,
+            const char *plugin_name,
+            const char *option,
+            const char **result,
+            unsigned int *len
+
+Results:
+            SASL_OK          -- success
+            SASL_FAIL        -- error
+
+      This callback is used by the SASL API to read options from the
+      application.  This allows a SASL configuration to be encapsulated
+      in the caller's configuration system. Configuration items may be
+      mechanism-specific and are arbitrary strings. If the application
+      does not provide a sasl_getopt_t callback, then the API MAY obtain
+      configuration information from other sources, for example from a
+      config file.
+
+      The context is the context variable from the sasl_callback_t
+      structure, the plugin_name is the name of plugin (or NULL), the
+      option is the option name, and the callback is expected to set the
+      result to a string valid till next call to sasl_getopt_t in the
+      same thread and the len to the length of that string.  The result
+      and len parameters are never NULL. If the name of plugin is NULL,
+      a general SASL option is requested, otherwise a plugin specific
+      version.
+
+ 3.4.   Basic SASL C API Utility Routines
+
+      This section describes utility functions provided as part of the
+      SASL API which may be used both by clients and servers.
+
+  3.4.1. sasl_decode64 function
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 11]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            const char *in,
+            unsigned int inlen,
+            char *out,
+            unsigned int outmax,
+            unsigned int *outlen
+
+Results:
+            SASL_BUFOVER    -- output buffer too small
+            SASL_BADPROT    -- invalid base64 string
+            SASL_OK         -- successful decode
+
+      This utility routine converts a base64 string of length inlen
+      pointed by in into an octet string. It is useful for SASL profiles
+      which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] pro-
+      files.  The output is copied to the buffer specified by the out
+      parameter.  It is NUL terminated and the length of the output is
+      placed in the outlen parameter if outlen is non-NULL. The lenght
+      doesn't include the terminating NUL character.
+
+      When the size of the output buffer, as specified by outmax, is too
+      small, the function returns SASL_BUFOVER error code and the
+      required length is stored in the outlen parameter if it is not
+      NULL.
+
+      The function may also return SASL_BADPROT error code when it
+      encounters an invalid base64 character.
+
+  3.4.2. sasl_encode64 function
+
+Arguments:
+            const char *in,
+            unsigned int inlen,
+            char *out,
+            unsigned int outmax,
+            unsigned int *outlen
+
+Results:
+            SASL_BUFOVER    -- output buffer too small
+            SASL_OK         -- successful decode
+
+      This utility routine converts an octet string of length inlen
+      pointed by in into a base64 string. It is useful for SASL profiles
+      which use base64 such as the IMAP [IMAP4] and POP [POP-AUTH] pro-
+      files.
+
+      The output is copied to the buffer specified by the out parameter.
+      It is NUL terminated and the length of the output is placed in the
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 12]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      outlen parameter if outlen is non-NULL. The lenght doesn't include
+      the terminating NUL character.
+
+      When the size of the output buffer, as specified by outmax, is too
+      small, the function returns SASL_BUFOVER error code and the
+      required length is stored in the outlen parameter if it is not
+      NULL.
+
+  3.4.3. sasl_errstring function
+
+Arguments:
+            int saslerr,
+            const char *langlist,
+            const char **outlang
+
+Results:
+            const char *
+
+      This converts a SASL error number into a constant string.  The
+      second argument MAY be NULL for the default language, or a comma-
+      separated list of RFC 1766 language tags.  The final parameter is
+      set to the RFC 1766 language tag of the string returned which will
+      be "i-default" if no matching language is found.  The strings are
+      UTF-8.  This requires no context so it may be used for the result
+      of an sasl_*_init or sasl_*_new result code.
+
+  3.4.4. sasl_errdetail function
+
+Arguments:
+            sasl_conn_t *conn
+
+Results:
+            const char *
+
+      This converts the last SASL error code that occured on a connec-
+      tion to UTF8 string. It uses the SASL_CB_LANGUAGE callback (see
+      section 3.3.1) to determine the language to use. It may return
+      more detailed information than sasl_errstring does.
+
+  3.4.5. sasl_seterror function
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 13]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn
+            unsigned flags,
+            const char *fmt,
+             ...
+
+Results:
+            none
+
+      This function sets sets the error string which will be returned by
+      sasl_errdetail.  It uses syslog()-style formatting (i.e. printf-
+      style with %m as the string form of an errno error).
+
+      Messages should be sensitive to the current language setting. If
+      there is no SASL_CB_LANGUAGE callback for the connection, text
+      MUST be in US-ASCII.  Otherwise UTF-8 is used and use of RFC 2482
+      for mixed-language text is encouraged.
+
+      <<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.>>
+
+      This function may be used by server callbacks.
+
+      If conn is NULL, the function does nothing.
+
+  3.4.6. sasl_erasebuffer function
+
+Arguments:
+            char *buf,
+            unsigned len
+
+Results:
+            none
+
+      This function fills the buffer buf of the lenght len with '\0'
+      characters.  The function may be used to clear from memory sensi-
+      tive informations, like passwords.
+
+ 3.5.   Basic SASL C API Server Routines
+
+      This section describes the basic routines for a server implementa-
+      tion of a SASL profile.
+
+  3.5.1. sasl_server_init function
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 14]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            const sasl_callback_t *callbacks,
+            const char *appname
+
+Results:
+            SASL_BADPARAM     -- error in config file
+            SASL_NOMEM        -- out of memory
+            SASL_BADVERS      -- Plug-in version mismatch
+            SASL_OK           -- success
+
+      This function initializes the server routines for the SASL C API.
+
+      The callbacks argument is the default list of callbacks (see sec-
+      tion 3.1.1 for definition of sasl_callback_t structure) and SHOULD
+      include the sasl_getopt_t callback (see section 3.3.3). The call-
+      backs may be NULL. The appname argument is the name of the calling
+      application and may be used by server plug-ins for logging.  On
+      success, SASL_OK is returned, and on failure a SASL C API error
+      code is returned.  This function may be called a second time to
+      change the default callbacks, but the first call must be made in a
+      single-threaded environment. The data referenced by the
+      sasl_callback_t structure must persist until sasl_done() is
+      called.
+
+      appname specifies the application name. SASL API may use it, for
+      example, for logging or to read an application specific configura-
+      tion. A library must pass NULL as appname.  appname can be also be
+      set with sasl_setprop function, and can be queried with sasl_get-
+      prop. <<Specify option name here>>
+
+  3.5.2. sasl_server_new function
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 15]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            const char *service,
+            const char *serverFQDN,
+            const char *user_realm,
+            const char *iplocalport,
+            const char *ipremoteport,
+            const sasl_callback_t *callbacks,
+            unsigned int flags,
+            sasl_conn_t **pconn
+
+Results:
+            SASL_OK        -- success
+            SASL_NOTINIT   -- SASL API not initialized
+            SASL_BADPARAM  -- Invalid parameter supplied
+            SASL_NOMECH    -- No mechanisms available
+            SASL_NOMEM     -- Not enough memory
+
+      This function creates a server connection context variable.  As
+      long as each thread uses its own connection context, the SASL C
+      API is thread-safe.
+
+      The service argument is an IANA registered GSSAPI service element
+      as defined in section 1.1. It MUST NOT be NULL.
+
+      The serverFQDN is the fully qualified name of the server. It MUST
+      NOT be NULL.
+
+      The user_realm specifies the default realm. A realm defines a set
+      of users on the system for systems which support multiple user
+      communities ("realms"). If user_realm is NULL, the value of
+      serverFQDN is used as the default realm.
+
+      The iplocalport is the string with the server IPv4/IPv6 address,
+      followed by ":" and than by port number. An IPv6 address must be
+      enclosed in "[" and "]". NULL may be used for iplocalport, but may
+      result in mechanisms requiring IP address being unavailable.
+
+      The ipremoteport is the string with the client IPv4/IPv6 address,
+      followed by ":" and than by port number. An IPv6 address must be
+      enclosed in "[" and "]". NULL may be used for ipremoteport, but
+      may result in mechanisms requiring IP address being unavailable.
+
+      The callbacks argument is a set of server callbacks which may
+      include a connection-specific sasl_getopt_t and/or an authoriza-
+      tion routine.
+
+      The flags argument represents server-supported security flags. The
+      only values currently supported are SASL_SECURITY_LAYER to
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 16]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      indicate the server supports the SASL security layer, or 0 to
+      indicate it doesn't.
+
+      The pconn argument is set to point to the newly created connection
+      context.
+
+  3.5.3. sasl_server_start function
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *mech,
+            const char *clientin,
+            insigned int clientinlen,
+            const char **serverout,
+            unsigned int *serveroutlen
+
+Results:
+            SASL_CONTINUE  -- Another authentication step required
+            SASL_OK        -- Authentication Complete
+            SASL_NOTINIT   -- SASL API not initialized
+            SASL_BADPARAM  -- Invalid parameter supplied
+            SASL_BADPROT   -- Client protocol error
+            SASL_NOMECH    -- Mechanism not supported
+            SASL_NOVERIFY  -- User exists, but no verifier exists for
+                              the mechanism
+            SASL_TRANS     -- A password transition is needed to use mechanism
+
+      This begins an authentication exchange and is called after the
+      client sends the initial authentication command.  The mech argu-
+      ment is the mechanism name the client is requesting.  If the
+      client includes an optional initial-response, it is passed in the
+      clientin and clientinlen fields.  Otherwise NULL and 0 are passed
+      for those arguments. The serverout and serveroutlen are filled in
+      with the server response, if any.  If SASL_CONTINUE is returned,
+      the server will need to wait for another client message and call
+      sasl_server_step.  If SASL_OK is returned, the authentication is
+      completed successfully, although server out data may be supplied.
+
+  3.5.4. sasl_server_step function
+
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 17]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *clientin,
+            insigned int clientinlen,
+            const char **serverout,
+            unsigned int *serveroutlen
+
+Results:
+            SASL_CONTINUE  -- Another authentication step required
+            SASL_OK        -- Authentication Complete
+            SASL_NOTINIT   -- SASL API not initialized
+            SASL_NOMECH    -- sasl_server_start not called
+            SASL_BADPARAM  -- Invalid parameter supplied
+            SASL_BADPROT   -- Client protocol error
+            SASL_NOVERIFY  -- User exists, but no verifier exists for
+                              the mechanism
+            SASL_TRANS     -- A password transition is needed to use mechanism
+
+      This routine performs one step in an authentication sequence.
+
+      The conn argument must be a connection context created by
+      sasl_server_new and used in a previous call to sasl_server_start.
+
+      The clientin and clientinlen parameters hold the SASL octet string
+      received from the client.  Note that for those SASL profiles which
+      base64 encode the exchange, this is the result after the removal
+      of the base64 encoding (see the sasl_decode64 routine). The cli-
+      entin MUST have a terminating NUL character not counted by
+      serverinlen.
+
+      The serverout and serveroutlen parameters hold the SASL octet
+      string to encode (if necessary) and send to the client. If
+      SASL_CONTINUE is returned, the server will need to wait for
+      another client message and call sasl_server_step.  If SASL_OK is
+      returned, the authentication is completed successfully, although
+      server out data may be supplied.
+
+ 3.6.   Common SASL API Routines
+
+      This section describes the routines that are common to both
+      clients and servers.
+
+  3.6.1. sasl_listmech function
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 18]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *user,
+            const char *prefix,
+            const char *sep,
+            const char *suffix,
+            char **result,
+            unsigned int *plen,
+            unsigned *pcount
+
+Results:
+            SASL_OK        -- Success
+            SASL_NOMEM     -- Not enough memory
+            SASL_NOMECH    -- No enabled mechanisms
+
+      This returns a list of enabled SASL mechanisms in a NUL-terminated
+      string.  The list is constructed by placing the prefix string at
+      the beginning, placing the sep string between any pair of mecha-
+      nisms and placing the suffix string at the end.
+
+      When calling this function plen and pcount MAY be NULL.
+
+      This function returns the list of client side SASL mechanisms, if
+      the conn was created by sasl_client_new and the list of server
+      side mechanisms, if the conn was created by sasl_server_new. The
+      list returned by this function must persist till a next call to
+      sasl_free_listmech or sasl_listmech.
+
+  3.6.2. sasl_free_listmech function
+
+Arguments:
+            sasl_conn_t *conn,
+            char **result
+
+Results:
+            none
+
+      This disposes of the result string returned by sasl_listmech.
+
+  3.6.3. sasl_setprop function
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 19]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn,
+            int propnum,
+            const void *value
+
+Results:
+            SASL_OK          -- property set
+            SASL_BADPARAM    -- invalid propnum or value
+            SASL_NOMEM       -- not enough memory to perform operation
+
+      This sets a property in a connection context. Commonly used prop-
+      erties with their descriptions are listed below:
+
+      SASL_SSF_EXTERNAL
+
+      Security layer strength factor (SSF) -- an unsigned integer usable
+      by the caller to specify approximate security layer strength
+      desired. It roughly corresponds to the effective key length for
+      encryption, e.g.
+       0   = no protection
+       1   = integrity protection only >1   = key lenght of the cipher
+
+      SASL_SSF_EXTERNAL property denotes SSF of the external security
+      layer (e.g.  provided by TLS). The value parameter points to
+      sasl_ssf_t, that is described as follows:
+
+      typedef unsigned sasl_ssf_t;
+
+
+
+      SASL_SEC_PROPS
+
+      The value parameter for SASL_SEC_PROPS points to sasl_secu-
+      rity_properties_t structure defined below. A particular implemen-
+      tation may extend it with additional fields.
+
+      typedef struct sasl_security_properties
+      {
+          sasl_ssf_t min_ssf;
+          sasl_ssf_t max_ssf;
+
+          unsigned maxbufsize;
+
+          /* bitfield for attacks to protect against */
+          unsigned security_flags;
+      } sasl_security_properties_t;
+
+      The min_ssf and the max_ssf define the minimal and the maximal
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 20]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      acceptable SSF.
+
+      The maxbufsize specifies the biggest buffer size that the
+      client/server is able to decode. 0 means that security layer is
+      not supported.
+
+      The security_flags is a bitmask of the various security flags
+      described below:
+
+       SASL_SEC_NOPLAINTEXT          -- don't permit mechanisms susceptible to simple
+                                        passive attack (e.g., PLAIN, LOGIN)
+       SASL_SEC_NOACTIVE             -- protection from active (non-dictionary) attacks
+                                        during authentication exchange.
+                                        Authenticates server.
+       SASL_SEC_NODICTIONARY         -- don't permit mechanisms susceptible to passive
+                                        dictionary attack
+       SASL_SEC_FORWARD_SECRECY      -- require forward secrecy between sessions
+                                        (breaking one won't help break next)
+       SASL_SEC_NOANONYMOUS          -- don't permit mechanisms that allow anonymous login
+       SASL_SEC_PASS_CREDENTIALS     -- require mechanisms which pass client
+                                        credentials, and allow mechanisms which can pass
+                                        credentials to do so
+       SASL_SEC_MUTUAL_AUTH          -- require mechanisms which provide mutual
+                                        authentication
+
+      SASL_AUTH_EXTERNAL
+
+      The value parameter for SASL_AUTH_EXTERNAL property points to the
+      external authentication ID as provided by external authentication
+      method, e.g. TLS, PPP or IPSec.
+
+  3.6.4. sasl_getprop function
+
+Arguments:
+            sasl_conn_t *conn,
+            int propnum,
+            const void **pvalue
+
+Results:
+            SASL_OK        -- Success
+            SASL_NOTDONE   -- Authentication exchange must complete prior to
+                              retrieving this attribute
+            SASL_BADPARAM  -- bad property number
+
+      This requests a pointer to a constant property available through
+      the SASL API.  The most common use by servers is to get the
+      SASL_USERNAME property which returns the authorization identity
+      (user to login as) from the SASL mechanism as a UTF-8 string in
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 21]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      the pvalue parameter.  Additional properties are listed in section
+      6.
+
+  3.6.5. sasl_dispose function
+
+Arguments:
+            sasl_conn_t **pconn
+
+Results:
+            none
+
+      This function disposes of the connection state created with
+      sasl_client_new or sasl_server_new, and sets the pointer to NULL.
+      If the pconn is already NULL the function does nothing.
+
+  3.6.6. sasl_done function
+
+Arguments:
+            none
+
+Results:
+            none
+
+      A SASL application that is finished with the SASL API must call
+      this function.  This function frees any memory allocated by the
+      SASL library or any other library state. After this call most of
+      the SASL API function will again return the SASL_NOTINIT error
+      code.
+
+      There must be a call to sasl_done for every successful call to
+      sasl_server_init or sasl_client_init made. Only the final
+      sasl_done does the actual cleanup; the preceding calls simply
+      decrement an internal reference count.
+
+      Connection states MUST be disposed of with sasl_dispose before
+      calling this function.
+
+4.     SASL Security Layer Routines
+
+      This section describes the routines need to support a security
+      layer.
+
+ 4.1. sasl_encode function
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 22]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *input,
+            unsigned int inputlen,
+            const char **output,
+            unsigned int *outputlen
+
+Results:
+            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 property
+
+      This function encodes a block of data for transmission using secu-
+      rity layer (if any). The output and outputlen are filled in with
+      the encoded data and its length respectively. If there is no secu-
+      rity layer the input buffer is returned in the output. Otherwise,
+      the output is only valid until a next call to sasl_encode or
+      sasl_dispose.
+
+ 4.1. sasl_decode function
+
+Arguments:
+            sasl_conn_t *conn,
+            const char *input,
+            unsigned int inputlen,
+            const char **output,
+            unsigned int *outputlen
+
+Results:
+            SASL_OK        -- Success (returns input if no layer negotiated)
+            SASL_NOTDONE   -- Security layer negotiation not finished
+            SASL_BADMAC    -- Bad message integrity check
+
+      This function decodes a block of data received using security
+      layer (if any). The output and outputlen are filled in with the
+      decoded data and its length respectively. If there is no security
+      layer the input buffer is returned in the output. Otherwise, the
+      output is only valid until a next call to sasl_decode or sasl_dis-
+      pose.
+
+5.     Advanced SASL API Routines
+
+      This section describes the less frequently used functions avail-
+      able in the SASL API.
+
+ 5.1.   Additional Initialization Routines
+
+  5.1.1. sasl_set_mutex function
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 23]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_mutex_alloc_t  *mutex_alloc,
+            sasl_mutex_lock_t   *mutex_lock,
+            sasl_mutex_unlock_t *mutex_unlock,
+            sasl_mutex_free_t   *mutex_free
+
+Results:
+            None
+
+      The sasl_set_mutex call sets the callbacks which the SASL API and
+      plug-ins will use whenever exclusive access to a process shared
+      resource is needed.  A single-threaded client or server need not
+      call this.  The types are designed to be compatible with the LDAP
+      API [LDAP-API]:
+
+      typedef void *sasl_mutex_alloc_t(void);
+
+      On success, this returns a pointer to an allocated and initialized
+      mutex structure.  On failure, it returns NULL.
+
+      typedef int sasl_mutex_lock_t(void *mutex);
+
+      This will block the current thread until it is possible to get an
+      exclusive lock on a mutex allocated by the mutex_alloc callback.
+      On success it returns 0, on failure due to deadlock or bad parame-
+      ter, it returns -1.
+
+      typedef int sasl_mutex_unlock_t(void *mutex);
+
+      This releases a lock on a mutex allocated by the mutex_alloc call-
+      back.  On success it returns 0, on failure due to an already
+      unlocked mutex, or bad parameter, it returns -1.
+
+      typedef void sasl_mutex_free_t(void *mutex);
+
+      This disposes of a mutex allocated by mutex_alloc.
+
+  5.1.2. sasl_set_alloc function
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 24]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+Arguments:
+            sasl_malloc_t  *malloc,
+            sasl_calloc_t  *calloc,
+            sasl_realloc_t *realloc,
+            sasl_free_t    *free
+
+Results:
+            None
+
+      This sets the memory allocation functions which the SASL API will
+      use.  The SASL API will use its own routines (usually the standard
+      C library) if these are not set.
+
+      typedef void *sasl_malloc_t(unsigned long mem_size);
+
+      This allocates memory mem_size bytes of memory.  The memory is not
+      initialized to any particular value.  It returns NULL on a fail-
+      ure, or when mem_size is 0.
+
+      typedef void *sasl_calloc_t(unsigned long elem_size,
+                      unsigned long num_elem);
+
+      This allocates elem_size * num_elem bytes of memory.  The memory
+      is initialized to 0.  It returns NULL on a failure or when either
+      elem_size and/or num_elem is 0.
+
+      typedef void *sasl_realloc_t(void *mem_ptr, unsigned long
+      new_size);
+
+      This changes the size of a memory block previously allocated by
+      malloc or calloc, and returns a pointer to the new location (which
+      may be different from mem_ptr).  If mem_ptr is NULL, it is identi-
+      cal to the malloc function.
+
+      It returns NULL on a failure or when new_size is 0. On failure the
+      original block is unchanged. When new_size is 0 the function works
+      as the free function.
+
+      typedef void sasl_free_t(void *mem_ptr);
+
+      This releases the memory in mem_ptr that was allocated by the mal-
+      loc or the calloc or resized by the realloc. If mem_ptr is NULL,
+      the function does nothing and returns immediately. The contents of
+      the memory may be altered by this call.
+
+6.     Additional Properties
+
+      <<To be completed>>
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 25]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+      SASL_SSF          -- security layer security strength factor,
+                           if 0, call to sasl_encode, sasl_decode unnecessary
+      SASL_MAXOUTBUF    -- security layer max output buf unsigned
+      SASL_DEFUSERREALM -- default realm passed to sasl_server_new or set with
+                           sasl_setprop
+      SASL_GETOPTCTX    -- context for getopt callback
+      SASL_CALLBACK     -- current callback function list
+      SASL_IPLOCALPORT  -- iplocalport string passed to sasl_server_new/
+                           sasl_client_new
+      SASL_IPREMOTEPORT -- ipremoteport string passed to sasl_server_new/
+                           sasl_client_new
+      SASL_SERVICE      -- service passed to sasl_*_new
+      SASL_SERVERFQDN   -- serverFQDN passed to sasl_*_new
+      SASL_AUTHSOURCE   -- name of the active plugin, if any
+      SASL_MECHNAME     -- active SASL mechanism name, if any
+      SASL_AUTHUSER     -- authentication/admin user (authorization id?)
+
+7.     References
+
+      [IMAP4] Crispin, M., "Internet Message Access Protocol - Version
+      4rev1", RFC 2060, University of Washington, December 1996.
+
+      [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate
+      Requirement Levels", RFC 2119, Harvard University, March 1997.
+
+      [POP3] Myers, J., Rose, M., "Post Office Protocol - Version 3",
+      RFC 1939, Carnegie Mellon, Dover Beach Consulting, Inc., May 1996.
+
+      [POP-AUTH] Myers, "POP3 AUTHentication command", RFC 1734,
+      Carnegie Mellon, December 1994.
+
+      [SASL] Myers, "Simple Authentication and Security Layer (SASL)",
+      RFC 2222, Netscape Communications, October 1997.
+
+      [GSSAPI]
+
+8.    Acknowledgements
+
+      The editor would like to thank Rob Siemborski and Ken Murchison
+      for providing useful feedback and suggestions.
+
+9.    Author's and Editor's Addresses
+
+
+     Author:
+
+     Chris Newman
+     Innosoft International, Inc.
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 26]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+     1050 Lakes Drive
+     West Covina, CA 91790 USA
+
+     Email: chris.newman@innosoft.com
+
+
+     Editor:
+
+     Alexey Melnikov
+     ACI WorldWide/MessagingDirect
+     59 Clarendon Road
+     Watford, Hertfordshire, WD17 1FQ, UK
+
+     Email: mel@messagingdirect.com
+
+
+10.    Full Copyright Statement
+
+   Copyright (C) The Internet Society (2003).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this doc-
+   ument itself may not be modified in any way, such as by removing the
+   copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of develop-
+   ing Internet standards in which case the procedures for copyrights
+   defined in the Internet Standards process must be followed, or as
+   required to translate it into languages other than English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MER-
+   CHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 27]
+
+
+
+
+
+INTERNET DRAFT                 SASL C API                  February 2003
+
+
+A. Appendix A -- Design Goals
+
+   The design goals of the SASL C API are as follows:
+
+
+o   To be simple and practical to use.
+
+o   To provide related utility services in addition to core SASL func-
+    tionality.
+
+o   To be reasonably extensible.
+
+o   To be suitable for use in a multi-threaded server or client.
+
+o   To avoid dependancies on a specific memory allocation system, thread
+    package or network model.
+
+o   To be an independent service rather than a new layer.
+
+
+B.     SASL API Index
+
+<<To be completed>>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman et al.             Expires: August 2003         FORMFEED[Page 28]
+
+
+
diff --git a/doc/draft-newman-sasl-passdss-xx.txt b/doc/draft-newman-sasl-passdss-xx.txt
new file mode 100644 (file)
index 0000000..4aa7cb8
--- /dev/null
@@ -0,0 +1,1122 @@
+
+
+
+
+
+
+Network Working Group                                          C. Newman
+Internet Draft: PASSDSS-3DES-1 SASL Mechanism                   Innosoft
+Document: draft-newman-sasl-passdss-01.txt                    March 1998
+                                                   Expires in six months
+
+
+             DSS Secured Password Authentication Mechanism
+
+
+Status of this memo
+
+     This document is an Internet-Draft.  Internet-Drafts are working
+     documents of the Internet Engineering Task Force (IETF), its areas,
+     and its working groups.  Note that other groups may also distribute
+     working documents as Internet-Drafts.
+
+     Internet-Drafts are draft documents valid for a maximum of six
+     months and may be updated, replaced, or obsoleted by other
+     documents at any time.  It is inappropriate to use Internet-Drafts
+     as reference material or to cite them other than as "work in
+     progress."
+
+     To view the entire list of current Internet-Drafts, please check
+     the "1id-abstracts.txt" listing contained in the Internet-Drafts
+     Shadow Directories on ftp.is.co.za (Africa), ftp.nordu.net
+     (Europe), munnari.oz.au (Pacific Rim), ds.internic.net (US East
+     Coast), or ftp.isi.edu (US West Coast).
+
+
+Abstract
+
+     Some system administrators are faced with a choice between
+     deploying a new authentication infrastructure or sending
+     unencrypted passwords in the clear over the Internet.  Deploying a
+     new authentication infrastructure often involves modifying
+     operating system services or keeping parallel authentication
+     databases up to date and is thus unacceptable to many
+     administrators.
+
+     Solutions which encrypt the entire session are often crippled with
+     weak keys (due to government restrictions) which are unsuitable for
+     passwords.  In addition, such solutions often reduce performance of
+     the entire session to an unacceptable level.  This specification
+     defines a SASL [SASL] mechanism which is compatible with existing
+     password-based authentication databases and does not require a
+     security layer for the remainder of the session.
+
+     [NOTE: Public discussion of this mechanism may take place on the
+
+
+
+Newman                                                          [Page 1]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     ietf-sasl@imc.org mailing list with a subscription address of
+     ietf-sasl-request@imc.org.  Private comments may be sent to the
+     author].
+
+1. How to Read This Document
+
+     This document is intended primarily for a programmer.  If
+     successful, it should be possible for a competent programmer to
+     write a client implementation using this specification, the SASL
+     [SASL] specification, an understanding of how to generate random
+     numbers [RANDOM], a description or implementation of the DES and
+     SHA1 [SHA1] algorithms and a multi-precision integer math library.
+     A cryptographic library or a copy of "Applied Cryptography"
+     [SCHNEIER] or similar reference is helpful for any implementation
+     and necessary for server DSS key generation.
+
+     The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+     in this document are to be interpreted as defined in "Key words for
+     use in RFCs to Indicate Requirement Levels" [KEYWORDS].
+
+1.1. Data Types Used in this Document
+
+     A list of data types used in this document follows.  Note that the
+     majority of this section is copied from the secure shell
+     specification [SSH-ARCH].
+
+     octet   A basic 8-bit unit of data.
+
+     uint32  A 32-bit unsigned integer.  Stored as four octets in
+             network byte order (also known as big endian or most
+             significant byte [MSB] first).  For example, the decimal
+             value 699921578 (hexadecimal 29b7f4aa) is represented with
+             the hexadecimal octet sequence 29 b7 f4 aa.
+
+     string  A string is a length-prefixed octet string.  The length is
+             represented as a uint32 with the data immediately
+             following.  A length of 0 indicates an empty string.  The
+             string MAY contain NUL or 8-bit octets.  When used to
+             represent textual strings, the characters are interpreted
+             in UTF-8 [UTF-8].  Other character encoding schemes MUST
+             NOT be used.
+
+     mpint   Represents multiple precision integers in two's complement
+             format, stored as a string, most significant octet first.
+             Negative numbers have one in the most significant bit of
+             the first octet of the string data. If the most significant
+             bit would be set for a positive number, the number MUST be
+             preceded by a zero byte.  Unnecessary leading zero or 255
+
+
+
+Newman                                                          [Page 2]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+             bytes MUST NOT be included.  The value zero MUST be stored
+             as a string with zero bytes of data.
+
+             By convention, a number that is used in modular
+             computations in the field of integers mod n SHOULD be
+             represented in the range 0 <= x < n.
+
+             Examples:
+
+              value (hex)        representation (hex)
+              -----------------------------------------------------------
+              0                  00 00 00 00
+              9a378f9b2e332a7    00 00 00 08 09 a3 78 f9 b2 e3 32 a7
+              80                 00 00 00 02 00 80
+              -1234              00 00 00 02 ed cc
+              -deadbeef          00 00 00 05 ff 21 52 41 11
+
+1.2. Glossary
+
+     This section includes some acronyms used in this document.
+
+     DES  The U.S. Government Data Encryption Standard is a symmetric
+          encryption algorithm introduced in 1975 which uses a 56 bit
+          key.  The algorithm is documented in [SCHNEIER].
+
+     DSA  The U.S. Government Digital Signature Algorithm standard.  A
+          public key signature algorithm available for unrestricted use
+          without a license.
+
+     DSS  The U.S. Government Digital Signature Standard [DSS] which
+          employs the DSA algorithm.
+
+     HMAC A hash-based message authentication code [HMAC] summarized in
+          Appendix A.4.  Test cases are available in [HMAC-TEST].
+
+     SHA  The Secure Hash Algorithm (version 1) which is part of the DSS
+          standard.
+
+     triple-DES
+          Use of the DES algorithm three times in an encrypt-decrypt-
+          encrypt mode with three independent keys as described in
+          appendix A.3.
+
+2. Overview
+
+     This section includes a brief discussion of design goals, intended
+     use and an overview for this SASL mechanism.  An overview of some
+     of the algorithms used is in Appendix A.
+
+
+
+Newman                                                          [Page 3]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+2.1. Design Goals
+
+     The ideal authentication mechanism would be simple, fast, fully
+     secure, freely distributable without restrictions and backwards
+     compatible with deployed back-end authentication databases.
+     Unfortunately, it is not possible to achieve all these goals so
+     priorities and tradeoffs are necessary.  This mechanism has
+     compatibility with deployed back-end authentication databases and
+     protection from passive and active attacks on the underlying
+     connection as primary design goals.  Simplicity and unrestricted
+     binary distribution are secondary design goals.
+
+     Backwards compatibility is achieved by using plain-text
+     passphrases.  Protection from passive and active attacks is
+     achieved by using public and symmetric key technology to encrypt
+     the passphrase and optionally protect the remainder of the session.
+     Some simplicity is achieved by avoiding complicated public key
+     certification issues and formats as well as making the SASL session
+     security layer and certification by the client optional.
+     Unrestricted binary distribution is hopefully achieved by using
+     unencumbered algorithms and making the SASL privacy layer optional.
+
+2.2. Intended Use
+
+     This is intended as a plug-and-play mechanism for services layered
+     on top of deployed passphrase-based back-end authentication
+     databases.  When no security layer is implemented it can be added
+     to a SASL-based protocol without modifying or substituting network
+     read and write APIs.  When the optional session privacy protection
+     is omitted, the author speculates that it may be possible to make a
+     binary implementation which would be exportable from the United
+     States.
+
+     For cases where simplicity, speed or unrestricted source code
+     distribution is more desirable than backwards compatibility or
+     security, a mechanism such as CRAM-MD5 [CRAM-MD5] or SCRAM [SCRAM]
+     is preferred.
+
+     The optional SASL integrity and privacy protection is provided as a
+     simple alternative to full service security layers such as TLS
+     [TLS] or Secure Shell [SSH-ARCH].  However, there are many
+     advantages to full service security layers such as compression,
+     faster symmetric cipher options, and the ability to leverage other
+     public key infrastructures.  An implementation which supports TLS
+     may have no incentive to support SASL security layers at all.  The
+     complexity verses functionality tradeoff is significant enough that
+     these mechanisms do not compete.
+
+
+
+
+Newman                                                          [Page 4]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+2.3. Mechanism Overview
+
+     The PASSDSS-3DES-1 mechanism uses three components to perform a
+     secure authentication against a legacy passphrase database.
+
+     In order to protect against active attacks, a DSS public key in a
+     format compatible with Secure Shell [SSH-TRANS] is used to
+     authenticate the server to the client.  The client is presumed to
+     have the server's public key or a SHA-1 hash thereof stored locally
+     in a secure database.  If the client is willing to risk exposure to
+     active attacks, it may skip the public key certification step
+     altogether or do a one-time initialization of its local database,
+     perhaps with user interaction.
+
+     In addition to the DSS public key, a Diffie-Hellman key exchange is
+     used to generate a key for encrypting the passphrase.  The
+     "PASSDSS-3DES-1" variant of this mechanism uses the same fixed
+     Diffie-Hellman group used by Secure Shell's diffie-hellman-group1-
+     sha1 key exchange [SSH-TRANS].  If more groups are necessary, they
+     will be assigned to mechanism variants "PASSDSS-3DES-2" and so
+     forth.
+
+     Finally, the triple-DES algorithm is used to encrypt the client's
+     passphrase and send it to the server.
+
+2.4. Message Format Overview
+
+     This section provides a quick overview of the format of the
+     messages.  The formal definition of the syntax for these messages
+     is in section 6.  A detailed discussion of their implementation on
+     clients and servers is in sections 3 and 4 respectively.
+
+     First message from client to server:
+       string azname       ; the user name to login as, may be empty if
+                             same as authentication name
+       string authname     ; the authentication name
+       mpint  X            ; Diffie-Hellman parameter X
+
+     The challenge from server to client is as follows:
+       uint32   pklength   ; length of SSH-style DSA server public key
+         string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+         mpint  p          ; DSA public key parameters
+         mpint  q
+         mpint  g
+         mpint  y
+       mpint    Y          ; Diffie-Hellman parameter Y
+       OCTET    ssecmask   ; SASL security layers offered
+       3 OCTET  sbuflen    ; maximum server security layer block size
+
+
+
+Newman                                                          [Page 5]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+       uint32   siglength  ; length of SSH-style dss signature
+         string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+         mpint  r          ; DSA signature parameters
+         mpint  s
+
+     The client then sends the following message encrypted with
+     triple-DES:
+       OCTET    csecmask   ; SASL security layer selection
+       3 OCTET  cbuflen    ; maximum client block size
+       string   passphrase ; the user's passphrase
+       20 OCTET cli-hmac   ; a client HMAC-SHA-1 signature
+
+3. Client Implementation of PASSDSS-3DES-1
+
+     This section includes a step-by-step guide for client implementors.
+     Although section 6 contains the formal definition of the syntax and
+     is the authoritative reference in case of errors here, this section
+     should be sufficient to build a correct implementation.
+
+     The SASL mechanism name is "PASSDSS-3DES-1".
+
+     The value of n used for the Diffie-Hellman exchange is as follows
+     (represented as an unsigned hexadecimal integer):
+
+           FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1
+           29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD
+           EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245
+           E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED
+           EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381
+           FFFFFFFF FFFFFFFF.
+
+     When represented as an "mpint", this would have a prefix of
+     "0000008100."  The value of g is 2.  This group was taken from the
+     ISAKMP/Oakley specification, and was originally generated by
+     Richard Schroeppel at the University of Arizona.  Properties of
+     this prime are described in [Orm96].
+
+     The client begins by doing the following:
+
+     (A) Generate the Diffie-Hellman private value "x".  This should be
+     less than (n - 1)/2.  The number of bits of entropy to use in "x"
+     is an important decision, as shorter lengths will be less secure
+     and longer lengths will noticeably reduce performance.  At the time
+     this was written, 192 bits of entropy [RANDOM] is probably
+     sufficient.  For more information on this topic, see [SHORT-EXP].
+
+
+
+
+
+
+Newman                                                          [Page 6]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     (B) Compute the Diffie-Hellman public value "X" as follows.  If X
+     has a value of 0, repeat step (A).
+                x
+           X = 2  mod n
+
+     The client then sends the following three pieces of information to
+     the server:
+
+     (1) An authorization identity represented as a string.  When the
+     empty string is used, this defaults to the authentication identity.
+     This is used by system administrators or proxy servers to login
+     with a different user identity.
+
+     (2) An authentication identity represented as a string.  This is
+     the identity whose passphrase will be used.
+
+     (3) The "X" result from step (B) represented as an mpint.
+
+     The server responds by sending a message containing the following
+     information:
+
+     (4) An "ssh-dss" public key compatible with Secure Shell, including
+     the 32-bit length prefix in network byte order, the Secure Shell
+     string "ssh-dss" and mpints for "p", "q", "g" and "y" (see Appendix
+     A.1).
+
+     (5) The mpint "Y" as defined for the Diffie-Hellman key exchange
+     (see Appendix A.2).
+
+     (6) A single octet bit mask representing the security layers
+     available in the same format used by the KERBEROS_V4 mechanism
+     [SASL].  Bit 0 (value 1) indicates it is permissible to have no
+     security layer.  Bit 1 (value 2) indicates integrity protection is
+     permissible.  Bit 2 (value 4) indicates privacy protection for the
+     rest of the session is available.  The remaining bits are reserved
+     for future use.
+
+     (7) A three octet unsigned integer in network byte order
+     representing the maximum cipher-text buffer size the server is able
+     to receive.  If this is less than 32, it indicates that a SASL
+     security layer is not supported.
+
+     (8) A DSA signature, including a 32-bit length, the Secure Shell
+     string "ssh-dss" and mpints for "r" and "s".
+
+     The client then does the following:
+
+     (C) Verify that "Y" is between 1 and n - 1 inclusive.  If "Y" is
+
+
+
+Newman                                                          [Page 7]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     outside this range, the client MUST cancel the authentication.
+
+     (D) Verify that the public key from step (4) belongs to the server.
+     This can be done either with a database of SSH public keys or with
+     a database of SHA1 hashes of such public keys.  If the client does
+     not have a matching entry for the server or does not have a public
+     key database, it MAY skip this step although it SHOULD alert the
+     user that the connection is susceptible to active attacks if it
+     does so.  It MAY also record the public key (or SHA1 hash thereof)
+     in its database with permission from the user.
+
+     (E) Compute the Diffie-Hellman key K as follows.  It may be
+     necessary to mask timing attacks [TIMING].
+                x
+           K = Y  mod n
+
+     (F) Create a buffer containing data from steps (1) through (7) in
+     order immediately followed by K represented as an mpint.
+
+     (G) Compute the SHA1 hash of the buffer from (F).  This produces a
+     20 octet result.
+
+     (H) If the public key from step (4) was not certified, this step
+     MAY be skipped.  Otherwise, verify that the DSS signature is a
+     signature of (G).  This computation is done as defined in appendix
+     A.1 where the output of step (G) represents the message "m" (note
+     that this results in SHA1 being applied twice).
+
+     (I) Compute the following 20-octet values.  K represents the output
+     of step (E) in mpint format.  H represents the output of step (G).
+     The || symbol represents string concatenation.  "A" represents a
+     single octet containing the US-ASCII value of capital letter A.
+         cs-encryption-iv    = SHA1( K || "A" || H )
+         sc-encryption-iv    = SHA1( K || "B" || H )
+         cs-encryption-key-1 = SHA1( K || "C" || H )
+         cs-encryption-key-2 = SHA1( K || cs-encryption-key-1 )
+         cs-encryption-key   = cs-encryption-key-1 || cs-encryption-key-2
+         sc-encryption-key-1 = SHA1( K || "D" || H )
+         sc-encryption-key-2 = SHA1( K || sc-encryption-key-1 )
+         sc-encryption-key   = sc-encryption-key-1 || sc-encryption-key-2
+         cs-integrity-key    = SHA1( K || "E" || H )
+         sc-integrity-key    = SHA1( K || "F" || H )
+
+     (J) Create a buffer beginning with a bit mask for the selected
+     security layer (it MUST be one offered in 6) followed by three
+     octets representing the maximum cipher-text buffer size (at least
+     32) the client can accept in network byte order.  This is followed
+     by a string containing the passphrase.  Note that integrity
+
+
+
+Newman                                                          [Page 8]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     protection is pointless unless the public key was certified in
+     step (D) and the signature was verified in step (H).
+
+     (K) Create a buffer containing items (1) through (7) immediately
+     followed by the first four octets of (J).
+
+     (L) Compute HMAC-SHA-1 with (K) as the data and the cs-integrity-
+     key from step (I) as the key.  This produces a 20 octet result.  A
+     summary of the HMAC-SHA-1 algorithm [HMAC] is in appendix A.4.
+
+     (M) Create a buffer containing (J) followed by (L) followed by an
+     arbitrary number of zero octets as necessary to reach the block
+     size of DES and conceal the passphrase length from an eavesdropper.
+
+     (N) Apply the triple-DES algorithm to (M) with the first 8 octets
+     of cs-encryption-iv from step (I) as the initialization vector and
+     the first 24 octets of cs-encryption-key as the key.  If optional
+     privacy protection is negotiated on, the triple-DES state is not
+     reset.
+
+     The client then sends a message to the server containing the
+     following:
+
+     (9) The output of step (N).
+
+     If a SASL security layer is negotiated on, the following steps are
+     used when sending a message:
+
+     (O) Create a buffer containing a uint32 client packet number
+     (starting from 0) immediately followed by the cs-integrity-key from
+     step (I).
+
+     (P) Compute HMAC-SHA-1 with (O) as the key and the data to transmit
+     as the data.
+
+     (Q) Create a buffer containing the data to transmit followed by the
+     20-octet output of (P).  If privacy was negotiated on, this is
+     followed by zero to seven padding octets followed by one more octet
+     indicating the number of padding octets.  The total size MUST be a
+     multiple of the DES block size.
+
+     (R) The result of step (Q) is encrypted with triple-DES if privacy
+     was negotiated and is sent prefixed by a uint32 length, as required
+     by SASL.
+
+     If a SASL security layer was negotiated on, the following steps are
+     taken when receiving a message:
+
+
+
+
+Newman                                                          [Page 9]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     (S) If privacy was negotiated on, the message is decrypted using
+     triple-DES with the first 24 octets of sc-encryption-key as the
+     key.  The value of the last octet plus one indicates the number of
+     octets to ignore at the end of the output.  The sc-encryption-iv is
+     used to initialize triple-DES state the first time this is done.
+
+     (T) Create a buffer containing a uint32 server packet number
+     (starting from 0) immediately followed by the sc-integrity-key.
+
+     (U) Compute HMAC-SHA-1 with (T) as the key over the portion of the
+     data excluding the 20 octet signature and any encryption padding.
+     If this is the same as the 20 octet signature, then the data is not
+     corrupted.
+
+4. Server Implementation of PASSDSS-3DES-1
+
+     The section includes a step-by-step guide for server implementors.
+     It is intended to be read in conjunction with section 3.
+
+     The server MUST have a persistent DSS-SSH public key.  Mechanisms
+     for generating such keys are described in [SCHNEIER] and [DSS].
+
+     IMPORTANT NOTE: The server MUST be able to process any message from
+     the client, including messages of any size, messages with invalid
+     content and messages with NULs in the middle of strings.  When
+     input is illegal, the server MUST gracefully reject authentication
+     or in extreme cases gracefully terminate the connection.
+     Particular care to avoid buffer overruns is important if the user
+     name or passphrase strings are copied.
+
+     The server performs the following computations prior to or during
+     the connection by the client:
+
+     (a) Select a random number k less than (p - 1)/2.  It is important
+     to generate a good random number [RANDOM].
+
+     (b) Compute signature component "r" as follows:
+                 k
+           r = (g  mod p) mod q
+
+     (c) Optionally pre-compute the group inverse of k, mod q and the
+     value xr.
+
+     (d) Select a random Diffie-Hellman private key y less than (n -
+     1)/2.  Follow the same guidance as in (A) above.
+
+
+
+
+
+
+Newman                                                         [Page 10]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     (e) Compute the Diffie-Hellman public value Y as follows.  If Y has
+     a value of 0, repeat step (d) above.
+                y
+           Y = 2  mod n
+
+     (f) Verify that the value X from the client is between 1 and (n -
+     1).  If it isn't, fail the authentication.
+
+     (g) Compute the Diffie-Hellman shared key K as follows.  It may be
+     necessary to mask timing attacks [TIMING].
+                y
+           K = X  mod n
+
+     (h) Create a buffer containing items (1) through (7) above followed
+     by K represented as an mpint.
+
+     (i) Compute the SHA-1 hash of the buffer from (h).  This produces a
+     20 octet result.
+
+     (j) Generate a DSS signature of (i).  The signature is made up of
+     "r" from step (b) and the result following computation (partially
+     completed in step c):
+                 -1
+           s = (k  (SHA1(h) + xr)) mod q
+
+     (k) Create a buffer containing items (4) through (8) and send it to
+     the client.
+
+     (l) Perform the computations as described in step (I) where K is
+     the result of step (g) in mpint format and H is the result of step
+     (i).
+
+     (m) Decrypt message (9) from the client using triple-DES with cs-
+     encryption-iv as the initialization vector and the first 24 octets
+     of cs-encryption-key as the key.
+
+     (n) Verify the passphrase from the output of step (m) against the
+     authentication database.  Fail the authentication if verification
+     fails.
+
+     (o) Verify that the selected security layer is permitted and the
+     cipher text buffer size is at least 32.  If not, fail the
+     authentication.
+
+     (p) Create a buffer containing steps (1) through (7) followed by
+     the first four octets of the result from (m).
+
+     (q) Compute the HMAC-SHA-1 of (p) with cs-integrity-key as the key.
+
+
+
+Newman                                                         [Page 11]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     This produces a 20-octet result.
+
+     (r) Compare the output of (q) with the 20 octet signature after the
+     passphrase in the output of (m).  If they don't match, fail the
+     authentication.
+
+     If a SASL security layer is negotiated on, sending and receiving
+     procedures are similar to steps (O)-(U), with client and server
+     roles exchanged (and thus sc-* values and cs-* value exchanged).
+     Note that triple-DES state from step (m) is not reset.
+
+5. Example
+
+     The following is an example of the PASSDSS-3DES-1 mechanism using
+     the IMAP [IMAP4] profile of SASL.  Note that base64 encoding and
+     the lack of an initial client response with the first command are
+     characteristics of the IMAP profile of SASL and not characteristics
+     of SASL or this mechanism.
+
+     In this example, "C:" represents lines sent from the client to the
+     server and "S:" represents lines sent from the server to the
+     client.  The wrapped lines are for editorial clarity -- there are
+     no actual newlines in the middle of the messages.
+
+       C: a001 AUTHENTICATE PASSDSS-3DES-1
+       S: +
+       C: AAAAAAAAAAVjaHJpcwAAAIEAhuVbMxdLxrAQVyUWbAp+X09h6QmZ2Jebz
+          H7YhtcbQyLbB9AGi1eIdojZYtAuVeE+PYkKUANLHI9XzWSFliIGMeUvBc
+          bflHr+s9tZ5/5YZh9blb33km3tUYVKyB5XP530bDn+lY1lAv6tXHKZPrx
+          b0zPhc+JGgpWGlmT5k9vx2Wk=
+       S: + AAAA8gAAAAdzc2gtZHNzAAAAQQDPVlO6nFefrq6fA/dQKIoNj75Jjpp
+          kVv3DkyILABCox2dMql0bnO48rHFuo167y6oukT/ocKupIw6bgKmdofgd
+          AAAAFQDRpB6FrxemUGRuLjY/oiH/Qef14QAAAEEAkVr9rOlB58k5XoqmP
+          NYTrVGZKWbCPcYtaL92ANxgWyjyRo49+m0+fHPNhNibQoLddEZF8lHPKW
+          gb7z7qz0QMdgAAAEARcIEiMz5jTZo8COf2njL3BTWRND5NGAgZY7s1YOm
+          2BfjVyf1/MkOiQMiXeonrsfMc0sWQGgpRYRtJWpe56cc2AAAAgQDoV5Uk
+          bcy3Gjf16MZwPLlJlvmjpSNv2dSSApoddd4+BgZr01zyt7hzb0yRruaN5
+          fG43DbJLkk7mtL1Hw8aYXBMQQzrPpHtx+anpCDoN2jlersCGFY2cnjxTf
+          HqY139ohA8vVXYpapeXxKXR4//Ib/ApTGmwlOeIikKDrBmEGX/JgEAAAA
+          AAAA8AAAAB3NzaC1kc3MAAAAVAI7j3HG8HyjCOxaGFOUTwZqe0xSHAAAA
+          FHSqU41vPHTCRTqmxNFwXqazPlJH
+       C: Obp6vQ83q1O/OnQDifZB1rWOci9LaSck8VxNB4UAFhRI56BAs4XPLqOWI
+          CoB3LYZ
+       S: a001 OK Authentication Completed
+
+     The following private values were used in this example.  These
+     values are all represented as an mpint in hexadecimal (msb first).
+
+
+
+
+Newman                                                         [Page 12]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     The client private Diffie-Hellman "x" value:
+
+       00000018 666E35B4 3BF4BF2B 40E31359 7A5D3AD0 61FD4F6F 736A6114
+
+     The server private Diffie-Hellman "y" value:
+
+       00000018 587BDFD6 800D101C 8E82E233 3B5A07AA DB87B8F1 68DC194D
+
+     The Diffie-Hellman shared secret:
+
+       00000080 3B46D3A8 D2163930 1C33D9FE EAFA528D F4B881CF DF906A03
+       33249A88 42547FF6 49FDC149 1A5084B1 B425A105 CE571283 AC61D896
+       AF8F7AF7 F95643F3 00A91E57 BCB8CFD7 77A25CBD 35F59A9E 59E98BEA
+       EA866339 7F0F9AA0 2F0F335C 8C6AAFF7 76BDB668 DF4D51AF 5B4FB807
+       81A70901 F478FB86 BF42055C BAF46094 EC72E98A
+
+     The DSA private key value (the public key is in the exchange):
+
+       00000014 252BCBFA 5634D706 6ED43128 972E181E 66BF9C30
+
+     The SHA-1 hash value used to compute the keys:
+
+       26 75 97 06 EB FE E3 69 C9 03 7D 49 64 19 D5 D2 97 66 E8 CE
+
+6. Formal Syntax of PASSDSS-3DES-1 Messages
+
+     This is the formal syntactic definition of the client and server
+     messages.  This uses ABNF [ABNF] notation including the core rules.
+     The first three rules define the formal exchange.  The later rules
+     define the elements of the exchange.
+
+     client-msg-1     = [azname] authname diffie-hellman-X
+
+     server-msg-1     = dss-public-key diffie-hellman-Y
+                        ssecmask sbuflen dss-signature
+
+     client-msg-2     = client-blob
+
+
+     authname         = string
+                        ;; interpreted as UTF-8 [UTF-8]
+
+     azname           = string
+                        ;; interpreted as UTF-8 [UTF-8]
+
+     cbuflen          = 3OCTET
+                        ;; Big endian binary unsigned integer
+                        ;; max length of client read buffer
+
+
+
+Newman                                                         [Page 13]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     cli-hmac         = 20OCTET
+
+     client-blob      = 8*OCTET
+                        ;; encrypted version of client-encrypted
+
+     client-encrypted = csecmask cbuflen passphrase cli-hmac *NUL
+                        ;; MUST be multiple of DES block size
+
+     csecmask         = OCTET
+                        ;; client selected protection layer
+
+     diffie-hellman-X = mpint
+
+     diffie-hellman-Y = mpint
+
+     dss-g            = mpint
+
+     dss-p            = mpint
+
+     dss-public-key   = length NUL NUL NUL %x07 "ssh-dss"
+                        dss-p dss-q dss-g dss-y
+                        ;; length is total length of remainder
+                        ;; as defined in [SSH-TRANS]
+
+     dss-q            = mpint
+
+     dss-r            = mpint
+
+     dss-signature    = length NUL NUL NUL %x07 "ssh-dss"
+                        dss-r dss-s
+                        ;; length is total length of remainder
+
+     dss-s            = mpint
+
+     dss-y            = mpint
+
+     length           = 4OCTET
+                        ;; binary number, big endian format (MSB first)
+
+     mpint            = length *OCTET
+                        ;; length specifies number of octets
+                        ;; see section 1 for detailed mpint definition
+
+     passphrase       = string
+                        ;; At least 64 octets MUST be supported
+
+
+
+
+
+
+Newman                                                         [Page 14]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     sbuflen          = 3OCTET
+                        ;; Big endian binary unsigned integer
+                        ;; max length of server read buffer
+
+     ssecmask         = OCTET
+                        ;; server protection layer mask
+
+     string           = length *OCTET
+                        ;; the length determines the number of octets
+                        ;; OCTETs are interpreted as UTF-8
+
+     NUL              = %x00  ;; US-ASCII NUL character
+
+7. Security Considerations
+
+     Security considerations are discussed throughout this memo.
+
+     This mechanism supplies the server with the plain-text passphrase,
+     so the server gains the ability to masquerade as the user to any
+     other services which share the same passphrase.
+
+     If the public key certification step is skipped, then an active
+     attacker can gain the client's passphrase and thus the ability to
+     masquerade as the user to any other services which share the same
+     passphrase.  Negotiating a security layer will fail to provide
+     protection from an active attacker in this case.
+
+     If no security layer is negotiated, the rest of the protocol
+     session is subject to active and passive attacks.
+
+     If an integrity-only layer is negotiated, the rest of the protocol
+     is subject to passive eavesdropping.
+
+     The quality of this mechanism depends on the quality of the random
+     number generator used.  See [RANDOM] for more information.
+
+8. Multinational Considerations
+
+     As remote access is a crucial service, users are encouraged to
+     restrict user names and passphrases to the US-ASCII character set.
+     However, if characters outside the US-ASCII character set are used
+     in user names and passphrases, then they are interpreted according
+     to UTF-8 [UTF-8] and it is a protocol error to include any octet
+     sequences not legal for UTF-8.  Servers are encouraged to enforce
+     this restriction to discourage clients from using non-interoperable
+     local character sets in this context.
+
+
+
+
+
+Newman                                                         [Page 15]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+9. Intellectual Property Issues and Acknowledgments
+
+     David Kravitz holds U.S. Patent #5,231,668 on the DSA algorithm.
+     NIST has made this patent available world-wide on a royalty-free
+     basis.
+
+     Diffie-Hellman was first published in 1976 [DIFFIE-HELLMAN].  U.S.
+     Patent #4,200,770 granted April 1980 has expired.  Canada Patent
+     #1,121,480 was granted April 6, 1982 and may still apply at this
+     time.
+
+     DES is covered under U.S. Patent #3,962,539 granted June 1978,
+     which has expired.
+
+     The majority of the constructions in this specification were copied
+     from the Secure Shell specifications [SSH-ARCH, SSH-TRANS].
+     Additional information is paraphrased from "Applied Cryptography"
+     [SCHNEIER].
+
+10. References
+
+     [ABNF] Crocker, Overell, "Augmented BNF for Syntax Specifications:
+     ABNF", RFC 2234, Internet Mail Consortium, Demon Internet Ltd,
+     November 1997.
+
+     [CRAM-MD5] Klensin, Catoe, Krumviede, "IMAP/POP AUTHorize Extension
+     for Simple Challenge/Response", RFC 2195, MCI, September 1997.
+
+     [DIFFIE-HELLMAN] Diffie, W., Hellman, M.E., "Privacy and
+     Authentication: An introduction to Cryptography," Proceedings of
+     the IEEE, v. 67, n. 3, March 1979, pp. 397-427.
+
+     [DSS] National Institute of Standards and Technology, "Digital
+     Signature Standard," NIST FIPS PUB 186, U.S. Department of
+     Commerce, May 1994.
+
+     [HMAC] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for Message
+     Authentication", RFC 2104, IBM, UCSD, February 1997.
+
+     [HMAC-TEST] Cheng, Glenn, "Test Cases for HMAC-MD5 and HMAC-SHA-1",
+     RFC 2202, IBM, NIST, September 1997.
+
+     [IMAP4] Crispin, M., "Internet Message Access Protocol - Version
+     4rev1", RFC 2060, University of Washington, December 1996.
+
+     [KEYWORDS] Bradner, "Key words for use in RFCs to Indicate
+     Requirement Levels", RFC 2119, Harvard University, March 1997.
+
+
+
+
+Newman                                                         [Page 16]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     [Orm96] Orman, H., "The Oakley Key Determination Protocol", version
+     1, TR97-92, Department of Computer Science Technical Report,
+     University of Arizona.
+
+     [RANDOM] Eastlake, Crocker, Schiller, "Randomness Recommendations
+     for Security", RFC 1750, DEC, Cybercash, MIT, December 1994.
+
+     [SASL] Myers, "Simple Authentication and Security Layer (SASL)",
+     RFC 2222, Netscape Communications, October 1997.
+
+     [SCHNEIER] Schneier, B., "Applied Cryptography: Protocols,
+     Algorithms and Source Code in C," John Wiley and Sons, Inc., 1996.
+
+     [SCRAM] Newman, "Salted Challenge Response Authentication Mechanism
+     (SCRAM)", work in progress, January 1998.
+
+     [SHA1] NIST FIPS PUB 180-1, "Secure Hash Standard," National
+     Institute of Standards and Technology, U.S. Department of Commerce,
+     April 1995.
+
+     [SHORT-EXP] van Oorschot, P., Wiener, M., "On Diffie-Hellman Key
+     Agreement with Short Exponents", Advances in Cryptography --
+     EUROCRYPT Springer-Verlag, ISBN 3-540-61186-X, pp. 332-343.
+
+     [SSH-ARCH] Ylonen, Kivinen, Saarinen, "SSH Protocol Architecture",
+     Work in progress, SSH, October 1997.
+
+     [SSH-TRANS] Ylonen, Kivinen, Saarinen, "SSH Transport Layer
+     Protocol", Work in progress, SSH, October 1997.
+
+     [TIMING] Kocher, P., "Timing Attacks on Implementations of Diffie-
+     Hellman, RSA, DSS and Other Systems", Advances in Cryptography --
+     CRYPTO '96 Proceedings, Lecture Notes in Computer Science, Vol
+     1109, Springer-Verlag, ISBN 3-540-61512-1, pp. 104-113.
+
+     [TLS] Dierks, Allen, "The TLS Protocol Version 1.0", Work in
+     progress.
+
+     [UTF8] Yergeau, "UTF-8, a transformation format of ISO 10646",
+     RFC 2279, Alis Technologies, January 1998.
+
+
+
+
+
+
+
+
+
+
+
+Newman                                                         [Page 17]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+11. Author's Address
+
+     Chris Newman
+     Innosoft International, Inc.
+     1050 Lakes Drive
+     West Covina, CA 91790 USA
+
+     Email: chris.newman@innosoft.com
+
+Appendix A. Algorithm Overview
+
+     This section provides a quick overview of the algorithms used.  For
+     a full understanding, the reader is encouraged to read "Applied
+     Cryptography" [SCHNEIER].  The follow descriptions are paraphrased
+     from that source.
+
+     Note that an overview of the DES algorithm is not included as
+     publicly available implementations and descriptions are very
+     common.
+
+Appendix A.1. DSA Algorithm
+
+     The DSA algorithm is a public key algorithm which can be used to
+     sign messages such that the source can be verified using a public
+     key.  The algorithm has the following parameters:
+
+     p is a prime number L bits long.  Implementations MUST support L
+     between 512 and 1024 bits.
+
+     q is a 160-bit prime factor of (p - 1).
+
+          (p - 1)/q
+     g = h          mod p  where h is any number less than p - 1 such
+
+              (p - 1)/q
+        that h           is greater than 1.
+
+     x is a number less than q and represents the private key.
+
+          x
+     y = g  mod p  and represents the public key.
+
+     To sign a message m, the client generates a random number k less
+     than q and computes:
+
+              k
+        r = (g  mod p) mod q
+
+
+
+
+Newman                                                         [Page 18]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+              -1
+        s = (k  (SHA1(m) + xr)) mod q
+
+     The signature is represented as r and s, and is verified as
+     follows:
+
+              -1
+        w  = s   mod q
+
+        u1 = (SHA1(m) * w) mod q
+
+        u2 = (rw) mod q
+
+                u1    u2
+        v  = ((g   * y  ) mod p) mod q
+
+     If v = r then the signature is verified.
+
+Appendix A.2. Diffie-Hellman Algorithm
+
+     The Diffie-Hellman algorithm is a key-exchange algorithm.  It
+     allows two ends of a communications channel to establish a shared
+     secret which a passive eavesdropper can not easily determine.  This
+     key can then be used in a symmetric algorithm such as triple-DES.
+     The two ends have a prior agreement on two numbers:
+
+     n a large prime number
+
+     g a primitive mod n.
+
+     The client chooses a random large integer x and computes:
+
+            x
+       X = g  mod n
+
+     and sends X to the server.  The server chooses a random large
+     integer y and computes:
+
+           y
+      Y = g  mod n
+
+           y
+      K = X  mod n
+
+     The server sends Y to the client.  The client computes:
+
+           x
+      K = Y  mod n
+
+
+
+Newman                                                         [Page 19]
+\f
+Internet Draft       PASSDSS-3DES-1 SASL Mechanism            March 1998
+
+
+     At this point, the client and server share the same secret K.
+
+Appendix A.3. Triple-DES Algorithm in EDE/outer-CBC Mode
+
+     The DES algorithm uses an 8 octet (64 bit) key of which 56 bits are
+     significant.  The triple-DES EDE algorithm uses a 24 octet (192
+     bit) key of which roughly 112 bits are significant see [SCHNEIER]
+     for more details.  The "EDE" refers to encrypt-decrypt-encrypt, and
+     the "CBC" refers to cipher-block-chaining where each cipher block
+     affects future cipher blocks.  If E() is the DES encryption
+     function, D() is the DES decryption function, C is a cipher text
+     block and P is a plain-text block, then triple-DES EDE in CBC mode
+     with outer chaining is:
+
+        C  = E  (D  (E  (P  XOR C   )))
+         i    K3  K2  K1  i      i-1
+
+     NOTE: C  is the initialization vector
+            0
+
+     and the decryption function is:
+
+        P  = C    XOR D  (E  (D  (C )))
+         i    i-1      K3  K2  K1  i
+
+     K1 is the first 8 octets of the triple-DES key, K2 is the second 8
+     octets and K3 is the final 8 octets.
+
+Appendix A.4. HMAC-SHA-1 Keyed hash function
+
+     HMAC-SHA-1 uses the SHA-1 hash function to create a keyed hash
+     function suitable for use as an integrity protection function.  A
+     more complete description is in [HMAC].  A brief summary of the
+     algorithm follows:
+
+     (A) If the key is longer than 64 octets, it is run through the
+     SHA-1 function to produce a 20 octet key.
+
+     (B) The key is exclusive-ored with a 64 octet buffer filled with
+     the octet value 0x36.
+
+     (C) SHA-1 is computed over (B) followed by the input text.
+
+     (D) The key is exclusive-ored with a 64 octet buffer filled with
+     the octet value 0x5C.
+
+     (E) SHA-1 is computed over (D) followed by the output of (C).
+
+
+
+
+Newman                                                         [Page 20]
diff --git a/doc/gssapi.html b/doc/gssapi.html
new file mode 100644 (file)
index 0000000..27aca38
--- /dev/null
@@ -0,0 +1,196 @@
+<HTML><HEAD>
+<title>Configuring GSSAPI and Cyrus SASL</title>
+<!-- $Id: gssapi.html,v 1.4 2003/09/24 18:54:05 rjs3 Exp $ -->
+</HEAD>
+<BODY>
+<h1>Configuring GSSAPI and Cyrus SASL</h1>
+
+<p>This document was contributed by <a
+href="mailto:kenh@cmf.nrl.navy.mil">Ken Hornstein</a> and updated
+by <a href="mailto:Alexey.Melnikov@isode.com">Alexey Melnikov</a>.
+
+<p>A couple of people have asked me privately, "Hey, how did you get the
+GSSAPI mechanism to work?  I tried, but the sample apps kept failing".
+(The short answer: I'm a tenacious bastard).
+
+<p>I figured that it couldn't hurt to give a quick explanation as to
+how you get GSSAPI working with the sample apps, since it wasn't
+obvious to me, and I consider myself not completely ignorant of GSSAPI
+and Kerberos.
+
+<ol>
+<li> Compile the Cyrus-SASL distribution with the GSSAPI plugin
+  for your favorite GSS-API mechanism.  I personally use the GSSAPI
+  libraries included with the <a href="http://web.mit.edu/kerberos/www/">MIT</a>
+  Kerberos 5 distribution; <a href="http://www.pdc.kth.se/heimdal/">Heimdal</a>
+  and <a href="http://www.cybersafe.com/">CyberSafe</a> work as well.
+
+<li> Start up the sample-server.  The command-line used for
+  sample-server needs to specify the GSSAPI service name and the
+  location of the plug-ins; your sample command line might look
+  something like this:
+
+<pre>  ./sample-server -s host -p ../plugins/.libs
+</pre>
+
+on UNIX and like
+
+<pre>  sample-server -s host -p ..\plugins
+</pre>
+
+on Windows.
+
+
+<p> In this example, I am using "host", which already exists on my
+  machine, <i>but</i> only root can read it, so I an running this as root.
+  If you want to use an alternate service name, you will need to
+  create that service in Kerberos, place it in a keytab readable by
+  you, _and_ point your Kerberos library at it.
+
+  Unix: both MIT Kerberos and Heimdal, 
+  use /etc/krb5.keytab on Unix by default, but this can be changed
+  by setting the <tt>KRB5_KTNAME</tt> environment variable; the default
+  for CyberSafe Kerberos is /krb5/v5srvtab for UNIX systems and can be
+  changed by setting the <tt>CSFC5KTNAME</tt> environment variable.
+
+  Windows: the default service key table location for CyberSafe is
+  C:\Program Files\CyberSafe\v5srvtab, unless the
+  CyberSafe registry setting for the KeyTab key is set to an
+  alternate path. MIT Kerberos on Windows uses the keytab filename
+  krb5kt.
+
+<p>  You should get a response similar to:
+
+<pre>  Generating client mechanism list...
+  Sending list of 3 mechanism(s)
+  S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw==
+</pre>
+
+<p>  Note that later on (assuming everything works) you might need to paste
+  in lines that are longer than canonical input processing buffer on your
+  system.  You can get around that by messing around with stty; while
+  the details vary from system to system, on Solaris you can do something
+  like:
+
+<pre>  ( stty -icanon min 1 time 0 ; ./sample-server -s host -p ../plugins/.libs )
+</pre>
+
+<li> Obtain a Kerberos ticket for the user you want to authenticate as.
+
+<pre>  kinit kenh
+</pre>
+
+
+<li> Start up the sample client.  You need to specify the service
+  name, the hostname, and the userid.  An example might be
+
+<pre>  ./sample-client -s host -n your.fqdn.here -u kenh -p ../plugins/.libs
+</pre>
+
+<p>  You should get a response similar to this:
+
+<pre>  Waiting for mechanism list from server...
+</pre>
+
+<li> Cut-and-paste the initial mechanism line from the server process
+  (this <i>includes</i> the "<tt>S: </tt>") into the client process.  You
+  should get something similar to:
+
+<pre>  S: R1NTQVBJIFBMQUlOIEFOT05ZTU9VUw==
+  Choosing best mechanism from: GSSAPI PLAIN ANONYMOUS
+  Using mechanism GSSAPI
+  Preparing initial.
+  Sending initial response...
+  C: <.... lots of base 64 data ...>
+  Waiting for server reply...
+</pre>
+
+<p>  If GSSAPI isn't selected as the mechanism, there is a few things that
+  might have gone wrong:
+
+<ul>
+<li> The mechanism might not have been offered by the server.  The decoded
+     mechanism list offered by the server appears in the "<tt>Choosing best
+     mechanism</tt>" line.  If GSSAPI didn't appear in that list, then
+     something is wrong on the server.  Make sure that you specified the
+     correct plugins directory.  If the plugin directory is correct, but
+     the library fails to load, you <i>might</i> be running across a bug
+     in libtool on some platforms.  If you have your Kerberos/gssapi
+     libraries not installed in the system library path, those libraries
+     are likely not able to be found when the SASL GSSAPI plugin loads.
+     The solution varies from system to system; what I did was take
+     the linker line generated by libtool and run it by hand, adding
+     a <tt>-R/path/to/kerberos/libraries</tt> switch (this was on Solaris).
+     You can check with a system call tracer to see exactly what it is
+     trying to do.
+
+<li> The client doesn't know about the mechanism.  The reasons for this
+     happening are the same as the server: check the -p switch, check
+     to make sure the correct libraries are being loaded with the GSSAPI
+     plugin.
+</ul>
+
+<p>  You can turn on a healthy amount of debugging information by changing
+  the definition in config.h of the VL macro to (and recompiling libsasl):
+
+<pre>  #define VL(foo) printf foo;
+</pre>
+
+<p> There is a possibility
+you might get an error that looks like this:
+
+<pre>  sample-client: Starting SASL negotiation: generic failure
+</pre>
+
+<p>  This can mean that you didn't provide all of the required information
+  to the sample-client (did you provide a service name with -s, the
+  hostname of the service with -n, and a username with -u ?), or that
+  GSSAPI has failed (unfortunately, on the client you cannot find out
+  the internal GSSAPI error; you will need to break out the debugger
+  for that).
+
+<li> Cut and paste the client response (The _entire_ line that begins
+  with C:, <i>including</i> the initial "<tt>C: </tt>") to the server
+  process.  You should get a response back that starts with "<tt>S:
+  </tt>".  Cut and paste <i>that</i> to the client, and continue this
+  exchange until you either get "<tt>Negotiation complete</tt>", or an error.
+  If you get an error on the server you should get a complete error
+  message (including the GSSAPI error string); on the client you
+  unfortunately will only probably get "<tt>generic failure</tt>", which will
+  again require the use of a debugger (but the VL macro should help
+  with this).
+
+<p>  One common thing that happens is that on your server you might see
+  the error:
+
+<pre>  sample-server: Performing SASL negotiation: authentication failure
+       (Requested identity not authenticated identity)
+</pre>
+
+<p>  This comes from not having a requested identity (the -u option) that
+  matches the identity that you were authenticated to via the GSSAPI.
+  This is of course mechanism specific, but if for example you're using
+  Kerberos, the Cyrus SASL library strips out the @REALM from your
+  identity <i>if</i> you are in the same realm as the server.  So if your
+  Kerberos identity is user@SOME.REALM and the server is in SOME.REALM,
+  you need to specify "user" to the -u flag of the client.  If you're
+  accessing a server in a foreign realm, you need to pass the full
+  principal name via the -u option to make this work correctly.
+
+<p>  If you complete the negotiation successfully, you should see something
+  that looks like (on both the client and server):
+
+<pre>  Negotiation complete
+  Username: kenh
+  sample-server: realm: can't request info until later in exchange
+  SSF: 56
+</pre>
+
+<p> If you get to that, then you've done it, and GSSAPI works successfully!
+If you have questions about any of this, feel free to drop me a line.
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
diff --git a/doc/index.html b/doc/index.html
new file mode 100644 (file)
index 0000000..b09a882
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<HTML><head>
+<TITLE>Cyrus SASL library</TITLE>
+</head>
+<body>
+<h1>Cyrus SASL library, version 2</h1>
+
+<p> SASL (Simple Authentication Security Layer) is an Internet
+standards-track method for remote computers to authenticate.  The
+Cyrus SASL library makes supporting various SASL mechanisms easy for
+both client and server writers.
+
+<P>The Cyrus project is the implementation of an enterprise mail
+system by the Carnegie Mellon University Computing Services Department.
+We are interested in scalable, easy to administer systems.
+
+<h2>The Cyrus SASL library distribution</h2>
+
+<p><a href="http://asg.web.cmu.edu/cyrus/download/"><b>Cyrus SASL
+library distribution</B></A>
+
+<h2>Documentation</h2>
+
+<ul>
+<li> <a href="readme.html"><b>Read Me First</b></A></li>
+<li> <a href="install.html"><b>Installation Documentation</b></A></li>
+<li> <a href="upgrading.html"><b>Information for upgrading from SASLv1</b></A></li>
+<li> <a href="appconvert.html"><b>SASLv1 to SASLv2 Application Conversion Guide</B></A></li>
+</ul>
+
+<ul>
+<li> <a href="components.html">A high-level overview of Cyrus SASL Components</a></li>
+<li> <a href="sysadmin.html">The Cyrus SASL for System Administrators</A></li>
+<li> <a href="options.html">Options for use with Cyrus SASL</A></li>
+<li> <a href="programming.html">The SASL Application Programmer's Guide</A></li>
+<li> <a href="plugprog.html">The SASL Plugin Programmer's Guide</A></li>
+<li> <a href="advanced.html">Advanced SASL usage</A></li>
+</ul>
+
+<b>Special Platforms</b>
+<ul>
+<li> <a href="macosx.html"><b>Mac OS X Build Guide</b></a>
+<li> <a href="os390.html"><b>OS/390 Build Guide</b></a>
+<li> <a href="windows.html"><b>Win32 Build Guide</b></a>
+</ul>
+
+<b>RFCs and drafts</b>
+
+<ul>
+<li> <a href="rfc1321.txt">RFC 1321: The MD5 Message-Digest
+Algorithm</a></li>
+<li> <a href="rfc1939.txt">RFC 1939: Post Office Protocol - Version
+3</a> (APOP/sasl_checkapop)</li>
+<li> <a href="rfc2104.txt">RFC 2104: HMAC: Keyed-Hashing for Message
+Authentication</a></li>
+<li> <a href="rfc2195.txt">RFC 2195: IMAP/POP AUTHorize Extention for
+Simple Challenge/Response</a>
+<br>
+<a href="draft-ietf-sasl-crammd5-xx.txt">
+draft-ietf-sasl-crammd5: The CRAM-MD5 SASL Mechanism</a> (CRAM-MD5)</li>
+<li> <a href="rfc2222.txt">RFC 2222: Simple Authentication and
+Security Layer (SASL)</a> (KERBEROS_V4)
+<br>
+<a href="draft-ietf-sasl-rfc2222bis-xx.txt">
+draft-ietf-sasl-rfc2222bis: Simple Authentication and Security Layer
+(SASL)</a> (EXTERNAL)</li>
+<li> <a href="rfc2243.txt">RFC 2243: OTP Extended Responses</a></li>
+<li> <a href="rfc2245.txt">RFC 2245: Anonymous SASL Mechanism</a>
+<br>
+<a href="draft-ietf-sasl-anon-xx.txt">
+draft-ietf-sasl-anon: Anonymous SASL Mechanism</a> (ANONYMOUS)</li>
+<li> <a href="rfc2289.txt">RFC 2289: A One-Time Password System</a></li>
+<li> <a href="rfc2444.txt">RFC 2444: The One-Time-Password SASL
+Mechanism</a> (OTP)</li>
+<li> <a href="rfc2595.txt">RFC 2595: Using TLS with IMAP, POP, and
+ACAP</a>
+<br>
+<a href="draft-ietf-sasl-plain-xx.txt">
+draft-ietf-sasl-plain: Plain SASL Mechanism</a> (PLAIN)</li>
+<li> <a href="rfc2831.txt">RFC 2831: Using Digest Authentication as a
+SASL Mechanism</a>
+<br>
+<a href="draft-ietf-sasl-rfc2831bis-xx.txt">
+ draft-ietf-sasl-rfc2831bis: Using Digest Authentication as a SASL
+ Mechanism</a> (DIGEST-MD5)</li>
+<li> <a href="rfc2945.txt">RFC 2945: The SRP Authentication and Key
+Exchange System</a></li>
+<li> <a href="rfc3174.txt">RFC 3174: US Secure Hash Algorithm 1 (SHA1)</a></li>
+<li> <a href="draft-burdis-cat-srp-sasl-xx.txt">
+draft-burdis-cat-srp-sasl: Secure Remote Password SASL
+Mechanism</a> (SRP)</li>
+<li> <a href="draft-ietf-sasl-gssapi-xx.txt">
+draft-ietf-sasl-gssapi: SASL GSSAPI Mechanisms</a> (GSSAPI)</li>
+<li> <a href="draft-ietf-sasl-saslprep-xx.txt">
+draft-ietf-sasl-saslprep: SASLprep: Stringprep profile for user names and passwords</a></li>
+<li> <a href="draft-murchison-sasl-login-xx.txt">
+draft-murchison-sasl-login: The LOGIN SASL Mechanism</a> (LOGIN) -- <i>obsolete</i></li>
+<li> <a href="draft-newman-sasl-passdss-xx.txt">
+draft-newman-sasl-passdss: DSS Secured Password Authentication Mechanism</a> (PASSDSS-3DES-1)</li>
+<li> <a href="draft-newman-sasl-c-api-xx.txt">
+draft-newman-sasl-c-api: The SASL C API</a> (very rough draft)</li>
+</ul>
+
+<b>Other Documentation & Resources</b>
+<ul>
+<li><a href="http://www.oreillynet.com/pub/a/network/2002/04/09/sasl.html">
+Using SASL: Pluggable Security</a></li>
+<li><a href="http://www.oreillynet.com/pub/a/network/2002/04/30/sasl2.html">
+Using SASL: CMU's Cyrus SASL Library</a></li>
+<li><a href="http://www.melnikov.ca/mel/devel/SASL_info.html">Information on
+SASL mechanisms, profiles, servers and clients implementing SASL.</a></li>
+<li><a href="http://www.sendmail.org/~ca/email/auth.html">FAQ</a> from
+ Sendmail. </li>
+<li><a href="http://www-cs-students.stanford.edu/~tjw/srp/ndss.html">
+The Secure Remote Password Protocol</a> paper by Thomas Wu</li>
+<li><a href="http://beepcore-tcl.sourceforge.net/tclsasl.html">TCL extensions
+for SASL</A></li>
+<li><a href="http://davenport.sourceforge.net/ntlm.html">
+The NTLM Authentication Protocol</a> (NTLM)</li>
+<li><a href="http://www.snia.org/tech_activities/CIFS/CIFS-TR-1p00_FINAL.pdf">
+Common Internet File System (CIFS) Technical Reference</a> (SMB/NTLM)</li>
+</ul>
+
+<p><hr><p>
+<A HREF="http://asg.web.cmu.edu/cyrus">Go</A> to the Project Cyrus Home Page<br>
+<A HREF="http://asg.web.cmu.edu">Go</A> to the Andrew Systems Group homepage.
+</body>
diff --git a/doc/install.html b/doc/install.html
new file mode 100644 (file)
index 0000000..65c0f90
--- /dev/null
@@ -0,0 +1,227 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+                      "http://www.w3.org/TR/html4/loose.dtd"> 
+<html><head>
+<title>Cyrus SASLv2 INSTALL Documentation</title>
+<!-- $Id: install.html,v 1.18 2005/02/16 20:52:05 shadow Exp $ -->
+</head>
+<body>
+<h1>Installation Procedure</h1>
+
+This document offers a general overview of installing the SASL library.
+
+<h2>Quick and Dirty</h2>
+<pre>
+  cd (directory it was untarred into)
+  ./configure
+  make
+  make install
+  ln -s /usr/local/lib/sasl2 /usr/lib/sasl2
+</pre>
+
+<p>If you're checking this directly out of CVS, you'll need to run "sh
+./SMakefile" to build the configure script first.
+
+<p>Read <A HREF="sysadmin.html">the System Administrator's Guide</A> to
+learn how to configure libsasl in depth.  There is also a <A
+HREF="upgrading.html">document</A> that covers migrating from libsasl v1
+to libsasl v2 applications.
+
+<p>You may also be interested in the contents of <tt>configure --help</tt>
+which can reveal the many possible configure options that can be used
+to build Cyrus SASL.
+
+<h3>Details</h3>
+
+<p>Note that the library looks for plugins in <tt>/usr/lib/sasl2</tt>,
+but installs them into <tt>${prefix}/lib/sasl2</tt>, where
+<tt>${prefix}</tt> is usually something like <tt>/usr/local</tt>.
+This is intentional - we want the plugins installed with the rest of
+the package (wherever things get installed at your site), but we want
+the library to <em>always</em> be able to find its plugins under
+<tt>/usr/lib/sasl2</tt>, no matter where you install things, so that
+the SASL plugin ABI on all platforms is roughly the same.
+
+<p>If you don't want to do this for some reason, you can set the location
+where the library will look for plugins by setting the environment
+variable SASL_PATH to the path the library should use.
+
+<h2>Slower and Cleaner</h2>
+
+Before reading this section, please be sure you are comfortable with
+the concepts presented in the <a href=components.html>components discussion</a>
+and in the <a href=readme.html>Read Me First</a> document.<p>
+
+You will want to have answered the following questions about your intended
+installation:<p>
+
+<ol>
+<li>What mechanisms do you want to support?  Are they plaintext (LOGIN, PLAIN),
+shared secret (DIGEST-MD5, CRAM-MD5), or Kerberos (KERBEROS_V4, GSSAPI)?
+Perhaps you will use some combination (generally plaintext with one of
+the other two types).</li>
+<li>Given the answer to the previous question, how will the mechanisms
+perform user verification?
+  <ul>
+  <li>The Kerberos mechanisms just need your existing
+Kerberos infroastructure.</li>
+  <li>The shared secret mechanisms will need an auxprop
+plugin backend.</li>
+  <li>The plaintext mechanisms can make do with saslauthd, Courier authdaemond (not included),
+*or* by using an auxprop plugin backend.</li>
+  <li>To use Kerberos and Plaintext, you'll likely want to use saslauthd
+with a kerberos module for plaintext authentication.  To use Shared Secret
+and plaintext, you'll want to use the auxprop plugin for password verification.
+  </li>
+  </ul></li>
+<li>If you are using an auxprop plugin, will you be using SASLdb (and
+if so, Berkeley DB [recommended], GDBM, or NDBM?), LDAP or an SQL backend
+(Postgres? MySQL?).</li>
+<li>If you are using saslauthd, what module will you be using?  LDAP?
+Kerberos?  PAM?</li>
+<li>Also if you are using saslauthd, what communication (IPC) method do
+you want to use?  On most systems, the correct answer is the default
+(unix sockets), but on Solaris you can use IPC doors, which have proven
+to be more stable than equivilant Solaris systems using unix sockets.</li>
+</ol>
+
+Once you have answered these questions, properly configuring a working
+configuration of Cyrus SASL becomes significantly easier.
+
+<h3>Requirements</h3>
+
+<p>You'll probably need the GNU make program, available as of this
+writing <a href="ftp://ftp.gnu.org/pub/gnu/make/">here</a>.<p>
+
+<p>If you are using SASLdb, you will need to pick your backend.
+libsasl2 can use gdbm, Berkeley db, or ndbm to implement its
+user/password lookup. Most systems come with ndbm these days; as of
+this writing, gdbm is available <a
+href="ftp://ftp.gnu.org/pub/gnu/gdbm/">here</a>.
+Berkeley DB is available from: <a
+href="http://www.sleepycat.com/">Sleepycat</a>
+
+<p>If you are using SQL, you'll need to properly configure your server/tables,
+and build the necessary client libraries on the system where you will be
+building and using SASL.  Currently we support <a href=http://postgresql.org>
+PostgreSQL</a> v7.2 (or higher) and <a href=http://mysql.org>MySQL</a>.
+
+<p>If you are using LDAPDB, you'll need SASL enabled OpenLDAP libraries.  <a
+href="http://www.openldap.org">OpenLDAP</a> 2.1.27 (or higher) or 2.2.6 (or
+higher) is support.</p>
+
+<p>For Kerberos support, you'll need the kerberos libraries.  At CMU, the
+version we use comes from <a href="http://www.pdc.kth.se/kth-krb/">here</a>.
+
+<p>For GSSAPI support you will need either <a href="http://web.mit.edu/kerberos/www/">MIT Kerberos 5</a>
+, the <a href="http://www.pdc.kth.se/heimdal">Heimdal</a> or
+<a href="http://www.cybersafe.com/">CyberSafe</a> implementation.
+
+<h3>Build Configuration</h3>
+
+<p>Once you have ansered all the necessary questions and installed
+(and tested!) any required packages for your configuration, you are
+ready to build SASL.  Building SASL is done with the aid of
+an autoconf <tt>configure</tt> script, which has a <b>lot</b> of options.
+Be sure to read the outpit of <tt>configure --help</tt> to be sure you
+aren't missing any (they are all documented).  Note that often times
+a <tt>--enable-foo</tt> option has a counterpart like <tt>--disable-foo</tt>
+to not enable that feature.
+
+<p>Some of the most important configuration options are those which allow
+you to turn off the comiplation of modules you do not need.  This is often
+the easiest way to solve compilation problems with Cyrus SASL.
+If you're not going to need a particular mechanism, don't build it!  Not
+building them can also add performance improvements as it does take system
+resources to load a given plugin, even if that plugin is otherwise unused
+(even when it is disabled via the <tt>mech_list</tt> <a href=options.html>option</a>).
+
+<p>As of this writing, modules that are enabled by default but may not
+be applicable to all systems include CRAM-MD5, DIGEST-MD5, OTP, KERBEROS_V4,
+GSSAPI, PLAIN, and ANONYMOUS.  These can be disabled with
+<tt>--disable-cram</tt>,
+<tt>--disable-digest</tt>, <tt>--disable-otp</tt>,
+<tt>--disable-krb4</tt>, <tt>--disable-gssapi</tt>,
+<tt>--disable-plain</tt>, and <tt>--disable-anon</tt> respecively.
+
+<p>If you are using an SQL auxprop plugin, you may want to specify one or more
+of <tt>--enable-sql</tt>, <tt>--with-mysql=PATH</tt>, and
+<tt>--with-pgsql=PATH</tt>, note that PATH in the later two should be replaced
+with the path where you installed the necessary client libraries.
+
+<p>If you are using LDAPDB auxprop plugin, you will need to specify
+<tt>--enable-ldapdb</tt> and <tt>--with-ldap=PATH</tt>.  <b>Warning:</b> LDAPDB
+auxprop plugin (and LDAP enabled saslauthd) introduces a circular dependency
+between OpenLDAP and SASL.  I.e., you must have OpenLDAP already built when
+building LDAPDB in SASL.  In order for LDAPDB to work at runtime, you must have
+OpenLDAP already built with SASL support. One way to solve this issue is to
+build Cyrus SASL first without ldap support, then build OpenLDAP, and then come
+back to SASL and build LDAPDB.</p>
+
+<p>Given the myriad of ways that Berkeley DB can be installed on a system,
+people useing it may want to look at the <tt>--with-bdb-libdir</tt> and
+<tt>--with-bdb-incdir</tt> as alternatives to <tt>--with-dbbase</tt> for
+specifying the paths to the Berkeley DB Library and Include directories.
+
+<p>In fact, if you're not planning on using SASLdb at all, it may be worth
+your time to disable its use entirely with the <tt>--with-dblib=none</tt>
+option.
+
+<p>If you are planning on using LDAP with saslauthd, be sure to specify
+the <tt>--with-ldap=PATH</tt> option to <tt>configure</tt>.
+
+<h3>Building and Installation</h3>
+
+After configure runs, you should be able to build SASL just by 
+running <tt>make</tt>.  If this runs into problems, be sure that you
+have disabled everything that your system doesn't need, and that you have
+correctly specified paths to any dependencies you may have.<p>
+
+To install the library, run <tt>make install</tt> as <tt>root</tt> followed by
+<tt>ln -s /usr/local/lib/sasl2 /usr/lib/sasl2</tt> (modified for your
+installation path as appropriate).  Be sure to do this last step or
+SASL will not be able to locate your plugins!
+
+<h3>Compilation Hints</h3>
+
+<p>You may need to play with your CPPFLAGS and LDFLAGS a little if you're
+using vendor compilers. We use <tt>gcc</tt> extensively, but you'll
+probably have more luck if you use the same compiler for the library
+as you do for your applications. You can see what compilers we use on
+our platforms by looking at the "SMakefile".
+
+<h3>Application Configuration</h3>
+
+<p>Plesae read about the <a href=options.html>SASL Options</a> to learn what
+needs to be configured so that applications can successfully use the SASL
+library.  This is also covered in the <a href=readme.html>Read Me First</a>
+document.
+
+<p>You will want to ensure that the settings of <tt>pwcheck_method</tt>
+and <tt>auxprop_plugin</tt> match the decisions you made about your
+authentication infrastructure.  (For example, if you are using
+saslauthd as a password verifier, you'll want to be sure to set
+<tt>pwcheck_method: saslauthd</tt>).
+
+<p>If you are using saslauthd, you will want to arrange for
+<tt>saslauthd -a pam</tt> (or ldap, or kerberos4, etc) to be run
+at boot.  If you are not going to be using saslauthd, then this is
+not necessary.
+
+<p>Many of these pieces are covered in more detail in the
+<a href=sysadmin.html>SASL System Administrator's Guide</a>.
+
+<h2>Supported platforms</h2>
+
+<p>This has been tested under Linux 2.2, Linux 2.4, Solaris 2.7 and
+Solaris 2.8.  It should work under any platform where dynamic objects
+can be linked against other dynamic objects, and where the dynamic
+library file extension is ".so", or where libtool creates the .la
+files correctly.  There is also documentation for
+<a href=windows.html>Win32</a>, <a href=macosx.html>MacOS X</a>, and
+<a href=os390.html>OS/390</a>.
+
+<hr>
+Back to the <a href="index.html">index</a>
+
+</body>
+</html>
diff --git a/doc/macosx.html b/doc/macosx.html
new file mode 100644 (file)
index 0000000..6d87046
--- /dev/null
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+  <title>Building and Using Cyrus SASL on Mac OS X</title>
+<!-- $Id: macosx.html,v 1.6 2003/12/12 00:43:03 rbraun Exp $ -->
+</head>
+<body>
+<h1>Cyrus SASL v2 on Mac OS X (and 9)</h1>
+<p>The Cyrus SASL v2 distribution now supports Mac OS X, including
+applications written to Apple's Carbon and Cocoa interfaces, as well
+as the standard Unix-like API. It includes the following
+components:</p>
+<ul>
+  <li>A port of the Unix SASL library, which lives in <tt>/usr/local/lib/libsasl2.dylib</tt>
+(or something like that) and
+with plugins in <tt>/usr/lib/sasl</tt> (which should be a symlink to <tt>/usr/local/lib/sasl</tt>).
+  </li>
+  <li>A framework which lives in
+<tt>/Library/Frameworks/SASL2.framework</tt>, and allows the use of the
+<tt>-framework</tt> option to Apple's <tt>ld</tt>, or linking with the
+framework in Project Builder. This framework is in fact a wrapper for a
+symlink to <tt>/usr/local/lib/libsasl2.dylib</tt> with the necessary
+information to recognize it as a framework. This is what we expect many
+Cocoa and Carbon Mach-O applications will want to use, and the framework
+is required for CFBundle to work, which is used by the CFM glue library.
+</li>
+  <li>A CFM glue library (<tt>/Library/CFMSupport/SASL2GlueCFM</tt>) which
+can be linked in by Carbon CFM applications, that uses CFBundle to bind
+the framework and thus load the Unix-level library. It automatically loads
+the important functions at <tt>sasl_client_init</tt> or
+<tt>sasl_server_init</tt> time; it also automatically makes sure memory
+allocation works if you're using the metrowerks malloc; if you're not,
+<tt>sasl_set_alloc</tt> works as usual. </li>
+  <li>A Carbon port of the existing CFM library for Mac OS 9. Note that
+this could probably be modified fairly easily to work on OS X, but
+there's not much point. The CFM glue layer to the Unix library
+supports many more functions, including the entire server API; also,
+the Unix implementation is mostly independent of Kerberos
+implementation, while the Mac OS 9 Carbon port specifically requires
+MIT Kerberos for Macintosh 3.5 or later in order to get Kerberos
+support. The Mac OS 9 code implements only the client API, but this is
+mostly what is wanted from SASL on OS 9 anyway. </li>
+</ul>
+<p>If you are building a Carbon CFM application and intend it to run on
+both OS 9 and OS X, you should link against the OS 9 Carbon SASL
+library, since it exports fewer APIs (client side only, specifically)
+than the OS X CFM glue. Your application should work seamlessly with
+both libraries if you do this, despite the different implementations
+underneath.</p>
+<p>If you need a Carbon CFM application to support server-side SASL
+functionality, you need to link against the <tt>SASL2GlueCFM</tt>
+library, but be aware that your application will not run on OS 9.</p>
+<h2>Compiling and Using the Unix library</h2>
+
+The Unix library is mostly ready to build on Mac OS X, but it does depend
+on the <tt>dlcompat</tt> package in order to load its plugins.
+<tt>dlcompat-20010505</tt> is a relatively simple version known to work
+with SASL; it is provided with the distribution in a tarball. You should
+<tt>make</tt> and <tt>make install</tt> the <tt>dlcompat</tt> library
+(which probably goes into <tt>/usr/local/lib/libdl.dylib</tt>) before
+attempting to <tt>./configure</tt> the SASL distribution itself. SASL will
+then pretend it's a real Unix <tt>libdl</tt>, and link against it. 
+
+<p>Since there are, at this point, newer and far more complex versions of
+dlcompat, you may prefer to use those instead if other software requires
+their functionality. The dlcompat homepage is located <a
+href="http://www.opendarwin.org/projects/dlcompat/">on the OpenDarwin
+site.</a> Many users may want to install the <tt>/sw</tt> tree from <a
+href="http://fink.sourceforge.net/">the Fink project</a> to get this, as
+well as possibly newer autotools and other software.<br> </p>
+
+<p>As of version 2.1.16, SASL uses and requires a recent version of GNU
+autotools (autoconf, automake, and libtool) to build its configuration scripts.
+If you are building from CVS, you will need to have the autotools installed
+on your system. The version included with all releases of the developer tools
+for OS X 10.2.x is too old for this; if you aren't using OS X 10.3 or later,
+you should upgrade to more recent patchlevels of these tools. The easiest way
+to do this is to <a href="http://fink.sourceforge.net/">install the Fink
+environment</a> and then <tt>apt-get
+install autoconf2.5 automake1.7 libtool14</tt>.<br>
+</p>
+<p>Recent versions of SASL ship with Kerberos v4 disabled by default.
+If you need Kerberos v4 for some reason, and you are using MIT Kerberos
+for Macintosh 4.0 or later, you should <tt>./configure</tt> with
+the added options <tt>"--enable-krb4=/usr --without-openssl
+--disable-digest"</tt> so that it finds the
+correct location for the header files, and does not use OpenSSL or
+build anything that depends on it (such as the digest-md5 plugin),
+since OpenSSL provides its own DES routines which do not work with
+Kerberos v4. <i>Please read the "Known Problems" section at the end of
+this
+document for more information on this issue.<br>
+</i></p>
+<p>You must be root to make install, since <tt>/usr/local</tt> is only
+modifiable by root. You need not enable the root account using
+NetInfo; the recommended (but underdocumented) method is to use
+<tt>sudo -s</tt> from the Terminal window when you are logged into an
+administrator's account, and enter the password for that account. When
+building on Mac OS X, <tt>make install</tt> will automatically add the
+framework to <tt>/Library/Frameworks</tt>.</p>
+<p>This does not build the CFM glue library. Building the CFM glue
+library requires Metrowerks CodeWarrior Pro 6 or later (tested with
+6), and the files necessary to build it are in the
+<tt>mac/osx_cfm_glue</tt> folder.</p>
+<h2>Changes to the Unix library to make it work on OS X</h2>
+<p>This is provided for reference purposes only. The build system will
+automatically take care of all of these issues when building on Darwin
+or Mac OS X.</p>
+<ul>
+  <li>The random code supports the preferred way to generate random
+numbers in Darwin. (In SASL v2, it does this on all unix-like
+platforms that lack jrand48). <i>Note that Mac OS X "Jaguar", version
+10.2,
+now has the standard jrand48 function, and that SASL will use this
+instead
+of the previous workaround.</i> </li>
+  <li>Symbols which are dlopened have an underscore prefixed. (This
+behavior is detected by configure in SASL v2.) </li>
+  <li>Plugins are linked with the <tt>-module</tt> option to <tt>libtool</tt>,
+which causes the <tt>-bundle</tt> option to be
+supplied to Apple's <tt>ld</tt>. (This is done on all platforms in
+SASL v2.) </li>
+  <li>The MD5 symbols are renamed to avoid library conflicts. This
+allows proper compilations against Heimdal and MIT's unix kerberos
+distribution, and prevents crashes when linked against MIT Kerberos
+for Macintosh (which also duplicates the symbols, but in a different
+way). Note that the MD5 symbols have local names on all platforms with
+SASL v2; this was only different in SASL v1. </li>
+  <li>MIT Kerberos for Macintosh 4.0 and later are fully supported. This
+was accomplished by using <tt>krb_get_err_text</tt> if available and
+checking for additional names for the krb4 libraries. </li> </ul>
+<h2>Changes to the Mac OS 9 projects to support Carbon</h2>
+<p><b><i>Please read these notes before you attempt to build SASL for OS 9
+Carbon!</i></b> </p> <ul>
+  <li><b>Important!</b> You must make sure that all files have their
+correct HFS filetype before starting to build this code! In
+particular, all source and text files must be of type <tt>'TEXT'</tt>,
+which is not the default if you use the Mac OS X cvs client to check
+out the projects. If you run into this problem, you may want to use a
+utility such as FileTyper to recursively change the type on all
+files. CodeWarrior is less picky about the projects' filetypes, but
+setting them to filetype <tt>'MMPr'</tt>, creator code <tt>'CWIE'</tt>
+may be helpful in opening the projects from the Finder. Users on Mac OS
+X familiar with the Unix <tt>find</tt>
+command should be able to rig <tt>/Developer/Tools/SetFile</tt>
+to do this job as well. </li>
+  <li>Many of the important projects (for <tt>libdes</tt>, <tt>libsasl</tt>,
+    <tt>build_plugins</tt>, and the sample client <tt>sc_shlb</tt>)
+have Carbon versions. </li>
+  <li>Plugins are loaded from a <tt>Carbon</tt> subfolder of the <tt>SASL
+v2</tt> folder in the Extensions folder. Plugins directly
+in
+the <tt>SASL v2</tt> folder are considered to be for the Classic
+libraries. </li>
+  <li>Note that when using the <tt>build_plugins</tt> project, you must
+generate the plugin init files using the <tt>makeinit.sh</tt> script in
+the <tt>plugins</tt> directory. The easiest way to do this is to run the
+script from a Unix shell, such as Mac OS X. You must then fix the
+filetypes of the generated source files (see above). </li>
+  <li>There is a new folder in <tt>CommonKClient</tt> called <tt>mac_kclient3</tt>
+which contains code compatible with MIT's new <a
+ href="http://web.mit.edu/macdev/Development/MITKerberos/MITKerberosLib/KClient/Documentation/index.html">KClient
+3.0</a> API. This folder must be in your CodeWarrior access paths, the
+old <tt>mac_kclient</tt> folder must not, and it must precede the
+project's main folder. </li>
+  <li>The kerberos4 plugin uses this new code. The kerberos4 plugin
+also
+statically links the Carbon <tt>libdes</tt>, and no other part of
+Carbon SASL uses <tt>libdes</tt> directly. <i>Your application should
+    <b>not</b> link against</i> <tt>libdes.shlb</tt> <i>under Carbon!</i>
+(It causes problems due to DES symbols also existing in the MIT
+Kerberos library, which loads first.) </li>
+  <li>To build the projects, you should have the MIT Kerberos for
+Macintosh 3.5 installation disk images mounted, since the access paths
+include the absolute paths to the library directories from that
+image. It's easier than you having to find the paths yourself, and
+smaller than having to distribute the libraries with SASL. </li>
+</ul>
+<h2>Known Problems</h2>
+<ul>
+  <li>The Kerberos v4 headers bundled with Mac OS X (and Kerberos for
+Macintosh) are not compatible with OS X's OpenSSL headers. (Kerberos v4
+support is disabled by default.) If you actually need krb4 support, the
+easiest solution is to build without using OpenSSL's
+<tt>libcrypto</tt>. To do this, specify the <tt>--without-openssl</tt>
+option to <tt>configure</tt>. As of version 2.1.18, this automatically
+disables using <tt>libcrypto</tt> for DES as well. You will probably
+also need to specify <tt>--disable-digest</tt> since the digestmd5 plugin
+does not build against Kerberos v4's DES headers or library. Note that
+this disables several features (digestmd5, NTLM, OTP) which require
+OpenSSL. If both Kerberos v4 and functionality that requires OpenSSL are
+needed, it is probably possible to build the Kerberos v4 plugin against
+the correct K4 DES libraries, and everything else against OpenSSL;
+however, we do not support that configuration.<br>
+  </li>
+  <li>Versions of Cyrus SASL prior to 2.1.14 with support for Carbon
+CFM applications on Mac OS X have a known bug involving the CFM glue
+code (in <tt>mac/osx_cfm_glue</tt>). If <tt>sasl_done</tt> is called
+to unload the SASL library, and then one of the initialization
+functions (such as <tt>sasl_client_init</tt>) is called to
+reinitialize it from the same process, the application will crash. A
+fix for one obvious cause of this problem is included in 2.1.14;
+however, as of this writing, it has not been tested. It is possible
+that other bugs in Cyrus SASL, or deficiencies in Apple's libraries,
+will make this fix insufficient to resolve this issue. </li>
+</ul>
+</body>
+</html>
diff --git a/doc/mechanisms.html b/doc/mechanisms.html
new file mode 100644 (file)
index 0000000..5ae7f5c
--- /dev/null
@@ -0,0 +1,268 @@
+<!-- $Id: mechanisms.html,v 1.6 2003/09/16 23:57:37 ken3 Exp $ -->
+<HTML>
+<HEAD>
+<TITLE>SASL Mechanism Properties/Features</TITLE>
+</HEAD>
+<BODY>
+<h2>SASL Mechanism Properties/Features</h2>
+
+This table shows what security flags and features are supported by each
+of the mechanisms provided by the Cyrus SASL Library.<p>
+
+<TABLE BORDER=1 CELLSPACING=1 CELLPADDING=2>
+
+<TR>
+<TH ROWSPAN=2><br></TH>
+<TH ROWSPAN=2>MAX<br>SSF</TH>
+<TH COLSPAN=7>SECURITY PROPERTIES</TH>
+<TH COLSPAN=4>FEATURES</TH>
+</TR>
+
+<TR>
+<TH><CENTER>NOPLAIN</CENTER></TH>
+<TH><CENTER>NOACTIVE</CENTER></TH>
+<TH><CENTER>NODICT</CENTER></TH>
+<TH><CENTER>FORWARD</CENTER></TH>
+<TH><CENTER>NOANON</CENTER></TH>
+<TH><CENTER>CRED</CENTER></TH>
+<TH><CENTER>MUTUAL</CENTER></TH>
+<TH><CENTER>CLT FIRST</CENTER></TH>
+<TH><CENTER>SRV FIRST</CENTER></TH>
+<TH><CENTER>SRV LAST</CENTER></TH>
+<TH><CENTER>PROXY</CENTER></TH>
+</TR>
+
+<TR>
+<TH>ANONYMOUS</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+</TR>
+
+<TR>
+<TH>CRAM-MD5</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+</TR>
+
+<TR>
+<TH>DIGEST-MD5</TH>
+<TD><CENTER>128</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>reauth</CENTER></TD>
+<TD><CENTER>initial auth</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>EXTERNAL</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>GSSAPI</TH>
+<TD><CENTER>56</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>KERBEROS_V4</TH>
+<TD><CENTER>56</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>LOGIN</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+</TR>
+
+<TR>
+<TH>NTLM</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+</TR>
+
+<TR>
+<TH>OTP</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>PLAIN</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+<!--
+<TR>
+<TH>SECURID</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+<TR>
+<TH>SKEY</TH>
+<TD><CENTER>0</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+</TR>
+-->
+<TR>
+<TH>SRP</TH>
+<TD><CENTER>128</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER><br></CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+<TD><CENTER>X</CENTER></TD>
+</TR>
+
+</TABLE>
+
+<h3>Understanding this table:</h3>
+<ul>
+<li><b>MAX SSF</b> - The maximum Security Strength Factor supported
+by the mechanism (roughly the number of bits of encryption provided, but may
+have other meanings, for example an SSF of 1 indicates integrity protection
+only, no encryption).</li>
+<li><b>NOPLAIN</b> - Mechanism is not susceptable to simple passive
+(eavesdropping) attack.</li>
+<li><b>NOACTIVE</b> - Protection from active (non-dictionary) attacks
+during authentication exchange.  (Implies <b>MUTUAL</b>).</li>
+<li><b>NODICT</b> - Not susceptable to passive dictionary attack.</li>
+<li><b>NOFORWARD</b> - Breaking one session won't help break the next.</li>
+<li><b>NOANON</b> - Don't permit anonymous logins.</li>
+<li><b>CRED</b> - Mechanism can pass client credentials.</li>
+<li><b>MUTUAL</b> - Supports mutual authentication (authenticates the server
+to the client)</li>
+<li><b>CLTFIRST</b> - The client should send first in this mechanism.</li>
+<li><b>SRVFIRST</b> - The server must send first in this mechanism.</li>
+<li><b>SRVLAST</b> - This mechanism supports server-send-last configurations.</li>
+<li><b>PROXY</b> - This mechanism supports proxy authentication.</li>
+</ul>
+
+</BODY>
+</HTML>
diff --git a/doc/options.html b/doc/options.html
new file mode 100644 (file)
index 0000000..b38bcef
--- /dev/null
@@ -0,0 +1,340 @@
+<HTML><HEAD>
+<title>Options for Cyrus SASL</title>
+<!-- $Id: options.html,v 1.30 2005/02/16 20:52:05 shadow Exp $ -->
+</HEAD>
+<BODY>
+<h1>Options for Cyrus SASL</h1>
+
+<p>This document contains information on what options are used by the
+Cyrus SASL library and bundled mechanisms.  The most commonly used
+options (and those that are therefore most commonly misunderstood
+are <b>pwcheck_method</b> and <b>auxprop_plugin</b>.  Please ensure
+that you have configured these correctly if things don't seem to
+be working right.  Additionally, <b>mech_list</b> can be an easy
+way to limit what mechanisms a given application will use.</p>
+
+<TABLE BORDER WIDTH=95%>
+<TR><TH>Option</TH><TH>Used By</TH><TH>Description</TH><TH>Default</TH></TR>
+<TR>
+<TD>authdaemond_path</TD><TD>SASL Library</TD> 
+<TD>Path to Courier-IMAP authdaemond's unix socket.
+Only applicable when pwcheck_method is set to authdaemond.</TD><TD>/dev/null</TD>
+</TR>
+<TR>
+<TD>auto_transition</TD><TD>SASL Library</TD> 
+<TD>When set to 'yes' or 'noplain',
+and when using an auxprop plugin, automatically transition
+users to other mechs when they do a successful plaintext
+authentication.  When set to 'noplain', only non-plaintext secrets 
+will be written.  <I>Note that the only mechs (as currently
+implemented) which don't use plaintext secrets are
+OTP and SRP.</I></TD><TD>no</TD>
+</TR>
+<TR>
+<TD>auxprop_plugin</TD><TD>Auxiliary Property Plugin</TD>
+<TD>Name of auxiliary plugin to use, you may specify a space-separated
+list of plugin names, and the plugins will be queried in order</TD>
+<TD>(null) - querys all plugins</TD>
+</TR>
+<TR>
+<TD>canon_user_plugin</TD><TD>SASL Library</TD>
+<TD>Name of canon_user plugin to use</TD><TD>INTERNAL</TD>
+</TR>
+<TR>
+<TD>keytab</TD><TD>GSSAPI</TD> <TD>Location of keytab
+file</TD><TD><tt>/etc/krb5.keytab</tt> (system dependant)</TD>
+</TR>
+<TR>
+<TD>ldapdb_uri</TD><TD>LDAPDB plugin</TD>
+<TD>ldap server uri, you can specify a space-separated list of URIs - 
+ldapi:// or ldaps://ldap1/ ldaps://ldap2/</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>ldapdb_id</TD><TD>LDAPDB plugin</TD>
+<TD>ldap SASL authentication id</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>ldapdb_mech</TD><TD>LDAPDB plugin</TD>
+<TD>ldap SASL mechanism for authentication</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>ldapdb_pw</TD><TD>LDAPDB plugin</TD>
+<TD>ldap password for SASL authentication id</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>ldapdb_rc</TD><TD>LDAPDB plugin</TD>
+<TD>The filename specified here will be put into the server's LDAPRC
+environment variable, and libldap-specific config options may be set
+in that ldaprc file.  The main purpose behind this option is to allow
+a client TLS certificate to be configured, so that SASL/EXTERNAL may
+be used between the SASL server and the LDAP server. This is the most
+optimal way to use this plugin when the servers are on separate machines.</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>ldapdb_starttls</TD><TD>LDAPDB plugin</TD>
+<TD>Use StartTLS.  This option may be set to 'try' or 'demand'.  
+When set to "try" any failure in StartTLS is ignored. 
+When set to "demand" then any failure aborts the connection.</TD>
+<TD>none</TD>
+</TR>
+<TR>
+<TD>log_level</TD><TD>SASL Library</TD>
+<TD><b>Numeric</b> Logging Level (see <TT>SASL_LOG_*</TT> in <tt>sasl.h</tt>
+for values and descriptions</TD>
+<TD>1 (SASL_LOG_ERR)</TD>
+</TR>
+<TR>
+<TD>mech_list</TD><TD>SASL Library</TD>
+<TD>Whitespace separated list of mechanisms to allow (e.g. 'plain
+otp').  Used to restrict the mechanisms to a subset of the installed
+plugins.</TD><TD>(use all available plugins)</TD>
+</TR>
+<TR>
+<TD>ntlm_server</TD><TD>NTLM (server)</TD>
+<TD>Name of server (WinNT, Win2K, Samba, etc) to which authentication
+will be proxied.</TD>
+<TD>(null) - perform authentication internally</TD>
+</TR>
+<TR>
+<TD>ntlm_v2</TD><TD>NTLM (client)</TD>
+<TD>Send NTLMv2 responses to the server.</TD>
+<TD>no (send NTLMv1)</TD>
+</TR>
+<TR>
+<TD>opiekeys</TD><TD>OTP (with OPIE)</TD>
+<TD>Location of the opiekeys file</TD><TD><tt>/etc/opiekeys</tt></TD>
+</TR>
+<TR>
+<TD>otp_mda</TD><TD>OTP (w/o OPIE)</TD>
+<TD>Message digest algorithm for one-time passwords, used by sasl_setpass
+(possible values: 'md4', 'md5', 'sha1')</TD><TD><tt>md5</tt></TD>
+</TR>
+<TR>
+<TD>plugin_list</TD><TD>SASL Library</TD>
+<TD>Location of Plugin list (Unsupported)</TD><TD><i>none</i></TD>
+</TR>
+<TR>
+<TD>pwcheck_method</TD><TD>SASL Library</TD>
+<TD>Whitespace separated list of mechanisms used to verify passwords,
+used by sasl_checkpass (possible values: 'auxprop', 'saslauthd',
+'pwcheck', 'authdaemond' [if compiled with <tt>--with-authdaemond</tt>])
+and 'alwaystrue' [if compiled with <tt>--enable-alwaystrue</tt>])
+</TD><TD>auxprop</TD>
+</TR>
+<TR>
+<TD>reauth_timeout</TD><TD>DIGEST-MD5</TD>
+<TD>Length in time (in minutes) that authentication info will be
+cached for a fast reauth.  A value of 0 will disable reauth.</TD>
+<TD>0</TD>
+</TR>
+<TR>
+<TD>saslauthd_path</TD><TD>SASL Library</TD>
+<TD>Path to saslauthd run directory (<b>including</b> the "/mux" named pipe)</TD>
+<TD>system dependant (generally won't need to be changed)</TD>
+</TR>
+<TR>
+<TD>sasldb_path</TD><TD>sasldb plugin</TD>
+<TD>Path to sasldb file</TD><TD><tt>/etc/sasldb2</tt> (system dependant)</TD>
+<TR>
+<TD>sql_engine</TD><TD>SQL plugin</TD>
+<TD>Name of SQL engine to use (possible values: 'mysql', 'pgsql', 'sqlite').</TD>
+<TD><tt>mysql</tt></TD>
+</TR>
+<TR>
+<TD>sql_hostnames</TD><TD>SQL plugin</TD>
+<TD>Comma separated list of SQL servers (in host[:port] format).</TD>
+<TD><i>none</i> (engine dependent)</TD>
+</TR>
+<TR>
+<TD>sql_user</TD><TD>SQL plugin</TD>
+<TD>Username to use for authentication to the SQL server.</TD>
+<TD><i>none</i> (engine dependent)</TD>
+</TR>
+<TR>
+<TD>sql_passwd</TD><TD>SQL plugin</TD>
+<TD>Password to use for authentication to the SQL server.</TD>
+<TD><i>none</i> (engine dependent)</TD>
+</TR>
+<TR>
+<TD>sql_database</TD><TD>SQL plugin</TD>
+<TD>Name of the database which contains the auxiliary properties.</TD>
+<TD><i>none</i> (engine dependent)</TD>
+</TR>
+<TR>
+<TD>sql_select</TD><TD>SQL plugin</TD>
+<TD>SELECT statement to use for fetching properties.  This option is
+<b>required</b> in order to use the SQL plugin.</TD>
+<TD><i>none</i></TD>
+</TR>
+<TR>
+<TD>sql_insert</TD><TD>SQL plugin</TD>
+<TD>INSERT statement to use for creating properties for new users.</TD>
+<TD><i>none</i></TD>
+</TR>
+<TR>
+<TD>sql_update</TD><TD>SQL plugin</TD>
+<TD>UPDATE statement to use for modifying properties.</TD>
+<TD><i>none</i></TD>
+</TR>
+<TR>
+<TD>sql_usessl</TD><TD>SQL plugin</TD>
+<TD>When set to 'yes', 'on', '1' or 'true', a secure connection will
+be made to the SQL server.</TD>
+<TD><tt>no</tt></TD>
+</TR>
+<TR>
+<TD>srp_mda</TD><TD>SRP</TD>
+<TD>Message digest algorithm for SRP calculations
+(possible values: 'md5', 'sha1', 'rmd160')</TD><TD><tt>sha1</tt></TD>
+</TR>
+<TR>
+<TD>srvtab</TD><TD>KERBEROS_V4</TD>
+<TD>Location of the srvtab file</TD><TD><tt>/etc/srvtab</tt> (system
+dependant)</TD>
+</TR>
+</TABLE>
+
+<h2>Notes on SQL auxprop options</h2>
+
+<p>The <tt>sql_insert</tt> and <tt>sql_update</tt> options are
+optional and are only needed if you wish to allow the SASL library
+(e.g., saslpasswd2) and plugins (e.g., OTP) to write properties to the
+SQL server.  If used, both statements MUST be provided so that
+properties can be added, changed and deleted.
+<font color=red>NOTE: The columns for writable properites MUST accept NULL values.</font>
+
+<p>The SQL statements provided in the <tt>sql_select</tt>,
+<tt>sql_insert</tt> and <tt>sql_update</tt> options can contain
+arguments which will be substituted with the appropriate values.  The
+valid arguments are:
+
+<DL compact>
+<DT><tt>%u</tt> <DD>Username whose properties are being fetched/stored.
+
+<DT><tt>%p</tt> <DD>Name of the property being fetched/stored.  This could
+     technically be anything, but SASL authentication will try
+     userPassword and cmusaslsecretMECHNAME (where MECHNAME is the
+     name of a SASL mechanism).
+
+<DT><tt>%r</tt> <DD>Realm to which the user belongs.  This could be the
+     kerberos realm, the FQDN of the computer the SASL application is
+     running on or whatever is after the @ on a username.  (read the
+     realm documentation).
+
+<DT><tt>%v</tt> <DD>Value of the property being stored (INSERT or
+     UPDATE only!). This could technically be anything depending on
+     the property itself, but is generally a userPassword.
+</DL>
+
+<font color=red>NOTE: DO NOT put quotes around the entire SQL
+statement, but each individual %u, %r and %v argument MUST be
+quoted.</font>
+
+
+<h3>Examples:</h3>
+
+<pre>
+     <tt>sql_select: SELECT %p FROM user_table WHERE username = '%u' and realm = '%r'</tt>
+</pre>
+
+     would send the following statement to SQL for user "bovik" and
+     the default realm for the machine "madoka.surf.org.uk":
+
+<pre>
+     <tt>SELECT userPassword FROM user_table WHERE username = 'bovik' and
+     realm = 'madoka.surf.org.uk';</tt>
+
+
+</pre>
+
+<pre>
+     <tt>sql_insert: INSERT INTO user_table (username, realm, %p) VALUES ('%u', '%r', '%v')</tt>
+
+</pre>
+
+   would generate the following statement to SQL for user "bovik" in
+   realm "madoka.surf.org.uk" with userPassword "wert":
+
+<pre>
+     <tt>INSERT INTO user_table (username, realm, userPassword) VALUES
+     ('bovik', 'madoka.surf.org.uk', 'wert');</tt>
+
+
+</pre>
+
+<p>Note that all substitutions do not have to be used. For instance,
+<pre>
+     <tt>SELECT password FROM auth WHERE username = '%u'</tt>
+</pre>
+is a valid value for <tt>sql_select</tt>.
+
+<h2>Notes on LDAPDB auxprop options</h2>
+
+<p>
+</p>
+
+<p>Unlike other LDAP-enabled plugins for other services that are common
+on the web, this plugin does not require you to configure DN search
+patterns to map usernames to LDAP DNs. This plugin requires SASL name
+mapping to be configured on the target slapd. This approach keeps the
+LDAP-specific configuration details in one place, the slapd.conf, and
+makes the configuration of remote services much simpler.</p>
+
+<p>This plugin is not for use with slapd itself. When OpenLDAP is
+built with SASL support, slapd uses its own internal auxprop module.
+By default, without configuring anything else, slapd will fail to load
+the ldapdb module when it's present. This is as it should be. If you
+don't like the "auxpropfunc: error -7" message that is sent to syslog
+by slapd, you can stop it by creating /usr/lib/sasl2/slapd.conf with:
+
+    <pre>auxprop_plugin: slapd</pre>
+
+which will force the SASL library to ignore all other auxprop modules.</p>
+
+<h3>Examples:</h3>
+
+<pre>
+ldapdb_uri: ldap://ldap.example.com
+ldapdb_id: root
+ldapdb_pw: secret
+ldapdb_mech: DIGEST-MD5
+</pre>
+
+<p>The LDAP server must be configured to map the SASL authcId "root" into a DN
+that has proxy authorization privileges to every account that is allowed to
+login to this server. (See the OpenLDAP Admin Guide section 10 for
+details.)</p>
+
+<pre>
+ldapdb_uri: ldapi://
+ldapdb_mech: EXTERNAL
+</pre>
+
+<p>This configuration assumes an LDAP server is on the same server that is
+using SASL and the underlying OS is *NIX based (ldapi:// requires UNIX domain
+sockets).  This is fast and secure, and needs no username or password to be
+stored.  The slapd.conf will need to map these usernames to LDAP DNs:
+
+<pre>
+sasl-regexp uidNumber=(.*)\\+gidNumber=(.*),cn=peercred,cn=external,cn=auth
+    ldap:///dc=example,dc=com??sub?(&(uidNumber=$1)(gidNumber=$2))
+</pre>
+
+<pre>
+sasl-regexp uid=(.*),cn=external,cn=auth
+    ldap:///dc=example,dc=com??sub?(uid=$1)
+</pre>
+
+</p>
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
+
diff --git a/doc/plugprog.html b/doc/plugprog.html
new file mode 100644 (file)
index 0000000..274195e
--- /dev/null
@@ -0,0 +1,300 @@
+<HTML><HEAD>
+<title>SASL Plugin Programmer's Guide</title>
+<!-- $Id: plugprog.html,v 1.5 2002/05/07 15:13:45 ken3 Exp $ -->
+</HEAD>
+<BODY>
+<h1>SASL Plugin Programmer's Guide</h1>
+
+<h3>NOTE: This is a work in progress. Any contributions would be
+<i>very</i> appreciated</h3>
+
+<ul><h2>Contents</h2>
+  <li><a href="#intro">Introduction</a></li>
+  <ul>
+    <li><a href="#about_this_guide">About this Guide</A></li>
+    <li><a href="#about_sasl">What is SASL</A></li>
+  </ul>
+  <li><a href="#common">Common Section</a></li>
+  <ul>
+    <li><a href="#overview">Overview of Plugin Programming</a></li>
+    <li><a href="#sasl_utils_t">Use of sasl_utils_t</a></li>
+    <li><a href="#error_reporting">Error Reporting</a></li>
+    <li><a href="#memory">Memory Allocation</a></li>
+    <li><a href="#cslssl">Client Send First / Server Send Last</a></li>
+  </ul>
+  <li><a href="#client">Client Plugins</a></li>
+  <li><a href="#server">Server Plugins</a></li>
+  <li><a href="#canon_user">User Canonicalization (canon_user) Plugins</a></li>
+  <li><a href="#auxprop">Auxiliary Property (auxprop) Plugins</a></li>
+</ul>
+
+<a name="intro"><h2>Introduction</h2></a>
+
+    <a name="about_this_guide"><h3>About this Guide</h3></a>
+
+    <p>This guide gives a <i>very</i> brief overview on the things that one
+       needs to know to write a mechanism for the SASLv2 API (and thus
+       Cyrus SASLv2).  Note that this page is a brief overview <i>only</i>
+       and that the authoritative documentation are the header files
+       included in the SASL distribution.  If you have any questions, please
+       feel free to contact the Cyrus development team at
+       <a href="mailto:cyrus-bugs@andrew.cmu.edu"><i>cyrus-bugs@andrew.cmu.edu
+       </i></a> or the cyrus-sasl mailing list at
+       <a href="mailto:cyrus-sasl@andrew.cmu.edu"><i>cyrus-sasl@andrew.cmu.edu
+       </i></a>.</p>
+
+    <p>Please note that this guide is only intended for developers looking
+       to write mechanisms for the SASLv2 API, and that application programmers
+       should be reading <a href="programming.html">this document</a> instead.
+    </p>
+   
+    <a name="about_sasl"><h3>What is SASL?</h3></a>
+    <p>A description of SASL is covered in detail in the
+      <a href="programming.html">programmer's guide</a>, which mechanism
+      developers should probably read first anyway to become familiar
+      with development using the SASL library.
+    </p>
+    
+<a name="common"><h2>Common Section</h2></a>
+    <a name="overview"><h3>Overview of Plugin Programming</h3></a>
+
+    <p>The basic idea behind programming plugins for Cyrus SASL rests in
+       the ability to dlopen a shared library.  Thus, all plugins should
+       be shared libraries.  It is recommended that they are libtool
+       libraries for portability reasons (Cyrus SASL parses .la files to
+       get the appropriate name to dlopen), but they can have an extention
+       of .so as well.</p>
+    <p>All plugins should live in the same directory
+       (generally /usr/lib/sasl2), which the glue code (that is, the interface
+       layer that sits between the plugins and the application) scans
+       when one of the init functions (sasl_server_init or sasl_client_init)
+       is called.  Cyrus SASL then attempts to open each library and
+       run an initialization function.  If the initialization function
+       succeeds, and the versions match, then the glue code determines
+       that the load was successful and the plugin is available for use.</p>
+    <p>There are serveral types of plugins (note that a given plugin library
+       may contain any or all of the following in combination, though
+       such a plugin would be a beast!):</p>
+    <ul>
+      <li><b>Mechanism Plugins</b> - These plugins implement mechanisms
+       for authentication, and are the majority of the plugins included
+       with Cyrus SASL.  Generally implementing both a client and a server
+       side they take care of the authentication process.</li>
+      <li><b>User Canonicalization Plugins</b> - These plugins enable differing
+       ways of canonicalizing authentication and authorization IDs.</li>
+      <li><b>Auxiliary Property Plugins</b> - These plugins allow auxilliary
+       properties about user accounts to be looked up, such as passwords.
+       Cyrus SASL includes a plugin to read sasldb files, for example.</li>
+    </ul>
+      
+    <a name="sasl_utils_t"><h3>Use of sasl_utils_t</h3></a>
+
+    <p>Because of the way that shared library plugins are loaded for both
+       speed and namespace reasons, the symbol tables are not shared across
+       plugins.  Thus, the only interface that the plugin should assume it
+       has to the outside world is through the <tt>sasl_utils_t</tt> structure (or
+       through links that it specifically requires).  Likewise, the glue code
+       has no (and will use no) interface into the plugin other than the
+       contents of the structures that are passed back to it by the
+       initialization function.</p>
+    <p>This should be stressed again: do not assume you have access to any
+       functions except through links that your library explicitly makes
+       or through what is provided via the <tt>sasl_utils_t</tt> structure.</p>
+
+    <a name="error_reporting"><h3>Error Reporting</h3></a>
+    <p>Error reporting is very important for failed authentication tracking
+       and helping to debug installations or authentication problems.  For
+       that reason, in addition to the standard SASL return codes, the
+       glue code provides an interface to its seterror function (via
+       <tt>sasl_utils_t</tt>).  This function sets detailed error information for
+       a given connection.</p>
+    <p><i>In order to ensure consistency of this information, it is the
+       responsibility of the deepest function with access to the sasl_conn_t
+       make the call to set the errdetail string.</i></p>
+
+    <a name="memory"><h3>Memory Allocation</h3></a>
+    <p>Memory allocation in SASLv2 follows the simple paradigm that if you
+      allocate it, you free it.  This improves portability, and allows
+      for a large performance improvement over SASLv1.  To prevent memory
+      leaks (especially in the mechanism plugins), please ensure that you
+      follow this paradigm.</p>
+
+    <a name="cslssl"><h3>Client Send First / Server Send Last</h3></a>
+    <p>Mechanism plugins used to have to worry about the situation
+      where they needed clients to send first (or server to send last), yet
+      the protocol did not support it.  Luckily, this is now handled by
+      the glue code, provided that the plugin declares the appropriate flags
+      in the structure returned by its init function.  Thus, the step functions
+      will not have to worry about these issues and can be implemented
+      knowing they will be called only when the application actually has
+      data for them and/or will allow them to send data.  These flags are as
+      follows:</p>
+    <ul>
+      <li><B>SASL_FEAT_WANT_CLIENT_FIRST</B>: The mechanism has the client
+       side send first always.  (e.g. PLAIN)</li>
+      <li><B>SASL_FEAT_SERVER_FIRST</B>: The mechanism has the server side
+       send first always.  (e.g. CRAM-MD5)</li>
+    </ul>
+
+<p>If neither flag is set, the mechanism will handle the client-send
+first situation internally, because the client may or may not send
+first.  (e.g. DIGEST-MD5).  In this case, the plugin must
+intelligently check for the presence (or absence) of clientin/serverin
+data.  Note that the optional client send-first is only possible when the
+protocol permits an initial response.
+
+<p>The server send last situation is handled by the plugin intelligently
+setting *serverout when the step function returns SASL_OK.  For mechanisms
+which never send last (e.g. PLAIN), *serverout must be set to NULL.  For
+mechanisms which always send last (e.g. DIGEST-MD5), *serverout must
+point to the success data.  For mechanisms in which the server may or
+may not send last (e.g. SRP), *serverout must be set accordingly.
+
+<a name="client"><h2>Client Plugins</h2></a>
+    <p>Client-side mechanism plugins are generally included in the same
+       plugin with their <a href="#server">server</a> counterpart, though
+       this is not a requirement.  They take care of the client-side of the
+       SASL negotiation.  For a simple example, see the ANONYMOUS plugin.</p>
+    <p>Client plugins must export <tt>sasl_client_plug_init</tt> which returns
+       a <tt>sasl_client_plug_t</tt> in order to load.  The structure has
+       several functional members and a global context (which applies to
+       all connections using the plugin).  The important ones are described
+       briefly here.</p>
+    <ul>
+      <li><b>mech_new</b> - Called at the beginning of each connection,
+       (on a call to sasl_client_start),
+       mech_new does mechanism-specific initialization, and if necessary
+       allocates a connection context (which the glue code keeps track
+       of for it).  mech_new does not actually send any data to the client,
+        it simply allocates the context.</li>
+      <li><b>mech_step</b> - Called from <tt>sasl_client_start</tt> and
+       <tt>sasl_client_step</tt>, this function does the actual work of
+       the client
+       side of the authentication.  If authentication is successful, it
+       should return SASL_OK, otherwise it should return a valid SASL
+       error code (and call seterror).  This should also set up the
+        oparams structure before returning SASL_OK, including any
+        security layer information (in the way of callbacks).  Note
+        that as soon as the client has both the authentication and
+        authorization IDs, it MUST call the canon_user function provided
+        in its params structure (for both the authentication and
+       authorization IDs, with SASL_CU_AUTHID and SASL_CU_AUTHZID
+        respectively).</li>
+      <li><b>mech_dispose</b> - Called to dispose of a connection context.
+       This is only called when the connection will no longer be used
+        (e.g. when <tt>sasl_dispose</tt> is called)</li>
+      <li><b>mech_free</b> - Called when the sasl library is shutting down
+       (by <tt>sasl_done</tt>).
+       Intended to free any global state of the plugin.</li>
+    </ul>
+<a name="server"><h2>Server Plugins</h2></a>
+    <p>Server-side mechanism plugins are generally included in the same
+       plugin with their <a href="#client">client</a> counterpart, though
+       this is not a requirement.  They take care of the server-side of the
+       SASL negotiation, and are generally more complicated than their
+       client-side counterparts.  For a simple example, see the ANONYMOUS
+       plugin.</p>
+    <p>Server plugins must export <tt>sasl_server_plug_init</tt> which returns
+       a <tt>sasl_server_plug_t</tt> in order to load.  The structure has
+       several functional members and a global context (which applies to
+       all connections using the plugin).  The important ones are described
+       briefly here.</p>
+    <ul>
+      <li><b>mech_new</b> - Called at the beginning of each connection,
+       (on a call to sasl_client_start),
+       mech_new does mechanism-specific initialization, and if necessary
+       allocates a connection context (which the glue code keeps track
+       of for it).  mech_new does not actually send any data to the client,
+        it simply allocates the context.</li>
+      <li><b>mech_step</b> - Called from <tt>sasl_server_start</tt> and
+       <tt>sasl_server_step</tt>, this function does the actual work of
+       the server
+       side of the authentication.  If authentication is successful, it
+       should return SASL_OK, otherwise it should return a valid SASL
+       error code (and call seterror).  This should also set up the
+        oparams structure before returning SASL_OK, including any
+        security layer information (in the way of callbacks and SSF
+       information).  Also, as soon
+        as the mechanism has computed both the authentication and the
+        authorization IDs, it MUST call the canon_user function provided
+        in the server params structure (for both the authentication and
+       authorization IDs, with SASL_CU_AUTHID and SASL_CU_AUTHZID
+        respectively).  This action will also fill in its
+        propctx, so any auxiliary property <i>requests</i>
+        (for example, to lookup
+        the password) should be done before the request to canonicalize
+        the authentication id.  Authorization ID lookups do not occur until
+        after the plugin returns success to the SASL library.<p>
+
+        Before returning SASL_OK, <tt>mech_step</tt> must fill in the
+        oparams fields for which it is responsible, that is, <tt>doneflag</tt>
+        (set to 1 to indicate a complete exchange), <tt>maxoutbuf</tt>, or
+        the maximum output size it can do at once for a security layer,
+        <tt>mech_ssf</tt> or the supplied SSF of the security layer,
+        and <tt>encode</tt>, <tt>decode</tt>, <tt>encode_context</tt>,
+       and <tt>decode_context</tt>,
+        which are what the glue code will call on calls to <tt>sasl_encode</tt>,
+       <tt>sasl_encodev</tt>, and <tt>sasl_decode</tt>.</li>
+      <li><b>mech_dispose</b> - Called to dispose of a connection context.
+       This is only called when the connection will no longer be used
+        (e.g. when <tt>sasl_dispose</tt> is called)</li>
+      <li><b>mech_free</b> - Called when the sasl library is shutting down
+       (by <tt>sasl_done</tt>).
+       Intended to free any global state of the plugin.</li>
+      <li><b>setpass</b> - Called to set a user's password.  This allows
+       mechanisms to support their own internal password or secret
+       database.</li>
+      <li><b>mech_avail</b> - Called by the first call to
+       <tt>sasl_listmech</tt>,
+       it checks to see if the mechanism is available for the given
+       user, and MAY allocate a connection context (thus avoiding
+       a call to <tt>mech_new</tt>).  However it should not do this
+       without significant performance benefit as it forces the glue
+       code to keep track of extra contexts that may not be used.</li>
+    </ul>
+<a name="canon_user"><h2>User Canonicalization (canon_user) Plugins</h2></a>
+    <p>User Canonicalization plugins allow for nonstandard ways of
+       canonicalizing the username.  They are subject to the following
+       requirements:</p>
+    <ul>
+      <li>They must copy their output into the provided output buffers.</li>
+      <li>The output buffers may be the same as the input buffers.</li>
+      <li>They must function for the case which is only an authentication
+         ID (flags == SASL_CU_AUTHID) or only an authorization ID
+         (flags == SASL_CU_AUTHZID) or both
+         (flags == SASL_CU_AUTHID | SASL_CU_AUTHZID)
+    </ul>
+    <p>User canonicalization plugins must export a <tt>sasl_canonuser_init</tt>
+       function which returns a <tt>sasl_canonuser_plug_t</tt> in order
+       to load successfully.  They must implement at least one of
+       the <tt>canon_user_client</tt> or <tt>canon_user_server</tt> members
+       of the <tt>sasl_canonuser_plug_t</tt>.  The INTERNAL canon_user plugin
+       that is inside of the glue code implements both in the same way.</p>
+<a name="auxprop"><h2>Auxiliary Property (auxprop) Plugins</h2></a>
+    <p>Perhaps the most exciting addition in SASLv2, Auxprop plugins
+       allow for an easy way to perform password and secret lookups (as well
+       as other information needed for authentication and authorization)
+       from directory services, and in the same request allow the application
+       to receive properties that it needs to provide the service.
+    </p>
+    <p>Auxprop plugins need to export the <tt>sasl_auxprop_init</tt> function
+       and pass back a <tt>sasl_auxprop_plug_t</tt> in order to load
+       successfully.  The sasldb plugin included with the Cyrus SASL
+       distribution would be a good place to start.</p>
+    <p>Interfacing with property contexts is extremely well documented in
+       <tt>prop.h</tt> and so that is omitted here.  The only important
+       note is to be sure that you are using the interfaces provided
+       through the <tt>sasl_utils_t</tt> structure and not calling
+       the functions directly.</p>
+    <p>To successfully implement an auxprop plugin there is only one
+       required function to implement, that is the <tt>auxprop_lookup</tt>
+       member of the <tt>sasl_auxprop_plug_t</tt>.  This is called
+       just after canonicalization of the username, with the canonicalized
+       username.  It can then do whatever lookups are necessary for any
+       of the requested auxiliary properties.</p>
+</p>
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
diff --git a/doc/programming.html b/doc/programming.html
new file mode 100644 (file)
index 0000000..e6b0ac4
--- /dev/null
@@ -0,0 +1,1231 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<meta name="generator" content="HTML Tidy, see www.w3.org">
+<title>SASL Application Programmer's Guide</title>
+</head>
+<body>
+<h1>SASL Application Programmer's Guide</h1>
+
+<h3>NOTE: This is a work in progress. Any contributions would be
+<i>very</i> appreciated</h3>
+
+<h2>Contents</h2>
+
+<ul>
+<li><a href="#intro">Introduction</a> 
+
+<ul>
+<li><a href="#about_this_guide">About this guide</a></li>
+
+<li><a href="#what_is_sasl">What is SASL?</a></li>
+</ul>
+</li>
+
+<li><a href="#background">Background</a> 
+
+<ul>
+<li><a href="#world_before">How did the world work before
+SASL?</a></li>
+
+<li><a href="#sasl_rescue">SASL to the rescue!</a></li>
+</ul>
+</li>
+
+<li><a href="#briefly">Briefly</a> 
+
+<ul>
+<li><a href="#what_good_for">What is the Cyrus SASL library good
+for?</a></li>
+
+<li><a href="#what_do">What does the Cyrus SASL library
+do?</a></li>
+
+<li><a href="#what_doesnt">What doesn't the Cyrus SASL library
+do?</a></li>
+</ul>
+</li>
+
+<li><a href="#client_only">Client-only Section</a> 
+
+<ul>
+<li><a href="#client_typical">A typical interaction from the
+client's perspective</a></li>
+
+<li><a href="#client_code">How does this look in code?</a></li>
+
+<li><a href="#sasl_client_init">sasl_client_init</a></li>
+
+<li><a href="#sasl_client_new">sasl_client_new</a></li>
+
+<li><a href="#sasl_client_start">sasl_client_start</a></li>
+
+<li><a href="#sasl_client_step">sasl_client_step</a></li>
+</ul>
+</li>
+
+<li><a href="#server_section">Server-only Section</a> 
+
+<ul>
+<li><a href="#server_typical">A typical interaction from the
+server's perspective</a></li>
+
+<li><a href="#server_code">How does this look in code?</a></li>
+
+<li><a href="#sasl_server_init">sasl_server_init</a></li>
+
+<li><a href="#sasl_server_new">sasl_server_new</a></li>
+
+<li><a href="#sasl_server_start">sasl_server_start</a></li>
+
+<li><a href="#sasl_server_step">sasl_server_step</a></li>
+
+<li><a href="#sasl_listmech">sasl_listmech</a></li>
+
+<li><a href="#sasl_checkpass">sasl_checkpass</a></li>
+</ul>
+</li>
+
+<li><a href="#common_section">Common Section</a> 
+
+<ul>
+<li><a href="#callbacks_interactions">Callbacks and
+Interaction</a></li>
+
+<li><a href="#layers">Security layers</a></li>
+</ul>
+</li>
+
+<li><a href="#example_section">Example applications that come with
+the Cyrus SASL library</a> 
+
+<ul>
+<li><a href="#sample_client"><tt>sample-client</tt> and
+<tt>sample-server</tt></a></li>
+
+<li><a href="#cyrus_imapd">Cyrus imapd v2.1.0 or later</a></li>
+
+<li><a href="#imtest"><tt>imtest</tt>, from cyrus imapd 2.1.0 or
+later</a></li>
+</ul>
+</li>
+
+<li><a href="#random_things">Miscellaneous Information</a> 
+
+<ul>
+<li><a href="#empty_exchanges">Empty exchanges</a></li>
+</ul>
+</li>
+</ul>
+
+<h2><a name="intro">Introduction</a></h2>
+
+<h3><a name="about_this_guide">About this Guide</a></h3>
+
+<p>This guide gives a tutorial on the use of the Cyrus SASL library
+for a client or server application. It complies with versions
+including and after 2.0.0. The following pages should only be
+considered a guide, not the final word on programming with the
+Cyrus SASL library. Consult the header files in the distribution in
+the case of ambiguities.</p>
+
+<h3><a name="what_is_sasl">What is SASL?</a></h3>
+
+<p>SASL stands for Simple Authentication Security Layer and is
+explained in <a href="http://ftp.ietf.org/rfc/rfc2222.txt">RFC
+2222</a>. That document is very difficult to understand however and
+it should be unnecessary to consult it.</p>
+
+<h2><a name="background">Background</a></h2>
+
+<h3><a name="world_before">How did the world work before
+SASL?</a></h3>
+
+<p>Before SASL, when a new protocol was written which required
+authentication (users proving who they are to an entity), the
+protocol had to allow explicitly for each individual authentication
+mechanism. There had to be a distinct way to say "I want to log in
+with Kerberos V4". There had to be another distinct way to say "I
+want to log in with CRAM-MD5". There had to be yet a different way
+to say "I want to log in anonymously," and so on. This was
+non-ideal for both the protocol and application writers.</p>
+
+<p>Additionally, many programmers were not very familiar with
+security, so the protocol did support many mechanisms, or worse,
+they were supported incorrectly. Moreover, when a new
+authentication method was invented the protocol needed to be
+modified to support that mechanism.</p>
+
+<p>This system also was not ideal for application writer. She had
+to have a special case for each mechanism she wished her
+application to support. Also, the mechanisms were difficult to
+implement. Even with a good library, an understanding of how the
+mechanism worked was still necessary. Finally if an application
+used more than one protocol (for example a mail client might use
+IMAP, POP, and SMTP) then "Kerberos V4 for IMAP", "Kerberos V4 for
+POP", "Kerberos V4 for SMTP", "CRAM MD5 for IMAP", "CRAM-MD5 for
+POP", etc... would need to be written. This could quickly create a
+huge number of different mechanism-protocol pairs to implement.</p>
+
+<h3><a name="sasl_rescue">SASL to the rescue!</a></h3>
+
+<p>SASL hopefully solves all these problems. In practice it makes
+many of them easier to deal with.</p>
+
+<p>Protocol designers simply have to support SASL (in particular
+RFC 2222). Consequently, any mechanism that supports SASL (just
+about anything you would want to use does now) is supported by the
+protocol. If a new authentication mechanism is invented the
+protocol automatically supports it without any modifications.</p>
+
+<p>Application writers, instead of having to support every
+mechanism for every protocol, only need to support SASL for every
+protocol. Application writers do not need to understand the
+authentication mechanisms at all: the SASL library handles all
+that. Also with the Cyrus SASL library if a new mechanism is
+invented you do not have rewrite your application at all. You may
+not even have to restart your application if it is a long running
+process. This is because the Cyrus SASL library loads each
+mechanism from a shared library. Simply copying a shared library
+into a directory will magically make your application support a new
+mechanism.</p>
+
+<p>Cyrus SASL version 2 supports a much improved API over version
+1, that allows for much smarter and faster memory allocation for
+the mechanisms as well as the applications. It is also provides for
+several new types of plugins to allow for greater overall
+flexibility. Unfortunately, though similar, this new API is
+completely incompatible with the old API, and applications will
+need to be rewritten.</p>
+
+<h2><a name="briefly">Briefly</a></h2>
+
+<h3><a name="what_good_for">What is the Cyrus SASL library good
+for?</a></h3>
+
+<p>The Cyrus SASL library is good for applications that wish to use
+protocols that support SASL authentication. An non-exhaustive list
+of these are: IMAP, SMTP, ACAP, and LDAP. Also if you are making a
+proprietary system and wish to support authentication it is a good
+way of supporting many different authentication types.</p>
+
+<h3><a name="what_do">What does the Cyrus SASL library do?</a></h3>
+
+<p>From a client point of view, the Cyrus SASL library, given a
+list of mechanisms the server supports it will decide the best
+mechanism to use and tell you what to send to the server at each
+step of the authentication. From a server perspective, it handles
+authentication requests from clients.</p>
+
+<h3><a name="what_doesnt">What doesn't the Cyrus SASL library
+do?</a></h3>
+
+<p>The Cyrus SASL library is neither network nor protocol aware. It
+is up to the application to send the data over the wire as well as
+to send the data in the protocol specific manner. With IMAP this
+means putting it in the form: <tt>+ [base64'ed data]\r\n</tt>. LDAP
+just sends data in binary via bind requests. The Cyrus SASL library
+has utility base64 encode and decode routines to help with
+this.</p>
+
+<h2><a name="client_section">Client-only Section</a></h2>
+
+<h3><a name="client_typical">A typical interaction from the
+client's perspective</a></h3>
+
+<ol>
+<li>A client makes a few calls (explained later) to initialize
+SASL.</li>
+
+<li>Every time the client application makes a new connection it
+should make a new context that is kept for the life of the
+connection.</li>
+
+<li>Ask the server for the list of supported mechanisms</li>
+
+<li>Feed this list to the library</li>
+
+<li>Start the authentication with the mechanism the library
+chose</li>
+
+<li>The server will return some bytes</li>
+
+<li>Give these to the library</li>
+
+<li>The library returns some bytes to the application</li>
+
+<li>Application sends these bytes over the network</li>
+
+<li>repeat the last 4 steps until the server tells you that the
+authentication is completed</li>
+</ol>
+
+<h3><a name="client_code">How does this look in code</a></h3>
+
+<b>Initialize the library</b>. (done once). 
+
+<pre>
+    
+        int result;
+
+        /* attempt to start sasl 
+         * See the section on Callbacks and Interactions for an 
+         * explanation of the variable callbacks
+         */ 
+
+        result=sasl_client_init(callbacks);
+            
+            /* check to see if that worked */
+            if (result!=SASL_OK) [failure]
+    
+</pre>
+
+<b>For every network connection, make a new SASL connection</b>: 
+
+<pre>
+       
+            /* The SASL context kept for the life of the connection */
+            sasl_conn_t *conn;
+
+            /* client new connection */
+            result=sasl_client_new("imap",     /* The service we are using */
+                       serverFQDN, /* The fully qualified domain
+                                                  name of the server we're
+                                                  connecting to */
+                       NULL, NULL, /* Local and remote IP
+                                                  address strings
+                                                  (NULL disables mechanisms
+                                                   which require this info)*/
+                                   NULL,       /* connection-specific
+                                                  callbacks */
+                       0,          /* security flags */
+                       &amp;conn);     /* allocated on success */
+
+            /* check to see if that worked */
+            if (result!=SASL_OK) [failure]
+
+     
+</pre>
+
+Next get the list of SASL mechanisms the server supports. This is
+usually done through a capability command. Format the list as a
+single string separated by spaces. Feed this string into SASL to
+begin the authentication process. 
+
+<pre>
+       
+            sasl_interact_t *client_interact=NULL;
+            const char *out, *mechusing;
+            unsigned outlen;
+
+            do {
+
+              result=sasl_client_start(conn,      /* the same context from
+                                                     above */ 
+                                       mechlist,  /* the list of mechanisms
+                                                     from the server */
+                                       &amp;client_interact, /* filled in if an
+                                                            interaction is needed */
+                       &amp;out,      /* filled in on success */
+                                       &amp;outlen,   /* filled in on success */
+                       &amp;mechusing);
+
+              if (result==SASL_INTERACT)
+              {
+                 [deal with the interactions. See interactions section below]
+              }
+
+
+           } while (result==SASL_INTERACT); /* the mechanism may ask us to fill
+                                               in things many times. result is 
+                                               SASL_CONTINUE on success */
+           if (result!=SASL_CONTINUE) [failure]
+
+       
+</pre>
+
+Note that you do not need to worry about the allocation and freeing
+of the output buffer out. This is all handled inside of the
+mechanism. It is important to note, however, that the output buffer
+is not valid after the next call to <tt>sasl_client_start</tt> or
+<tt>sasl_client_step</tt>.
+
+<p>If this is successful send the protocol specific command to
+start the authentication process. This may or may not allow for
+initial data to be sent (see the documentation of the protocol to
+see).</p>
+
+<pre>
+        For IMAP this might look like:
+          {tag} "AUTHENTICATE" {mechusing}\r\n
+          A01 AUTHENTICATE KERBEROS_V4\r\n
+           
+        SMTP looks like:
+         "AUTH" {mechusing}[ {out base64 encoded}]
+         AUTH DIGEST-MD5 GHGJJGDDFDKHGHJG=
+       
+</pre>
+
+<br>
+ <a name="client_authentication_step"><b>Check Results</b></a> <br>
+ Next, read what the server sent back. It can be one of three
+things: 
+
+<ol>
+<li>Authentication failure. Authentication process is halted. This
+might look like <tt>A01 NO Authentication failure</tt> in IMAP or
+<tt>501 Failed</tt> in SMTP. Either retry the authentication or
+abort.</li>
+
+<li>Authentication success. We're now successfully authenticated.
+This might look like <tt>A01 OK Authenticated successful</tt> in
+IMAP or <tt>235 Authentication successful</tt> in SMTP. Go <a href=
+"#client_authentication_success">here</a></li>
+
+<li>Another step in the authentication process is necessary. This
+might look like <tt>+ HGHDS1HAFJ=</tt> in IMAP or <tt>334
+PENCeUxFREJoU0NnbmhNWitOMjNGNndAZWx3b29kLmlubm9zb2Z0LmNvbT4=</tt>
+in SMTP. Note it could be an empty string such as <tt>+ \r\n</tt>
+in IMAP.</li>
+</ol>
+
+Convert the continuation data to binary format (for example, this
+may include base64 decoding it). Perform another step in the
+authentication. 
+
+<pre>
+              do {
+                result=sasl_client_step(conn,  /* our context */
+                        in,    /* the data from the server */
+                        inlen, /* it's length */
+                        &amp;client_interact,  /* this should be
+                                                              unallocated and NULL */
+                        &amp;out,     /* filled in on success */
+                        &amp;outlen); /* filled in on success */
+
+                if (result==SASL_INTERACT)
+                {
+                   [deal with the interactions. See below]
+                }
+
+
+              } while (result==SASL_INTERACT || result == SASL_CONTINUE);
+
+              if (result!=SASL_OK) [failure]
+              
+         
+</pre>
+
+Format the output (variable out of length outlen) in the protocol
+specific manner and send it across the network to the server. <br>
+ Goto <a href="#client_authentication_step">here</a> (this process
+repeats until authentication either succeeds or fails. <br>
+<br>
+<br>
+ <a name="client_authentication_success"><b>Authentication
+Successful</b></a><br>
+<br>
+
+<p>Before we're done we need to call sasl_client_step() one more
+time to make sure the server isn't trying to fool us. Some
+protocols include data along with the last step. If so this data
+should be used here. If not use a length of zero.</p>
+
+<pre>
+                result=sasl_client_step(conn,  /* our context */
+                        in,    /* the data from the server */
+                        inlen, /* it's length */
+                        &amp;client_interact,  /* this should be unallocated and NULL */
+                        &amp;out,     /* filled in on success */
+                        &amp;outlen); /* filled in on success */
+
+                if (result!=SASL_OK) [failure]
+       
+</pre>
+
+<p>Congratulations. You have successfully authenticated to the
+server.</p>
+
+<p>Don't throw away the SASL connection object (sasl_conn_t *) yet
+though. If a security layer was negotiated you will need it to
+encode and decode the data sent over the network.</p>
+
+<br>
+ When you are finally done with connection to server, dispose of
+SASL connection. 
+
+<pre>
+      
+               sasl_dispose(&amp;conn);
+
+         
+</pre>
+
+If you are done with SASL forever (application quiting for
+example): 
+
+<pre>
+            sasl_done();         
+     
+</pre>
+
+<h3>sasl_client_init</h3>
+
+<pre>
+    int sasl_client_init(const sasl_callback_t *callbacks);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>callbacks - List of callbacks. See Callbacks section</li>
+</ul>
+
+This function initializes the SASL library. This must be called
+before any other SASL calls. See the callbacks section for complete
+description of callbacks. 
+
+<h3>sasl_client_new</h3>
+
+<pre>
+    int sasl_client_new(const char *service,
+                const char *serverFQDN,
+                        const char *iplocalport,
+                        const char *ipremoteport,
+                const sasl_callback_t *prompt_supp,
+                unsigned secflags,
+                sasl_conn_t **pconn);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>service - the service name being used. This usually is the
+protocol name (e.g. "ldap")</li>
+
+<li>serverFQDN - Fully qualified domain name of server</li>
+
+<li>iplocalport and ipremoteport - a string of the format
+"a.b.c.d;p" detailing the local or remote IP and port, or NULL
+(which will disable mechanisms that require this information)</li>
+
+<li>prompt_supp - List off callbacks specific to this
+connection</li>
+
+<li>secflags - security flags ORed together requested (e.g.
+SASL_SEC_NOPLAINTEXT)</li>
+
+<li>pconn - the SASL connection object allocated upon success</li>
+</ul>
+
+This function creates a new SASL connection object. It should be
+called once for every connection you want to authenticate for. 
+
+<h3>sasl_client_start</h3>
+
+<pre>
+    int sasl_client_start(sasl_conn_t *conn,
+                  const char *mechlist,
+              sasl_interact_t **prompt_need,
+              const char **clientout,
+              unsigned *clientoutlen,
+              const char **mech);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - the SASL connection object gotten from
+sasl_client_new()</li>
+
+<li>mechlist - the list of mechanisms to try (separated by
+spaces)</li>
+
+<li>prompt_need - filled in when a SASL_INTERACT is returned</li>
+
+<li>clientout - filled in upon success with data to send to
+server</li>
+
+<li>clientoutlen - length of that data</li>
+
+<li>mech - filled in with mechanism being used</li>
+</ul>
+
+This function starts an authentication session. It takes a list of
+possible mechanisms (usually gotten from the server through a
+capability command) and chooses the "best" mechanism to try. Upon
+success clientout points at data to send to the server. 
+
+<h3>sasl_client_step</h3>
+
+<pre>
+    int sasl_client_step(sasl_conn_t *conn,
+         const char *serverin,
+         unsigned serverinlen,
+         sasl_interact_t **prompt_need,
+         const char **clientout,
+         unsigned *clientoutlen);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - the SASL connection object gotten from
+sasl_client_new()</li>
+
+<li>serverin - data from the server</li>
+
+<li>serverinlen - length of data from the server</li>
+
+<li>prompt_need - filled in with a SASL_INTERACT is returned</li>
+
+<li>clientout - filled in upon success with data to send to
+server</li>
+
+<li>clientoutlen - length of that data</li>
+</ul>
+
+This step preforms a step in the authentication process. It takes
+the data from the server (serverin) and outputs data to send to the
+server (clientout) upon success. SASL_CONTINUE is returned if
+another step in the authentication process is necessary. SASL_OK is
+returned if we're all done. 
+
+<h2><a name="server_section">Server-only Section</a></h2>
+
+<h3><a name="server_typical">A typical interaction from the
+server's perspective</a></h3>
+
+The server makes a few Cyrus SASL calls for initialization. When it
+gets a new connection it should make a new context for that
+connection immediately. The client may then request a list of
+mechanisms the server supports. The client also may request to
+authenticate at some point. The client will specify the mechanism
+it wishes to use. The server should negotiate this authentication
+and keep around the context afterwards for encoding and decoding
+the layers. 
+
+<h3><a name="server_code">How does this look in code?</a></h3>
+
+Initialization (done once). The application name is used for
+reading configuration information. 
+
+<pre>
+    
+    int result;
+
+    /* Initialize SASL */
+    result=sasl_server_init(callbacks,      /* Callbacks supported */
+                            "TestServer");  /* Name of the application */
+
+   
+</pre>
+
+This should be called for each new connection. It probably should
+be called right when the socket is accepted. 
+
+<pre>
+    sasl_conn_t *conn;
+    int result;
+
+    /* Make a new context for this connection */
+    result=sasl_server_new("smtp", /* Registered name of service */
+                   NULL, /* my fully qualified domain name; 
+                        NULL says use gethostname() */
+                           NULL, /* The user realm used for password
+                        lookups; NULL means default to serverFQDN
+                                    Note: This does not affect Kerberos */
+                       NULL, NULL, /* IP Address information strings */
+                   NULL, /* Callbacks supported only for this connection */
+                       0, /* security flags (security layers are enabled
+                               * using security properties, separately)
+               &amp;conn);
+
+   
+</pre>
+
+When a client requests the list of mechanisms supported by the
+server. This particular call might produce the string: <i>"{PLAIN,
+KERBEROS_V4, CRAM-MD5, DIGEST-MD5}"</i> 
+
+<pre>
+    result=sasl_listmech(conn,  /* The context for this connection */
+             NULL,  /* not supported */
+             "{",   /* What to prepend the string with */
+             ", ",  /* What to separate mechanisms with */
+             "}",   /* What to append to the string */
+             &amp;result_string, /* The produced string. */
+                         &amp;string_length, /* length of the string */
+                         &amp;number_of_mechanisms); /* Number of mechanisms in
+                                                the string */
+    
+   
+</pre>
+
+When a client requests to authenticate: 
+
+<pre>
+    int result;
+    const char *out;
+    unsigned outlen;
+
+    result=sasl_server_start(conn, /* context */
+                             mechanism_client_chose,
+                             clientin,    /* the optional string the client gave us */
+                             clientinlen, /* and it's length */
+                             &amp;out, /* The output of the library.
+                                      Might not be NULL terminated */
+                             &amp;outlen);
+
+    if ((result!=SASL_OK) &amp;&amp; (result!=SASL_CONTINUE))
+      [failure. Send protocol specific message that says authentication failed]
+    else if (result==SASL_OK)
+      [authentication succeeded. Send client the protocol specific message 
+       to say that authentication is complete]
+    else 
+      [send data 'out' with length 'outlen' over the network in protocol
+       specific format]
+   
+</pre>
+
+When a response is returned by the client. <i>clientin</i> is the
+data from the client decoded from protocol specific format to a
+string of bytes of length <i>clientinlen</i>. This step may occur
+zero or more times. An application must be able to deal with it
+occurring an arbitrary number of times. 
+
+<pre>
+    int result;
+   
+    result=sasl_server_step(conn,
+                            clientin,      /* what the client gave */
+                            clientinlen,   /* it's length */
+                            &amp;out,          /* allocated by library on success. 
+                                              Might not be NULL terminated */
+                            &amp;outlen);
+
+    if ((result!=SASL_OK) &amp;&amp; (result!=SASL_CONTINUE))
+      [failure. Send protocol specific message that says authentication failed]
+    else if (result==SASL_OK)
+      [authentication succeeded. Send client the protocol specific message 
+       to say that authentication is complete]
+    else 
+      [send data 'out' with length 'outlen' over the network in protocol
+       specific format]
+   
+</pre>
+
+This continues until authentication succeeds. When the connection
+is concluded, make a call to <tt>sasl_dispose</tt> as with the
+client connection. 
+
+<h3><a name="sasl_server_init">sasl_server_init</a></h3>
+
+<pre>
+    int sasl_server_init(const sasl_callback_t *callbacks,
+                         const char *appname);
+</pre>
+
+Parameters: 
+
+<ul>
+<li>callbacks - A list of callbacks supported by the application
+(see Interaction and Callbacks section)</li>
+
+<li>appname - A string of the name of the application. This string
+is what is used when loading configuration options.</li>
+</ul>
+
+sasl_server_init() initializes the session. This should be the
+first function called. In this function the shared library
+authentication mechanisms are loaded. 
+
+<h3><a name="sasl_server_new">sasl_server_new</a></h3>
+
+<pre>
+    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 secflags,
+            sasl_conn_t **pconn);
+</pre>
+
+Parameters: 
+
+<ul>
+<li>service - The name of the service you are supporting. This
+might be "acap" or "smtp". This is used by Kerberos mechanisms and
+possibly other mechanisms. It is also used for PAM
+authentication.</li>
+
+<li>serverFQDN - This is the fully qualified domain name of the
+server (i.e. your hostname); if NULL, the library calls
+<tt>gethostbyname()</tt>.</li>
+
+<li>user_realm - The realm the connected client is in. The Kerberos
+mechanisms ignore this parameter and default to the local Kerberos
+realm. A value of NULL makes the library default, usually to the
+serverFQDN; a value of "" specifies that the client should specify
+the realm; this also changes the semantics of "@" in a username for
+mechanisms that don't support realms.</li>
+
+<li>iplocalport and ipremoteport - a string of the format
+"a.b.c.d;p" detailing the local or remote IP and port, or NULL
+(which will disable mechanisms that require this information)</li>
+
+<li>callbacks - Additional callbacks that you wish only to apply to
+this connection.</li>
+
+<li>secflags - security flags.</li>
+
+<li>pconn - Context. Filled in on success.</li>
+</ul>
+
+<h3><a name="sasl_server_start">sasl_server_start</a></h3>
+
+<pre>
+     int sasl_server_start(sasl_conn_t *conn,
+               const char *mech,
+               const char *clientin,
+               unsigned clientinlen,
+               const char **serverout,
+               unsigned *serveroutlen);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - The context for the connection</li>
+
+<li>mech - The authentication mechanism the client wishes to try
+(e.g. <tt>KERBEROS_V4</tt>)</li>
+
+<li>clientin - Initial client challenge bytes. Note: some protocols
+do not allow this. If this is the case passing NULL is valid</li>
+
+<li>clientinlen - The length of the challenge. 0 is there is
+none.</li>
+
+<li>serverout - allocated and filled in by the function. These are
+the bytes that should be encoded as per the protocol and sent over
+the network back to the client.</li>
+
+<li>serveroutlen - length of bytes to send to client</li>
+</ul>
+
+This function begins the authentication process with a client. If
+the program returns SASL_CONTINUE that means <tt>serverout</tt>
+should be sent to the client. If SASL_OK is returned that means
+authentication is complete and the application should tell the
+client the authentication was successful. Any other return code
+means the authentication failed and the client should be notified
+of this. 
+
+<h3><a name="sasl_server_step">sasl_server_step</a></h3>
+
+<pre>
+    int sasl_server_step(sasl_conn_t *conn,
+                 const char *clientin,
+                 unsigned clientinlen,
+                 const char **serverout,
+                 unsigned *serveroutlen);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - The context for the connection</li>
+
+<li>clientin - Data sent by the client.</li>
+
+<li>clientinlen - The length of the client data. Note that this may
+be 0</li>
+
+<li>serverout - allocated and filled in by the function. These are
+the bytes that should be encoded as per the protocol and sent over
+the network back to the client.</li>
+
+<li>serveroutlen - length of bytes to send to client. Note that
+this may be 0</li>
+</ul>
+
+This function preforms a step of the authentication. This may need
+to be called an arbitrary number of times. If the program returns
+SASL_CONTINUE that means <tt>serverout</tt> should be sent to the
+client. If SASL_OK is returned that means authentication is
+complete and the application should tell the client the
+authentication was successful. Any other return code means the
+authentication failed and the client should be notified of this. 
+
+<h3><a name="sasl_listmech">sasl_listmech</a></h3>
+
+<pre>
+    int sasl_listmech(sasl_conn_t *conn,
+              const char *user,
+              const char *prefix,
+              const char *sep,
+              const char *suffix,
+              const char **result,
+              unsigned *plen,
+              unsigned *pcount);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - The context for this connection</li>
+
+<li>user - Currently not implemented</li>
+
+<li>prefix - The string to prepend</li>
+
+<li>sep - The string to separate mechanisms with</li>
+
+<li>suffix - The string to end with</li>
+
+<li>result - Resultant string</li>
+
+<li>plen - Number of characters in the result string</li>
+
+<li>pcount - Number of mechanisms listed in the result string</li>
+</ul>
+
+This function is used to create a string with a list of SASL
+mechanisms supported by the server. This string is often needed for
+a capability statement. 
+
+<h3><a name="sasl_checkpass">sasl_checkpass</a></h3>
+
+<pre>
+    int sasl_checkpass(sasl_conn_t *conn,
+                       const char *user,
+                       unsigned userlen,
+               const char *pass,
+               unsigned passlen);
+   
+</pre>
+
+Parameters: 
+
+<ul>
+<li>conn - The context for this connection</li>
+
+<li>user - The user trying to check the password for</li>
+
+<li>userlen - The user length</li>
+
+<li>pass - The password</li>
+
+<li>passlen - The password length</li>
+</ul>
+
+This checks a plaintext password <i>pass</i> for user <i>user</i>
+Some protocols have legacy systems for plaintext authentication
+where this might be used. 
+
+<h2><a name="common_section">Common Section</a></h2>
+
+<h3><a name="callbacks_interactions">Callbacks and
+Interactions</a></h3>
+
+When the application starts and calls sasl_client_init() you must
+specify for what data you support callbacks and/or interactions.
+These are for the library getting information needed for
+authentication from the application. This is needed for things like
+authentication name and password. If you do not declare supporting
+a callback you will not be able to use mechanisms that need that
+data. A callback is for when you have the information before you
+start the authentication. The SASL library calls a function you
+specify and your function fills in the requested information. For
+example if you had the userid of the user already for some reason.
+An interaction is usually for things you support but will need to
+ask the user for (e.g. password). sasl_client_start() or
+sasl_client_step() will return SASL_INTERACT. This will be a list
+of sasl_interact_t's which contain a human readable string you can
+prompt the user with, a possible computer readable string, and a
+default result. The nice thing about interactions is you get them
+all at once so if you had a GUI application you could bring up a
+dialog box asking for authentication name and password together
+instead of one at a time.
+
+<p>Any memory that is given to the SASL library for the purposes of
+callbacks and interactions must persist until the exchange
+completes in either success or failure. That is, the data must
+persist until <tt>sasl_client_start</tt> or
+<tt>sasl_client_step</tt> returns something other than
+<tt>SASL_INTERACT</tt> or <tt>SASL_CONTINUE</tt>.</p>
+
+<p><b>Memory management:</b>As in the rest of the SASLv2 API,
+whoever allocates the memory is responsible for freeing it. In
+almost all cases this should be fairly easy to manage, however a
+slight exception where the interaction sasl_interact_t structure is
+allocated and freed by the library, while the results are allocated
+and freed by the application. As noted above, however, <i>the
+results may not be freed until after the exchange completes, in
+either success or failure</i>.</p>
+
+<p>For a detailed description of what each of the callback types
+are see the sasl.h file. Here are some brief explanations:</p>
+
+<ul>
+<li>SASL_CB_AUTHNAME - the name of the user authenticating</li>
+
+<li>SASL_CB_USER - the name of the user acting for. (for example
+postman delivering mail for tmartin might have an AUTHNAME of
+postman and a USER of tmartin)</li>
+
+<li>SASL_CB_PASS - password for AUTHNAME</li>
+
+<li>SASL_CB_GETREALM - Realm of the server</li>
+</ul>
+
+An example of a way to handle callbacks: 
+
+<pre>
+    /* callbacks we support. This is a global variable at the 
+       top of the program */
+    static sasl_callback_t callbacks[] = {
+    {
+      SASL_CB_GETREALM, NULL, NULL  /* we'll just use an interaction if this comes up */
+    }, {
+      SASL_CB_USER, NULL, NULL      /* we'll just use an interaction if this comes up */
+    }, {
+      SASL_CB_AUTHNAME, &amp;getauthname_func, NULL /* A mechanism should call getauthname_func
+                                                   if it needs the authentication name */
+    }, { 
+      SASL_CB_PASS, &amp;getsecret_func, NULL      /* Call getsecret_func if need secret */
+    }, {
+      SASL_CB_LIST_END, NULL, NULL
+    }
+    };
+
+
+    static int getsecret_func(sasl_conn_t *conn,
+      void *context __attribute__((unused)),
+      int id,
+      sasl_secret_t **psecret)
+    {
+       [ask the user for their secret]
+
+       [allocate psecret and insert the secret]
+
+      return SASL_OK;
+    }
+
+    static int getauthname_func(void *context,
+                                int id,
+                                const char **result,
+                                unsigned *len)
+    {
+       if (id!=SASL_CB_AUTHNAME) return SASL_FAIL;
+
+       [fill in result and len]
+
+       return SASL_OK;
+     }
+
+    
+    in the main program somewhere
+    
+    sasl_client_init(callbacks);
+
+   
+</pre>
+
+<h3><a name="layers">Security layers</a></h3>
+
+<p>All is well and good to securely authenticate, but if you don't
+have some sort of integrity or privacy layer, anyone can hijack
+your TCP session after authentication. If your application has
+indicated that it can support a security layer, one <i>might</i> be
+negotiated.</p>
+
+<p>To set that you support a security layer, set a security
+property structure with <tt>max_ssf</tt> set to a non-zero
+number:</p>
+
+<pre>
+   sasl_security_properties_t secprops;
+
+   secprops.min_ssf = 0;
+   secprops.max_ssf = 256;
+   secprops.maxbufsize = /* SEE BELOW */;
+
+   secprops.property_names = NULL;
+   secprops.property_values = NULL;
+   secprops.security_flags = SASL_SEC_NOANONYMOUS; /* as appropriate */
+
+   sasl_setprop(conn, SASL_SEC_PROPS, &amp;secprops);
+</pre>
+
+The <tt>secprops</tt> variable will be copied during the call to
+<tt>sasl_setprop</tt>, so you may free its memory immediately. The
+<i>SSF</i> stands for <i>security strength factor</i> and is a
+rough indication of how "secure" the connection is. A connection
+supplying only integrity with no privacy would have an SSF of 1. A
+connection secured by 56-bit DES would have an SSF of 56. 
+
+<p>To require a security layer, set <tt>min_ssf</tt> to the minimum
+acceptable security layer strength.</p>
+
+<p>After authentication is successful, you can determine whether or
+not a security layer has been negotiated by looking at the SASL_SSF
+property:</p>
+
+<pre>
+   const int *ssfp;
+
+   result = sasl_getprop(conn, SASL_SSF, (const **) &amp;ssfp);
+   if (result != SASL_OK) {
+       /* ??? */
+   }
+   if (*ssfp &gt; 0) {
+       /* yay, we have a security layer! */
+   }
+</pre>
+
+<p>If a security layer has been negotiated, your application must
+make use of the <tt>sasl_encode()</tt> and <tt>sasl_decode()</tt>
+calls. All output must be passed through <tt>sasl_encode()</tt>
+before being written to the wire; all input must be passed through
+<tt>sasl_decode()</tt> before being looked at by the application.
+Your application must also be prepared to deal with
+<tt>sasl_decode()</tt> not returning any data in the rare case that
+the peer application did something strange (by splitting a single
+SASL blob into two seperate TCP packets).</p>
+
+<p>The only subtlety dealing with security layers is the maximum size
+of data that can be passed through <tt>sasl_encode()</tt> or
+<tt>sasl_decode()</tt>. This must be limited to make sure that only
+a finite amount of data needs to be buffered. The simple rules to
+follow:</p>
+
+<ul>
+<li>Before starting authentication, set <tt>maxbufsize</tt> in your
+security properties to be the buffer size that you pass to the
+<tt>read()</tt> system call&mdash;that is, the amount of data
+you're prepared to read at any one time.</li>
+
+<li>After authentication finishes, use <tt>sasl_getprop()</tt> to
+retrieve the <tt>SASL_MAXOUTBUF</tt> value, and call
+<tt>sasl_encode()</tt> with chunks of data of that size or less.
+<tt>sasl_encode()</tt> will throw an error if you call it with a
+larger chunk of data, so be careful!</li>
+</ul>
+
+<p><b>Memory management:</b> As usual, whoever allocates the memory
+must free it. The SASL library will keep the data returned from
+<tt>sasl_encode()</tt> until the next call to <tt>sasl_encode()</tt>
+on that connection. (<tt>sasl_decode()</tt> results persist until the
+next call to <tt>sasl_decode()</tt> on that connection.) The
+application must not attempt to free the memory returned from either
+function.</p>
+
+<p><b>Internally:</b></p>
+
+<ul>
+<li>your application sets SASL_SEC_PROPS with the buffer size X of
+the amount of data it will be using to read() from the socket.</li>
+
+<li>libsasl passes this number to the mechanism.</li>
+
+<li>the mechanism passes this number to the other side. the other
+side gives the corresponding read() size to our side.</li>
+
+<li>the mechanism subtracts the overhead of the layers from the
+size retrieved from the other side and returns it to the
+libsasl.</li>
+
+<li>libsasl then returns (via SASL_MAXOUTBUF) this number as the
+maximum amount of plaintext material that can be encoded at any one
+time, Y.</li>
+
+<li>sasl_encode() enforces the restriction of the length Y.</li>
+</ul>
+
+<h2><a name="example_section">Example applications that come with
+the Cyrus SASL library</a></h2>
+
+<h3><a name="sample_client"><tt>sample-client</tt> and
+<tt>sample-server</tt></a></h3>
+
+The sample client and server included with this distribution were
+initially written to help debug mechanisms. They base64 encode all
+the data and print it out on standard output. 
+
+<p>Make sure that you set the IP addresses, the username, the
+authenticate name, and anything else on the command line (some
+mechanisms depend on these being present).</p>
+
+<p>Also, sometimes you will receive a get "<tt>realm: Information
+not available</tt>" message, or similar; this is due to the fact
+that some mechanisms do not support realms and therefore never set
+it.</p>
+
+<h3><a name="cyrus_imapd">Cyrus imapd v2.1.0 or later</a></h3>
+
+The Cyrus IMAP server now incorporates SASLv2 for all its
+authentication needs. It is a good example of a fairly large server
+application. Also of interest is the prot layer, included in
+libcyrus. This is a stdio-like interface that automatically takes
+care of layers using a simple "<tt>prot_setsasl()</tt>" call. 
+
+<p>Cyrus imapd also sets a <tt>SASL_CB_PROXY_POLICY</tt> callback,
+which should be of interest to many applications.</p>
+
+<h3><a name="imtest"><tt>imtest</tt>, from Cyrus 2.1.0 or
+later</a></h3>
+
+<tt>imtest</tt> is an application included with Cyrus imapd. It is
+a very simple IMAP client, but should be of interest to those
+writing applications. It also uses the prot layer, but it is easy
+to incorporate similar support without using the prot layer.
+Likewise, there are other sample client applications that you can
+look at including <tt>smtptest</tt> and <tt>pop3test</tt> in the
+SASL distribution and the Cyrus IMAPd distribution, respectively. 
+
+<h2><a name="random_things">Miscellaneous Information</a></h2>
+
+<h3><a name="empty_exchanges">Empty exchanges</a></h3>
+
+<p>Some SASL mechanisms intentionally send no data; an application
+should be prepared to either send or receive an empty exchange. The
+SASL profile for the protocol should define how to send an empty
+string; make sure to send an empty string when requested, and when
+receiving an empty string make sure that the "<tt>inlength</tt>"
+passed in is 0.</p>
+
+<p>Note especially that the distinction between the empty string ""
+and the lack of a string (NULL) is extremely important in many
+cases (most notably, the client-send first scenario), and the
+application must ensure that it is passing the correct values to
+the SASL library at all times.</p>
+
+<h3><a name="idle">Idle</a></h3>
+
+While the implementation and the plugins correctly implement the
+idle calls, none of them currently do anything. 
+
+<hr>
+Please send any questions or comments to: 
+
+<address><a href=
+"mailto:cyrus-bugs@andrew.cmu.edu">cyrus-bugs@andrew.cmu.edu</a></address>
+
+<br>
+ Back to the <a href="index.html">index</a>
+</body>
+</html>
+
diff --git a/doc/readme.html b/doc/readme.html
new file mode 100644 (file)
index 0000000..155224e
--- /dev/null
@@ -0,0 +1,129 @@
+<HTML><HEAD>
+<title>Cyrus SASLv2 README</title>
+<!-- $Id: readme.html,v 1.13 2005/02/16 20:52:05 shadow Exp $ -->
+</HEAD>
+<BODY>
+<H1>Read Me First</H1>
+
+This document offers a general overview of the Cyrus SASL library.
+The Cyrus SASL Libray provides applications with an implementation
+of the Simple Authentication and Security Layer (RFC2222), and
+several authentication mechanisms.  Users interested in the "big picture"
+of what is provided by the library should read about
+<a href=components.html>Cyrus SASL Components</a>.
+
+<H2>FEATURES</H2>
+
+The following <a href="mechanisms.html">mechanisms</a> are included in
+this distribution:
+<ul>
+<li>ANONYMOUS
+<li>CRAM-MD5
+<li>DIGEST-MD5
+<li>EXTERNAL
+<li>GSSAPI (MIT Kerberos 5, Heimdal Kerberos 5 or CyberSafe)
+<li>KERBEROS_V4
+<li>LOGIN
+<li>NTLM (requires OpenSSL libcrypto)
+<li>OTP (requires OpenSSL libcrypto)
+<li>PLAIN
+<li>SRP (work in progress; requires OpenSSL libcrypto)
+</ul>
+
+The library also supports storing user secrets in either a hash
+database (e.g. Berkeley DB, gdbm, ndbm), LDAP, or in a SQL database 
+(MySQL, Postgres).
+
+
+Additionally, mechanisms such as PLAIN and LOGIN
+(where the plaintext password is directly supplied by the client)
+can perform direct password verification via the saslauthd daemon.  This
+allows the use of LDAP, PAM, and a variety of other password verification
+routines.
+
+The sample directory contains two programs which provide a reference
+for using the library, as well as making it easy to test a mechanism
+on the command line.  See <a
+href="programming.html">programming.html</a> for more information.<p>
+
+This library is believed to be thread safe IF:
+<ul>
+<li>you supply mutex functions (see sasl_set_mutex())
+<li>you make no libsasl calls until sasl_client/server_init() completes
+<li>no libsasl calls are made after sasl_done() is begun
+<li>when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
+</ul>
+
+<H2>TYPICAL UNIX INSTALLATION</H2>
+
+First, if you are upgrading from Cyrus SASLv1, please see <a
+href="upgrading.html">upgrading.html</a>.<p>
+
+Please see the file <a href="install.html">install.html</a> for instructions
+on how to install this package.<p>
+
+Note that the library can use the environment variable SASL_PATH to locate the
+directory where the mechanisms are; this should be a colon-separated
+list of directories containing plugins.  Otherwise it will default to the
+value of <tt>--with-plugindir</tt> as supplied to <tt>configure</tt> (which
+itself defaults to <tt>/usr/local/lib</tt>).
+
+<H2>INSTALLATION ON MAC OS X</H2>
+Please read <A HREF="macosx.html">macosx.html</A>
+
+<H2>INSTALLATION ON WINDOWS</H2>
+Please read <A HREF="windows.html">windows.html</A>.  This configuration
+has not been extensively tested.
+
+<H2>CONFIGURATION</H2>
+There are two main ways to configure the SASL library for a given
+application.  The first (and typically easiest) is to make use
+of the application's configuration files.  Provided the application supports it
+(via the <tt>SASL_CB_GETOPT</tt> callback), please refer to that documetation
+for how to supply <a href=options.html>SASL options</a>.<p>
+
+Alternatively, Cyrus SASL looks for configuration files in
+/usr/lib/sasl/Appname.conf where Appname is settable by the
+application (for example, Sendmail 8.10 and later set this to
+"Sendmail").<p>
+
+Configuration using the application's configuration files (via
+the <tt>getopt</tt> callback) will override those supplied by
+the SASL configuration files.<p>
+
+For a detailed guide on configuring libsasl, please look at
+<A HREF=sysadmin.html>sysadmin.html</A> and
+<A HREF=options.html>options.html</A>
+
+<H2>KNOWN BUGS</H2>
+<ul>
+<li>libtool doesn't always link libraries together.  In our environment,
+we only have static Krb5 libraries; the GSSAPI plugin should link
+these libraries in on platforms that support it (Solaris and Linux
+among them) but it does not.  It also doesn't always get the runpath
+of libraries correct.
+<li>Also see our <A HREF=http://bugzilla.andrew.cmu.edu>bugzilla</A>.
+</ul>
+
+<H2>AUTHORS</H2>
+
+For any comments/suggestions/bug reports, please contact <a
+href="mailto:cyrus-bugs@andrew.cmu.edu">cyrus-bugs@andrew.cmu.edu</a>.
+Be sure to include the version of libsasl and your operating system;
+messages without this information will not be answered.<p>
+
+Major contributors to the libsasl code can be found in the top-level
+file AUTHORS.  Additionally saslauthd has an AUTHORS file that lists
+major contributors as well.<p>
+
+People considering doing binary distributions that include saslauthd
+should be aware that the code is covered by several slightly different
+(but compatible) licenses, due to how it was contributed.  Details can
+be found within the source code.<p>
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
+
diff --git a/doc/rfc1321.txt b/doc/rfc1321.txt
new file mode 100644 (file)
index 0000000..68af27d
--- /dev/null
@@ -0,0 +1,1179 @@
+
+
+
+
+
+
+Network Working Group                                          R. Rivest
+Request for Comments: 1321           MIT Laboratory for Computer Science
+                                             and RSA Data Security, Inc.
+                                                              April 1992
+
+
+                     The MD5 Message-Digest Algorithm
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard.  Distribution of this memo is
+   unlimited.
+
+Acknowlegements
+
+   We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
+   David Chaum, and Noam Nisan for numerous helpful comments and
+   suggestions.
+
+Table of Contents
+
+   1. Executive Summary                                                1
+   2. Terminology and Notation                                         2
+   3. MD5 Algorithm Description                                        3
+   4. Summary                                                          6
+   5. Differences Between MD4 and MD5                                  6
+   References                                                          7
+   APPENDIX A - Reference Implementation                               7
+   Security Considerations                                            21
+   Author's Address                                                   21
+
+1. Executive Summary
+
+   This document describes the MD5 message-digest algorithm. The
+   algorithm takes as input a message of arbitrary length and produces
+   as output a 128-bit "fingerprint" or "message digest" of the input.
+   It is conjectured that it is computationally infeasible to produce
+   two messages having the same message digest, or to produce any
+   message having a given prespecified target message digest. The MD5
+   algorithm is intended for digital signature applications, where a
+   large file must be "compressed" in a secure manner before being
+   encrypted with a private (secret) key under a public-key cryptosystem
+   such as RSA.
+
+
+
+
+
+
+
+Rivest                                                          [Page 1]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+   The MD5 algorithm is designed to be quite fast on 32-bit machines. In
+   addition, the MD5 algorithm does not require any large substitution
+   tables; the algorithm can be coded quite compactly.
+
+   The MD5 algorithm is an extension of the MD4 message-digest algorithm
+   1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
+   design. MD5 was designed because it was felt that MD4 was perhaps
+   being adopted for use more quickly than justified by the existing
+   critical review; because MD4 was designed to be exceptionally fast,
+   it is "at the edge" in terms of risking successful cryptanalytic
+   attack. MD5 backs off a bit, giving up a little in speed for a much
+   greater likelihood of ultimate security. It incorporates some
+   suggestions made by various reviewers, and contains additional
+   optimizations. The MD5 algorithm is being placed in the public domain
+   for review and possible adoption as a standard.
+
+   For OSI-based applications, MD5's object identifier is
+
+   md5 OBJECT IDENTIFIER ::=
+     iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
+
+   In the X.509 type AlgorithmIdentifier [3], the parameters for MD5
+   should have type NULL.
+
+2. Terminology and Notation
+
+   In this document a "word" is a 32-bit quantity and a "byte" is an
+   eight-bit quantity. A sequence of bits can be interpreted in a
+   natural manner as a sequence of bytes, where each consecutive group
+   of eight bits is interpreted as a byte with the high-order (most
+   significant) bit of each byte listed first. Similarly, a sequence of
+   bytes can be interpreted as a sequence of 32-bit words, where each
+   consecutive group of four bytes is interpreted as a word with the
+   low-order (least significant) byte given first.
+
+   Let x_i denote "x sub i". If the subscript is an expression, we
+   surround it in braces, as in x_{i+1}. Similarly, we use ^ for
+   superscripts (exponentiation), so that x^i denotes x to the i-th
+   power.
+
+   Let the symbol "+" denote addition of words (i.e., modulo-2^32
+   addition). Let X <<< s denote the 32-bit value obtained by circularly
+   shifting (rotating) X left by s bit positions. Let not(X) denote the
+   bit-wise complement of X, and let X v Y denote the bit-wise OR of X
+   and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
+   denote the bit-wise AND of X and Y.
+
+
+
+
+
+Rivest                                                          [Page 2]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+3. MD5 Algorithm Description
+
+   We begin by supposing that we have a b-bit message as input, and that
+   we wish to find its message digest. Here b is an arbitrary
+   nonnegative integer; b may be zero, it need not be a multiple of
+   eight, and it may be arbitrarily large. We imagine the bits of the
+   message written down as follows:
+
+          m_0 m_1 ... m_{b-1}
+
+   The following five steps are performed to compute the message digest
+   of the message.
+
+3.1 Step 1. Append Padding Bits
+
+   The message is "padded" (extended) so that its length (in bits) is
+   congruent to 448, modulo 512. That is, the message is extended so
+   that it is just 64 bits shy of being a multiple of 512 bits long.
+   Padding is always performed, even if the length of the message is
+   already congruent to 448, modulo 512.
+
+   Padding is performed as follows: a single "1" bit is appended to the
+   message, and then "0" bits are appended so that the length in bits of
+   the padded message becomes congruent to 448, modulo 512. In all, at
+   least one bit and at most 512 bits are appended.
+
+3.2 Step 2. Append Length
+
+   A 64-bit representation of b (the length of the message before the
+   padding bits were added) is appended to the result of the previous
+   step. In the unlikely event that b is greater than 2^64, then only
+   the low-order 64 bits of b are used. (These bits are appended as two
+   32-bit words and appended low-order word first in accordance with the
+   previous conventions.)
+
+   At this point the resulting message (after padding with bits and with
+   b) has a length that is an exact multiple of 512 bits. Equivalently,
+   this message has a length that is an exact multiple of 16 (32-bit)
+   words. Let M[0 ... N-1] denote the words of the resulting message,
+   where N is a multiple of 16.
+
+3.3 Step 3. Initialize MD Buffer
+
+   A four-word buffer (A,B,C,D) is used to compute the message digest.
+   Here each of A, B, C, D is a 32-bit register. These registers are
+   initialized to the following values in hexadecimal, low-order bytes
+   first):
+
+
+
+
+Rivest                                                          [Page 3]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+          word A: 01 23 45 67
+          word B: 89 ab cd ef
+          word C: fe dc ba 98
+          word D: 76 54 32 10
+
+3.4 Step 4. Process Message in 16-Word Blocks
+
+   We first define four auxiliary functions that each take as input
+   three 32-bit words and produce as output one 32-bit word.
+
+          F(X,Y,Z) = XY v not(X) Z
+          G(X,Y,Z) = XZ v Y not(Z)
+          H(X,Y,Z) = X xor Y xor Z
+          I(X,Y,Z) = Y xor (X v not(Z))
+
+   In each bit position F acts as a conditional: if X then Y else Z.
+   The function F could have been defined using + instead of v since XY
+   and not(X)Z will never have 1's in the same bit position.) It is
+   interesting to note that if the bits of X, Y, and Z are independent
+   and unbiased, the each bit of F(X,Y,Z) will be independent and
+   unbiased.
+
+   The functions G, H, and I are similar to the function F, in that they
+   act in "bitwise parallel" to produce their output from the bits of X,
+   Y, and Z, in such a manner that if the corresponding bits of X, Y,
+   and Z are independent and unbiased, then each bit of G(X,Y,Z),
+   H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
+   the function H is the bit-wise "xor" or "parity" function of its
+   inputs.
+
+   This step uses a 64-element table T[1 ... 64] constructed from the
+   sine function. Let T[i] denote the i-th element of the table, which
+   is equal to the integer part of 4294967296 times abs(sin(i)), where i
+   is in radians. The elements of the table are given in the appendix.
+
+   Do the following:
+
+   /* Process each 16-word block. */
+   For i = 0 to N/16-1 do
+
+     /* Copy block i into X. */
+     For j = 0 to 15 do
+       Set X[j] to M[i*16+j].
+     end /* of loop on j */
+
+     /* Save A as AA, B as BB, C as CC, and D as DD. */
+     AA = A
+     BB = B
+
+
+
+Rivest                                                          [Page 4]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+     CC = C
+     DD = D
+
+     /* Round 1. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
+     /* Do the following 16 operations. */
+     [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
+     [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
+     [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
+     [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]
+
+     /* Round 2. */
+     /* Let [abcd k s i] denote the operation
+          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
+     /* Do the following 16 operations. */
+     [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
+     [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
+     [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
+     [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]
+
+     /* Round 3. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
+     /* Do the following 16 operations. */
+     [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
+     [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
+     [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
+     [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]
+
+     /* Round 4. */
+     /* Let [abcd k s t] denote the operation
+          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
+     /* Do the following 16 operations. */
+     [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
+     [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
+     [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
+     [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]
+
+     /* Then perform the following additions. (That is increment each
+        of the four registers by the value it had before this block
+        was started.) */
+     A = A + AA
+     B = B + BB
+     C = C + CC
+     D = D + DD
+
+   end /* of loop on i */
+
+
+
+Rivest                                                          [Page 5]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+3.5 Step 5. Output
+
+   The message digest produced as output is A, B, C, D. That is, we
+   begin with the low-order byte of A, and end with the high-order byte
+   of D.
+
+   This completes the description of MD5. A reference implementation in
+   C is given in the appendix.
+
+4. Summary
+
+   The MD5 message-digest algorithm is simple to implement, and provides
+   a "fingerprint" or message digest of a message of arbitrary length.
+   It is conjectured that the difficulty of coming up with two messages
+   having the same message digest is on the order of 2^64 operations,
+   and that the difficulty of coming up with any message having a given
+   message digest is on the order of 2^128 operations. The MD5 algorithm
+   has been carefully scrutinized for weaknesses. It is, however, a
+   relatively new algorithm and further security analysis is of course
+   justified, as is the case with any new proposal of this sort.
+
+5. Differences Between MD4 and MD5
+
+     The following are the differences between MD4 and MD5:
+
+       1.   A fourth round has been added.
+
+       2.   Each step now has a unique additive constant.
+
+       3.   The function g in round 2 was changed from (XY v XZ v YZ) to
+       (XZ v Y not(Z)) to make g less symmetric.
+
+       4.   Each step now adds in the result of the previous step.  This
+       promotes a faster "avalanche effect".
+
+       5.   The order in which input words are accessed in rounds 2 and
+       3 is changed, to make these patterns less like each other.
+
+       6.   The shift amounts in each round have been approximately
+       optimized, to yield a faster "avalanche effect." The shifts in
+       different rounds are distinct.
+
+
+
+
+
+
+
+
+
+
+Rivest                                                          [Page 6]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+References
+
+   [1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and
+       RSA Data Security, Inc., April 1992.
+
+   [2] Rivest, R., "The MD4 message digest algorithm", in A.J.  Menezes
+       and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90
+       Proceedings, pages 303-311, Springer-Verlag, 1991.
+
+   [3] CCITT Recommendation X.509 (1988), "The Directory -
+       Authentication Framework."
+
+APPENDIX A - Reference Implementation
+
+   This appendix contains the following files taken from RSAREF: A
+   Cryptographic Toolkit for Privacy-Enhanced Mail:
+
+     global.h -- global header file
+
+     md5.h -- header file for MD5
+
+     md5c.c -- source code for MD5
+
+   For more information on RSAREF, send email to <rsaref@rsa.com>.
+
+   The appendix also includes the following file:
+
+     mddriver.c -- test driver for MD2, MD4 and MD5
+
+   The driver compiles for MD5 by default but can compile for MD2 or MD4
+   if the symbol MD is defined on the C compiler command line as 2 or 4.
+
+   The implementation is portable and should work on many different
+   plaforms. However, it is not difficult to optimize the implementation
+   on particular platforms, an exercise left to the reader. For example,
+   on "little-endian" platforms where the lowest-addressed byte in a 32-
+   bit word is the least significant and there are no alignment
+   restrictions, the call to Decode in MD5Transform can be replaced with
+   a typecast.
+
+A.1 global.h
+
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* 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
+
+
+
+Rivest                                                          [Page 7]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+  been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* 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
+
+A.2 md5.h
+
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+
+
+
+Rivest                                                          [Page 8]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* 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 MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+A.3 md5c.c
+
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* 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.
+ */
+
+#include "global.h"
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+
+
+
+Rivest                                                          [Page 9]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+  ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+  ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+
+
+
+Rivest                                                         [Page 10]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+ (a) += (b); \
+  }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+  }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context;                                        /* context */
+{
+  context->count[0] = context->count[1] = 0;
+  /* Load magic initialization constants.
+*/
+  context->state[0] = 0x67452301;
+  context->state[1] = 0xefcdab89;
+  context->state[2] = 0x98badcfe;
+  context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+  operation, processing another message block, and updating the
+  context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context;                                        /* context */
+unsigned char *input;                                /* input block */
+unsigned int inputLen;                     /* length of input block */
+{
+  unsigned int i, index, partLen;
+
+  /* Compute number of bytes mod 64 */
+  index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+  /* Update number of bits */
+  if ((context->count[0] += ((UINT4)inputLen << 3))
+
+
+
+Rivest                                                         [Page 11]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+   < ((UINT4)inputLen << 3))
+ context->count[1]++;
+  context->count[1] += ((UINT4)inputLen >> 29);
+
+  partLen = 64 - index;
+
+  /* Transform as many times as possible.
+*/
+  if (inputLen >= partLen) {
+ MD5_memcpy
+   ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+   MD5Transform (context->state, &input[i]);
+
+ index = 0;
+  }
+  else
+ i = 0;
+
+  /* Buffer remaining input */
+  MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+  inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+  the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16];                         /* message digest */
+MD5_CTX *context;                                       /* context */
+{
+  unsigned char bits[8];
+  unsigned int index, padLen;
+
+  /* Save number of bits */
+  Encode (bits, context->count, 8);
+
+  /* Pad out to 56 mod 64.
+*/
+  index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+  padLen = (index < 56) ? (56 - index) : (120 - index);
+  MD5Update (context, PADDING, padLen);
+
+  /* Append length (before padding) */
+  MD5Update (context, bits, 8);
+
+
+
+Rivest                                                         [Page 12]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+  /* Store state in digest */
+  Encode (digest, context->state, 16);
+
+  /* Zeroize sensitive information.
+*/
+  MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+  UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+  Decode (x, block, 64);
+
+  /* Round 1 */
+  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+
+
+
+Rivest                                                         [Page 13]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+  /* Round 3 */
+  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+  /* Round 4 */
+  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+
+  /* Zeroize sensitive information.
+
+
+
+Rivest                                                         [Page 14]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+*/
+  MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+  a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+  }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+  a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+  unsigned int i, j;
+
+  for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+   (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+
+
+
+Rivest                                                         [Page 15]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+  unsigned int i;
+
+  for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
+
+A.4 mddriver.c
+
+/* MDDRIVER.C - test driver for MD2, MD4 and MD5
+ */
+
+/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
+rights reserved.
+
+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.
+ */
+
+/* The following makes MD default to MD5 if it has not already been
+  defined with C compiler flags.
+ */
+#ifndef MD
+#define MD MD5
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include "global.h"
+#if MD == 2
+#include "md2.h"
+#endif
+#if MD == 4
+
+
+
+Rivest                                                         [Page 16]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+#include "md4.h"
+#endif
+#if MD == 5
+#include "md5.h"
+#endif
+
+/* Length of test block, number of test blocks.
+ */
+#define TEST_BLOCK_LEN 1000
+#define TEST_BLOCK_COUNT 1000
+
+static void MDString PROTO_LIST ((char *));
+static void MDTimeTrial PROTO_LIST ((void));
+static void MDTestSuite PROTO_LIST ((void));
+static void MDFile PROTO_LIST ((char *));
+static void MDFilter PROTO_LIST ((void));
+static void MDPrint PROTO_LIST ((unsigned char [16]));
+
+#if MD == 2
+#define MD_CTX MD2_CTX
+#define MDInit MD2Init
+#define MDUpdate MD2Update
+#define MDFinal MD2Final
+#endif
+#if MD == 4
+#define MD_CTX MD4_CTX
+#define MDInit MD4Init
+#define MDUpdate MD4Update
+#define MDFinal MD4Final
+#endif
+#if MD == 5
+#define MD_CTX MD5_CTX
+#define MDInit MD5Init
+#define MDUpdate MD5Update
+#define MDFinal MD5Final
+#endif
+
+/* Main driver.
+
+Arguments (may be any combination):
+  -sstring - digests string
+  -t       - runs time trial
+  -x       - runs test script
+  filename - digests file
+  (none)   - digests standard input
+ */
+int main (argc, argv)
+int argc;
+
+
+
+Rivest                                                         [Page 17]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+char *argv[];
+{
+  int i;
+
+  if (argc > 1)
+ for (i = 1; i < argc; i++)
+   if (argv[i][0] == '-' && argv[i][1] == 's')
+     MDString (argv[i] + 2);
+   else if (strcmp (argv[i], "-t") == 0)
+     MDTimeTrial ();
+   else if (strcmp (argv[i], "-x") == 0)
+     MDTestSuite ();
+   else
+     MDFile (argv[i]);
+  else
+ MDFilter ();
+
+  return (0);
+}
+
+/* Digests a string and prints the result.
+ */
+static void MDString (string)
+char *string;
+{
+  MD_CTX context;
+  unsigned char digest[16];
+  unsigned int len = strlen (string);
+
+  MDInit (&context);
+  MDUpdate (&context, string, len);
+  MDFinal (digest, &context);
+
+  printf ("MD%d (\"%s\") = ", MD, string);
+  MDPrint (digest);
+  printf ("\n");
+}
+
+/* Measures the time to digest TEST_BLOCK_COUNT TEST_BLOCK_LEN-byte
+  blocks.
+ */
+static void MDTimeTrial ()
+{
+  MD_CTX context;
+  time_t endTime, startTime;
+  unsigned char block[TEST_BLOCK_LEN], digest[16];
+  unsigned int i;
+
+
+
+
+Rivest                                                         [Page 18]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+  printf
+ ("MD%d time trial. Digesting %d %d-byte blocks ...", MD,
+  TEST_BLOCK_LEN, TEST_BLOCK_COUNT);
+
+  /* Initialize block */
+  for (i = 0; i < TEST_BLOCK_LEN; i++)
+ block[i] = (unsigned char)(i & 0xff);
+
+  /* Start timer */
+  time (&startTime);
+
+  /* Digest blocks */
+  MDInit (&context);
+  for (i = 0; i < TEST_BLOCK_COUNT; i++)
+ MDUpdate (&context, block, TEST_BLOCK_LEN);
+  MDFinal (digest, &context);
+
+  /* Stop timer */
+  time (&endTime);
+
+  printf (" done\n");
+  printf ("Digest = ");
+  MDPrint (digest);
+  printf ("\nTime = %ld seconds\n", (long)(endTime-startTime));
+  printf
+ ("Speed = %ld bytes/second\n",
+  (long)TEST_BLOCK_LEN * (long)TEST_BLOCK_COUNT/(endTime-startTime));
+}
+
+/* Digests a reference suite of strings and prints the results.
+ */
+static void MDTestSuite ()
+{
+  printf ("MD%d test suite:\n", MD);
+
+  MDString ("");
+  MDString ("a");
+  MDString ("abc");
+  MDString ("message digest");
+  MDString ("abcdefghijklmnopqrstuvwxyz");
+  MDString
+ ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+  MDString
+ ("1234567890123456789012345678901234567890\
+1234567890123456789012345678901234567890");
+}
+
+/* Digests a file and prints the result.
+
+
+
+Rivest                                                         [Page 19]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+ */
+static void MDFile (filename)
+char *filename;
+{
+  FILE *file;
+  MD_CTX context;
+  int len;
+  unsigned char buffer[1024], digest[16];
+
+  if ((file = fopen (filename, "rb")) == NULL)
+ printf ("%s can't be opened\n", filename);
+
+  else {
+ MDInit (&context);
+ while (len = fread (buffer, 1, 1024, file))
+   MDUpdate (&context, buffer, len);
+ MDFinal (digest, &context);
+
+ fclose (file);
+
+ printf ("MD%d (%s) = ", MD, filename);
+ MDPrint (digest);
+ printf ("\n");
+  }
+}
+
+/* Digests the standard input and prints the result.
+ */
+static void MDFilter ()
+{
+  MD_CTX context;
+  int len;
+  unsigned char buffer[16], digest[16];
+
+  MDInit (&context);
+  while (len = fread (buffer, 1, 16, stdin))
+ MDUpdate (&context, buffer, len);
+  MDFinal (digest, &context);
+
+  MDPrint (digest);
+  printf ("\n");
+}
+
+/* Prints a message digest in hexadecimal.
+ */
+static void MDPrint (digest)
+unsigned char digest[16];
+{
+
+
+
+Rivest                                                         [Page 20]
+\f
+RFC 1321              MD5 Message-Digest Algorithm            April 1992
+
+
+  unsigned int i;
+
+  for (i = 0; i < 16; i++)
+ printf ("%02x", digest[i]);
+}
+
+A.5 Test suite
+
+   The MD5 test suite (driver option "-x") should print the following
+   results:
+
+MD5 test suite:
+MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
+MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
+MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
+MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
+MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
+MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
+d174ab98d277d9f5a5611c2c9f419d9f
+MD5 ("123456789012345678901234567890123456789012345678901234567890123456
+78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
+
+Security Considerations
+
+   The level of security discussed in this memo is considered to be
+   sufficient for implementing very high security hybrid digital-
+   signature schemes based on MD5 and a public-key cryptosystem.
+
+Author's Address
+
+   Ronald L. Rivest
+   Massachusetts Institute of Technology
+   Laboratory for Computer Science
+   NE43-324
+   545 Technology Square
+   Cambridge, MA  02139-1986
+
+   Phone: (617) 253-5880
+   EMail: rivest@theory.lcs.mit.edu
+
+
+
+
+
+
+
+
+
+
+
+
+Rivest                                                         [Page 21]
+\f
\ No newline at end of file
diff --git a/doc/rfc1939.txt b/doc/rfc1939.txt
new file mode 100644 (file)
index 0000000..b11350e
--- /dev/null
@@ -0,0 +1,1291 @@
+
+
+
+
+
+
+Network Working Group                                           J. Myers
+Request for Comments: 1939                               Carnegie Mellon
+STD: 53                                                          M. Rose
+Obsoletes: 1725                             Dover Beach Consulting, Inc.
+Category: Standards Track                                       May 1996
+
+
+                    Post Office Protocol - Version 3
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Table of Contents
+
+   1. Introduction ................................................    2
+   2. A Short Digression ..........................................    2
+   3. Basic Operation .............................................    3
+   4. The AUTHORIZATION State .....................................    4
+      QUIT Command ................................................    5
+   5. The TRANSACTION State .......................................    5
+      STAT Command ................................................    6
+      LIST Command ................................................    6
+      RETR Command ................................................    8
+      DELE Command ................................................    8
+      NOOP Command ................................................    9
+      RSET Command ................................................    9
+   6. The UPDATE State ............................................   10
+      QUIT Command ................................................   10
+   7. Optional POP3 Commands ......................................   11
+      TOP Command .................................................   11
+      UIDL Command ................................................   12
+      USER Command ................................................   13
+      PASS Command ................................................   14
+      APOP Command ................................................   15
+   8. Scaling and Operational Considerations ......................   16
+   9. POP3 Command Summary ........................................   18
+   10. Example POP3 Session .......................................   19
+   11. Message Format .............................................   19
+   12. References .................................................   20
+   13. Security Considerations ....................................   20
+   14. Acknowledgements ...........................................   20
+   15. Authors' Addresses .........................................   21
+   Appendix A. Differences from RFC 1725 ..........................   22
+
+
+
+Myers & Rose                Standards Track                     [Page 1]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+   Appendix B. Command Index ......................................   23
+
+1. Introduction
+
+   On certain types of smaller nodes in the Internet it is often
+   impractical to maintain a message transport system (MTS).  For
+   example, a workstation may not have sufficient resources (cycles,
+   disk space) in order to permit a SMTP server [RFC821] and associated
+   local mail delivery system to be kept resident and continuously
+   running.  Similarly, it may be expensive (or impossible) to keep a
+   personal computer interconnected to an IP-style network for long
+   amounts of time (the node is lacking the resource known as
+   "connectivity").
+
+   Despite this, it is often very useful to be able to manage mail on
+   these smaller nodes, and they often support a user agent (UA) to aid
+   the tasks of mail handling.  To solve this problem, a node which can
+   support an MTS entity offers a maildrop service to these less endowed
+   nodes.  The Post Office Protocol - Version 3 (POP3) is intended to
+   permit a workstation to dynamically access a maildrop on a server
+   host in a useful fashion.  Usually, this means that the POP3 protocol
+   is used to allow a workstation to retrieve mail that the server is
+   holding for it.
+
+   POP3 is not intended to provide extensive manipulation operations of
+   mail on the server; normally, mail is downloaded and then deleted.  A
+   more advanced (and complex) protocol, IMAP4, is discussed in
+   [RFC1730].
+
+   For the remainder of this memo, the term "client host" refers to a
+   host making use of the POP3 service, while the term "server host"
+   refers to a host which offers the POP3 service.
+
+2. A Short Digression
+
+   This memo does not specify how a client host enters mail into the
+   transport system, although a method consistent with the philosophy of
+   this memo is presented here:
+
+      When the user agent on a client host wishes to enter a message
+      into the transport system, it establishes an SMTP connection to
+      its relay host and sends all mail to it.  This relay host could
+      be, but need not be, the POP3 server host for the client host.  Of
+      course, the relay host must accept mail for delivery to arbitrary
+      recipient addresses, that functionality is not required of all
+      SMTP servers.
+
+
+
+
+
+Myers & Rose                Standards Track                     [Page 2]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+3. Basic Operation
+
+   Initially, the server host starts the POP3 service by listening on
+   TCP port 110.  When a client host wishes to make use of the service,
+   it establishes a TCP connection with the server host.  When the
+   connection is established, the POP3 server sends a greeting.  The
+   client and POP3 server then exchange commands and responses
+   (respectively) until the connection is closed or aborted.
+
+   Commands in the POP3 consist of a case-insensitive keyword, possibly
+   followed by one or more arguments.  All commands are terminated by a
+   CRLF pair.  Keywords and arguments consist of printable ASCII
+   characters.  Keywords and arguments are each separated by a single
+   SPACE character.  Keywords are three or four characters long. Each
+   argument may be up to 40 characters long.
+
+   Responses in the POP3 consist of a status indicator and a keyword
+   possibly followed by additional information.  All responses are
+   terminated by a CRLF pair.  Responses may be up to 512 characters
+   long, including the terminating CRLF.  There are currently two status
+   indicators: positive ("+OK") and negative ("-ERR").  Servers MUST
+   send the "+OK" and "-ERR" in upper case.
+
+   Responses to certain commands are multi-line.  In these cases, which
+   are clearly indicated below, after sending the first line of the
+   response and a CRLF, any additional lines are sent, each terminated
+   by a CRLF pair.  When all lines of the response have been sent, a
+   final line is sent, consisting of a termination octet (decimal code
+   046, ".") and a CRLF pair.  If any line of the multi-line response
+   begins with the termination octet, the line is "byte-stuffed" by
+   pre-pending the termination octet to that line of the response.
+   Hence a multi-line response is terminated with the five octets
+   "CRLF.CRLF".  When examining a multi-line response, the client checks
+   to see if the line begins with the termination octet.  If so and if
+   octets other than CRLF follow, the first octet of the line (the
+   termination octet) is stripped away.  If so and if CRLF immediately
+   follows the termination character, then the response from the POP
+   server is ended and the line containing ".CRLF" is not considered
+   part of the multi-line response.
+
+   A POP3 session progresses through a number of states during its
+   lifetime.  Once the TCP connection has been opened and the POP3
+   server has sent the greeting, the session enters the AUTHORIZATION
+   state.  In this state, the client must identify itself to the POP3
+   server.  Once the client has successfully done this, the server
+   acquires resources associated with the client's maildrop, and the
+   session enters the TRANSACTION state.  In this state, the client
+   requests actions on the part of the POP3 server.  When the client has
+
+
+
+Myers & Rose                Standards Track                     [Page 3]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+   issued the QUIT command, the session enters the UPDATE state.  In
+   this state, the POP3 server releases any resources acquired during
+   the TRANSACTION state and says goodbye.  The TCP connection is then
+   closed.
+
+   A server MUST respond to an unrecognized, unimplemented, or
+   syntactically invalid command by responding with a negative status
+   indicator.  A server MUST respond to a command issued when the
+   session is in an incorrect state by responding with a negative status
+   indicator.  There is no general method for a client to distinguish
+   between a server which does not implement an optional command and a
+   server which is unwilling or unable to process the command.
+
+   A POP3 server MAY have an inactivity autologout timer.  Such a timer
+   MUST be of at least 10 minutes' duration.  The receipt of any command
+   from the client during that interval should suffice to reset the
+   autologout timer.  When the timer expires, the session does NOT enter
+   the UPDATE state--the server should close the TCP connection without
+   removing any messages or sending any response to the client.
+
+4. The AUTHORIZATION State
+
+   Once the TCP connection has been opened by a POP3 client, the POP3
+   server issues a one line greeting.  This can be any positive
+   response.  An example might be:
+
+      S:  +OK POP3 server ready
+
+   The POP3 session is now in the AUTHORIZATION state.  The client must
+   now identify and authenticate itself to the POP3 server.  Two
+   possible mechanisms for doing this are described in this document,
+   the USER and PASS command combination and the APOP command.  Both
+   mechanisms are described later in this document.  Additional
+   authentication mechanisms are described in [RFC1734].  While there is
+   no single authentication mechanism that is required of all POP3
+   servers, a POP3 server must of course support at least one
+   authentication mechanism.
+
+   Once the POP3 server has determined through the use of any
+   authentication command that the client should be given access to the
+   appropriate maildrop, the POP3 server then acquires an exclusive-
+   access lock on the maildrop, as necessary to prevent messages from
+   being modified or removed before the session enters the UPDATE state.
+   If the lock is successfully acquired, the POP3 server responds with a
+   positive status indicator.  The POP3 session now enters the
+   TRANSACTION state, with no messages marked as deleted.  If the
+   maildrop cannot be opened for some reason (for example, a lock can
+   not be acquired, the client is denied access to the appropriate
+
+
+
+Myers & Rose                Standards Track                     [Page 4]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+   maildrop, or the maildrop cannot be parsed), the POP3 server responds
+   with a negative status indicator.  (If a lock was acquired but the
+   POP3 server intends to respond with a negative status indicator, the
+   POP3 server must release the lock prior to rejecting the command.)
+   After returning a negative status indicator, the server may close the
+   connection.  If the server does not close the connection, the client
+   may either issue a new authentication command and start again, or the
+   client may issue the QUIT command.
+
+   After the POP3 server has opened the maildrop, it assigns a message-
+   number to each message, and notes the size of each message in octets.
+   The first message in the maildrop is assigned a message-number of
+   "1", the second is assigned "2", and so on, so that the nth message
+   in a maildrop is assigned a message-number of "n".  In POP3 commands
+   and responses, all message-numbers and message sizes are expressed in
+   base-10 (i.e., decimal).
+
+   Here is the summary for the QUIT command when used in the
+   AUTHORIZATION state:
+
+      QUIT
+
+         Arguments: none
+
+         Restrictions: none
+
+         Possible Responses:
+             +OK
+
+         Examples:
+             C: QUIT
+             S: +OK dewey POP3 server signing off
+
+5. The TRANSACTION State
+
+   Once the client has successfully identified itself to the POP3 server
+   and the POP3 server has locked and opened the appropriate maildrop,
+   the POP3 session is now in the TRANSACTION state.  The client may now
+   issue any of the following POP3 commands repeatedly.  After each
+   command, the POP3 server issues a response.  Eventually, the client
+   issues the QUIT command and the POP3 session enters the UPDATE state.
+
+
+
+
+
+
+
+
+
+
+Myers & Rose                Standards Track                     [Page 5]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+   Here are the POP3 commands valid in the TRANSACTION state:
+
+      STAT
+
+         Arguments: none
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             The POP3 server issues a positive response with a line
+             containing information for the maildrop.  This line is
+             called a "drop listing" for that maildrop.
+
+             In order to simplify parsing, all POP3 servers are
+             required to use a certain format for drop listings.  The
+             positive response consists of "+OK" followed by a single
+             space, the number of messages in the maildrop, a single
+             space, and the size of the maildrop in octets.  This memo
+             makes no requirement on what follows the maildrop size.
+             Minimal implementations should just end that line of the
+             response with a CRLF pair.  More advanced implementations
+             may include other information.
+
+                NOTE: This memo STRONGLY discourages implementations
+                from supplying additional information in the drop
+                listing.  Other, optional, facilities are discussed
+                later on which permit the client to parse the messages
+                in the maildrop.
+
+             Note that messages marked as deleted are not counted in
+             either total.
+
+         Possible Responses:
+             +OK nn mm
+
+         Examples:
+             C: STAT
+             S: +OK 2 320
+
+
+      LIST [msg]
+
+         Arguments:
+             a message-number (optional), which, if present, may NOT
+             refer to a message marked as deleted
+
+
+
+
+
+Myers & Rose                Standards Track                     [Page 6]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             If an argument was given and the POP3 server issues a
+             positive response with a line containing information for
+             that message.  This line is called a "scan listing" for
+             that message.
+
+             If no argument was given and the POP3 server issues a
+             positive response, then the response given is multi-line.
+             After the initial +OK, for each message in the maildrop,
+             the POP3 server responds with a line containing
+             information for that message.  This line is also called a
+             "scan listing" for that message.  If there are no
+             messages in the maildrop, then the POP3 server responds
+             with no scan listings--it issues a positive response
+             followed by a line containing a termination octet and a
+             CRLF pair.
+
+             In order to simplify parsing, all POP3 servers are
+             required to use a certain format for scan listings.  A
+             scan listing consists of the message-number of the
+             message, followed by a single space and the exact size of
+             the message in octets.  Methods for calculating the exact
+             size of the message are described in the "Message Format"
+             section below.  This memo makes no requirement on what
+             follows the message size in the scan listing.  Minimal
+             implementations should just end that line of the response
+             with a CRLF pair.  More advanced implementations may
+             include other information, as parsed from the message.
+
+                NOTE: This memo STRONGLY discourages implementations
+                from supplying additional information in the scan
+                listing.  Other, optional, facilities are discussed
+                later on which permit the client to parse the messages
+                in the maildrop.
+
+             Note that messages marked as deleted are not listed.
+
+         Possible Responses:
+             +OK scan listing follows
+             -ERR no such message
+
+         Examples:
+             C: LIST
+             S: +OK 2 messages (320 octets)
+             S: 1 120
+
+
+
+Myers & Rose                Standards Track                     [Page 7]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             S: 2 200
+             S: .
+               ...
+             C: LIST 2
+             S: +OK 2 200
+               ...
+             C: LIST 3
+             S: -ERR no such message, only 2 messages in maildrop
+
+
+      RETR msg
+
+         Arguments:
+             a message-number (required) which may NOT refer to a
+             message marked as deleted
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             If the POP3 server issues a positive response, then the
+             response given is multi-line.  After the initial +OK, the
+             POP3 server sends the message corresponding to the given
+             message-number, being careful to byte-stuff the termination
+             character (as with all multi-line responses).
+
+         Possible Responses:
+             +OK message follows
+             -ERR no such message
+
+         Examples:
+             C: RETR 1
+             S: +OK 120 octets
+             S: <the POP3 server sends the entire message here>
+             S: .
+
+
+      DELE msg
+
+         Arguments:
+             a message-number (required) which may NOT refer to a
+             message marked as deleted
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+
+
+
+
+
+Myers & Rose                Standards Track                     [Page 8]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+         Discussion:
+             The POP3 server marks the message as deleted.  Any future
+             reference to the message-number associated with the message
+             in a POP3 command generates an error.  The POP3 server does
+             not actually delete the message until the POP3 session
+             enters the UPDATE state.
+
+         Possible Responses:
+             +OK message deleted
+             -ERR no such message
+
+         Examples:
+             C: DELE 1
+             S: +OK message 1 deleted
+                ...
+             C: DELE 2
+             S: -ERR message 2 already deleted
+
+
+      NOOP
+
+         Arguments: none
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             The POP3 server does nothing, it merely replies with a
+             positive response.
+
+         Possible Responses:
+             +OK
+
+         Examples:
+             C: NOOP
+             S: +OK
+
+
+      RSET
+
+         Arguments: none
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             If any messages have been marked as deleted by the POP3
+             server, they are unmarked.  The POP3 server then replies
+
+
+
+Myers & Rose                Standards Track                     [Page 9]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             with a positive response.
+
+         Possible Responses:
+             +OK
+
+         Examples:
+             C: RSET
+             S: +OK maildrop has 2 messages (320 octets)
+
+6. The UPDATE State
+
+   When the client issues the QUIT command from the TRANSACTION state,
+   the POP3 session enters the UPDATE state.  (Note that if the client
+   issues the QUIT command from the AUTHORIZATION state, the POP3
+   session terminates but does NOT enter the UPDATE state.)
+
+   If a session terminates for some reason other than a client-issued
+   QUIT command, the POP3 session does NOT enter the UPDATE state and
+   MUST not remove any messages from the maildrop.
+
+      QUIT
+
+         Arguments: none
+
+         Restrictions: none
+
+         Discussion:
+             The POP3 server removes all messages marked as deleted
+             from the maildrop and replies as to the status of this
+             operation.  If there is an error, such as a resource
+             shortage, encountered while removing messages, the
+             maildrop may result in having some or none of the messages
+             marked as deleted be removed.  In no case may the server
+             remove any messages not marked as deleted.
+
+             Whether the removal was successful or not, the server
+             then releases any exclusive-access lock on the maildrop
+             and closes the TCP connection.
+
+         Possible Responses:
+             +OK
+             -ERR some deleted messages not removed
+
+         Examples:
+             C: QUIT
+             S: +OK dewey POP3 server signing off (maildrop empty)
+                ...
+             C: QUIT
+
+
+
+Myers & Rose                Standards Track                    [Page 10]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             S: +OK dewey POP3 server signing off (2 messages left)
+                ...
+
+7. Optional POP3 Commands
+
+   The POP3 commands discussed above must be supported by all minimal
+   implementations of POP3 servers.
+
+   The optional POP3 commands described below permit a POP3 client
+   greater freedom in message handling, while preserving a simple POP3
+   server implementation.
+
+      NOTE: This memo STRONGLY encourages implementations to support
+      these commands in lieu of developing augmented drop and scan
+      listings.  In short, the philosophy of this memo is to put
+      intelligence in the part of the POP3 client and not the POP3
+      server.
+
+      TOP msg n
+
+         Arguments:
+             a message-number (required) which may NOT refer to to a
+             message marked as deleted, and a non-negative number
+             of lines (required)
+
+         Restrictions:
+             may only be given in the TRANSACTION state
+
+         Discussion:
+             If the POP3 server issues a positive response, then the
+             response given is multi-line.  After the initial +OK, the
+             POP3 server sends the headers of the message, the blank
+             line separating the headers from the body, and then the
+             number of lines of the indicated message's body, being
+             careful to byte-stuff the termination character (as with
+             all multi-line responses).
+
+             Note that if the number of lines requested by the POP3
+             client is greater than than the number of lines in the
+             body, then the POP3 server sends the entire message.
+
+         Possible Responses:
+             +OK top of message follows
+             -ERR no such message
+
+         Examples:
+             C: TOP 1 10
+             S: +OK
+
+
+
+Myers & Rose                Standards Track                    [Page 11]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             S: <the POP3 server sends the headers of the
+                message, a blank line, and the first 10 lines
+                of the body of the message>
+             S: .
+                ...
+             C: TOP 100 3
+             S: -ERR no such message
+
+
+      UIDL [msg]
+
+      Arguments:
+          a message-number (optional), which, if present, may NOT
+          refer to a message marked as deleted
+
+      Restrictions:
+          may only be given in the TRANSACTION state.
+
+      Discussion:
+          If an argument was given and the POP3 server issues a positive
+          response with a line containing information for that message.
+          This line is called a "unique-id listing" for that message.
+
+          If no argument was given and the POP3 server issues a positive
+          response, then the response given is multi-line.  After the
+          initial +OK, for each message in the maildrop, the POP3 server
+          responds with a line containing information for that message.
+          This line is called a "unique-id listing" for that message.
+
+          In order to simplify parsing, all POP3 servers are required to
+          use a certain format for unique-id listings.  A unique-id
+          listing consists of the message-number of the message,
+          followed by a single space and the unique-id of the message.
+          No information follows the unique-id in the unique-id listing.
+
+          The unique-id of a message is an arbitrary server-determined
+          string, consisting of one to 70 characters in the range 0x21
+          to 0x7E, which uniquely identifies a message within a
+          maildrop and which persists across sessions.  This
+          persistence is required even if a session ends without
+          entering the UPDATE state.  The server should never reuse an
+          unique-id in a given maildrop, for as long as the entity
+          using the unique-id exists.
+
+          Note that messages marked as deleted are not listed.
+
+          While it is generally preferable for server implementations
+          to store arbitrarily assigned unique-ids in the maildrop,
+
+
+
+Myers & Rose                Standards Track                    [Page 12]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+          this specification is intended to permit unique-ids to be
+          calculated as a hash of the message.  Clients should be able
+          to handle a situation where two identical copies of a
+          message in a maildrop have the same unique-id.
+
+      Possible Responses:
+          +OK unique-id listing follows
+          -ERR no such message
+
+      Examples:
+          C: UIDL
+          S: +OK
+          S: 1 whqtswO00WBw418f9t5JxYwZ
+          S: 2 QhdPYR:00WBw1Ph7x7
+          S: .
+             ...
+          C: UIDL 2
+          S: +OK 2 QhdPYR:00WBw1Ph7x7
+             ...
+          C: UIDL 3
+          S: -ERR no such message, only 2 messages in maildrop
+
+
+      USER name
+
+         Arguments:
+             a string identifying a mailbox (required), which is of
+             significance ONLY to the server
+
+         Restrictions:
+             may only be given in the AUTHORIZATION state after the POP3
+             greeting or after an unsuccessful USER or PASS command
+
+         Discussion:
+             To authenticate using the USER and PASS command
+             combination, the client must first issue the USER
+             command.  If the POP3 server responds with a positive
+             status indicator ("+OK"), then the client may issue
+             either the PASS command to complete the authentication,
+             or the QUIT command to terminate the POP3 session.  If
+             the POP3 server responds with a negative status indicator
+             ("-ERR") to the USER command, then the client may either
+             issue a new authentication command or may issue the QUIT
+             command.
+
+             The server may return a positive response even though no
+             such mailbox exists.  The server may return a negative
+             response if mailbox exists, but does not permit plaintext
+
+
+
+Myers & Rose                Standards Track                    [Page 13]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             password authentication.
+
+         Possible Responses:
+             +OK name is a valid mailbox
+             -ERR never heard of mailbox name
+
+         Examples:
+             C: USER frated
+             S: -ERR sorry, no mailbox for frated here
+                ...
+             C: USER mrose
+             S: +OK mrose is a real hoopy frood
+
+
+      PASS string
+
+         Arguments:
+             a server/mailbox-specific password (required)
+
+         Restrictions:
+             may only be given in the AUTHORIZATION state immediately
+             after a successful USER command
+
+         Discussion:
+             When the client issues the PASS command, the POP3 server
+             uses the argument pair from the USER and PASS commands to
+             determine if the client should be given access to the
+             appropriate maildrop.
+
+             Since the PASS command has exactly one argument, a POP3
+             server may treat spaces in the argument as part of the
+             password, instead of as argument separators.
+
+         Possible Responses:
+             +OK maildrop locked and ready
+             -ERR invalid password
+             -ERR unable to lock maildrop
+
+         Examples:
+             C: USER mrose
+             S: +OK mrose is a real hoopy frood
+             C: PASS secret
+             S: -ERR maildrop already locked
+               ...
+             C: USER mrose
+             S: +OK mrose is a real hoopy frood
+             C: PASS secret
+             S: +OK mrose's maildrop has 2 messages (320 octets)
+
+
+
+Myers & Rose                Standards Track                    [Page 14]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+      APOP name digest
+
+         Arguments:
+             a string identifying a mailbox and a MD5 digest string
+             (both required)
+
+         Restrictions:
+             may only be given in the AUTHORIZATION state after the POP3
+             greeting or after an unsuccessful USER or PASS command
+
+         Discussion:
+             Normally, each POP3 session starts with a USER/PASS
+             exchange.  This results in a server/user-id specific
+             password being sent in the clear on the network.  For
+             intermittent use of POP3, this may not introduce a sizable
+             risk.  However, many POP3 client implementations connect to
+             the POP3 server on a regular basis -- to check for new
+             mail.  Further the interval of session initiation may be on
+             the order of five minutes.  Hence, the risk of password
+             capture is greatly enhanced.
+
+             An alternate method of authentication is required which
+             provides for both origin authentication and replay
+             protection, but which does not involve sending a password
+             in the clear over the network.  The APOP command provides
+             this functionality.
+
+             A POP3 server which implements the APOP command will
+             include a timestamp in its banner greeting.  The syntax of
+             the timestamp corresponds to the `msg-id' in [RFC822], and
+             MUST be different each time the POP3 server issues a banner
+             greeting.  For example, on a UNIX implementation in which a
+             separate UNIX process is used for each instance of a POP3
+             server, the syntax of the timestamp might be:
+
+                <process-ID.clock@hostname>
+
+             where `process-ID' is the decimal value of the process's
+             PID, clock is the decimal value of the system clock, and
+             hostname is the fully-qualified domain-name corresponding
+             to the host where the POP3 server is running.
+
+             The POP3 client makes note of this timestamp, and then
+             issues the APOP command.  The `name' parameter has
+             identical semantics to the `name' parameter of the USER
+             command. The `digest' parameter is calculated by applying
+             the MD5 algorithm [RFC1321] to a string consisting of the
+             timestamp (including angle-brackets) followed by a shared
+
+
+
+Myers & Rose                Standards Track                    [Page 15]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+             secret.  This shared secret is a string known only to the
+             POP3 client and server.  Great care should be taken to
+             prevent unauthorized disclosure of the secret, as knowledge
+             of the secret will allow any entity to successfully
+             masquerade as the named user.  The `digest' parameter
+             itself is a 16-octet value which is sent in hexadecimal
+             format, using lower-case ASCII characters.
+
+             When the POP3 server receives the APOP command, it verifies
+             the digest provided.  If the digest is correct, the POP3
+             server issues a positive response, and the POP3 session
+             enters the TRANSACTION state.  Otherwise, a negative
+             response is issued and the POP3 session remains in the
+             AUTHORIZATION state.
+
+             Note that as the length of the shared secret increases, so
+             does the difficulty of deriving it.  As such, shared
+             secrets should be long strings (considerably longer than
+             the 8-character example shown below).
+
+         Possible Responses:
+             +OK maildrop locked and ready
+             -ERR permission denied
+
+         Examples:
+             S: +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us>
+             C: APOP mrose c4c9334bac560ecc979e58001b3e22fb
+             S: +OK maildrop has 1 message (369 octets)
+
+             In this example, the shared  secret  is  the  string  `tan-
+             staaf'.  Hence, the MD5 algorithm is applied to the string
+
+                <1896.697170952@dbc.mtview.ca.us>tanstaaf
+
+             which produces a digest value of
+
+                c4c9334bac560ecc979e58001b3e22fb
+
+8. Scaling and Operational Considerations
+
+   Since some of the optional features described above were added to the
+   POP3 protocol, experience has accumulated in using them in large-
+   scale commercial post office operations where most of the users are
+   unrelated to each other.  In these situations and others, users and
+   vendors of POP3 clients have discovered that the combination of using
+   the UIDL command and not issuing the DELE command can provide a weak
+   version of the "maildrop as semi-permanent repository" functionality
+   normally associated with IMAP.  Of course the other capabilities of
+
+
+
+Myers & Rose                Standards Track                    [Page 16]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+   IMAP, such as polling an existing connection for newly arrived
+   messages and supporting multiple folders on the server, are not
+   present in POP3.
+
+   When these facilities are used in this way by casual users, there has
+   been a tendency for already-read messages to accumulate on the server
+   without bound.  This is clearly an undesirable behavior pattern from
+   the standpoint of the server operator.  This situation is aggravated
+   by the fact that the limited capabilities of the POP3 do not permit
+   efficient handling of maildrops which have hundreds or thousands of
+   messages.
+
+   Consequently, it is recommended that operators of large-scale multi-
+   user servers, especially ones in which the user's only access to the
+   maildrop is via POP3, consider such options as:
+
+   *  Imposing a per-user maildrop storage quota or the like.
+
+      A disadvantage to this option is that accumulation of messages may
+      result in the user's inability to receive new ones into the
+      maildrop.  Sites which choose this option should be sure to inform
+      users of impending or current exhaustion of quota, perhaps by
+      inserting an appropriate message into the user's maildrop.
+
+   *  Enforce a site policy regarding mail retention on the server.
+
+      Sites are free to establish local policy regarding the storage and
+      retention of messages on the server, both read and unread.  For
+      example, a site might delete unread messages from the server after
+      60 days and delete read messages after 7 days.  Such message
+      deletions are outside the scope of the POP3 protocol and are not
+      considered a protocol violation.
+
+      Server operators enforcing message deletion policies should take
+      care to make all users aware of the policies in force.
+
+      Clients must not assume that a site policy will automate message
+      deletions, and should continue to explicitly delete messages using
+      the DELE command when appropriate.
+
+      It should be noted that enforcing site message deletion policies
+      may be confusing to the user community, since their POP3 client
+      may contain configuration options to leave mail on the server
+      which will not in fact be supported by the server.
+
+      One special case of a site policy is that messages may only be
+      downloaded once from the server, and are deleted after this has
+      been accomplished.  This could be implemented in POP3 server
+
+
+
+Myers & Rose                Standards Track                    [Page 17]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+      software by the following mechanism: "following a POP3 login by a
+      client which was ended by a QUIT, delete all messages downloaded
+      during the session with the RETR command".  It is important not to
+      delete messages in the event of abnormal connection termination
+      (ie, if no QUIT was received from the client) because the client
+      may not have successfully received or stored the messages.
+      Servers implementing a download-and-delete policy may also wish to
+      disable or limit the optional TOP command, since it could be used
+      as an alternate mechanism to download entire messages.
+
+9. POP3 Command Summary
+
+      Minimal POP3 Commands:
+
+         USER name               valid in the AUTHORIZATION state
+         PASS string
+         QUIT
+
+         STAT                    valid in the TRANSACTION state
+         LIST [msg]
+         RETR msg
+         DELE msg
+         NOOP
+         RSET
+         QUIT
+
+      Optional POP3 Commands:
+
+         APOP name digest        valid in the AUTHORIZATION state
+
+         TOP msg n               valid in the TRANSACTION state
+         UIDL [msg]
+
+      POP3 Replies:
+
+         +OK
+         -ERR
+
+      Note that with the exception of the STAT, LIST, and UIDL commands,
+      the reply given by the POP3 server to any command is significant
+      only to "+OK" and "-ERR".  Any text occurring after this reply
+      may be ignored by the client.
+
+
+
+
+
+
+
+
+
+Myers & Rose                Standards Track                    [Page 18]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+10. Example POP3 Session
+
+      S: <wait for connection on TCP port 110>
+      C: <open connection>
+      S:    +OK POP3 server ready <1896.697170952@dbc.mtview.ca.us>
+      C:    APOP mrose c4c9334bac560ecc979e58001b3e22fb
+      S:    +OK mrose's maildrop has 2 messages (320 octets)
+      C:    STAT
+      S:    +OK 2 320
+      C:    LIST
+      S:    +OK 2 messages (320 octets)
+      S:    1 120
+      S:    2 200
+      S:    .
+      C:    RETR 1
+      S:    +OK 120 octets
+      S:    <the POP3 server sends message 1>
+      S:    .
+      C:    DELE 1
+      S:    +OK message 1 deleted
+      C:    RETR 2
+      S:    +OK 200 octets
+      S:    <the POP3 server sends message 2>
+      S:    .
+      C:    DELE 2
+      S:    +OK message 2 deleted
+      C:    QUIT
+      S:    +OK dewey POP3 server signing off (maildrop empty)
+      C:  <close connection>
+      S:  <wait for next connection>
+
+11. Message Format
+
+   All messages transmitted during a POP3 session are assumed to conform
+   to the standard for the format of Internet text messages [RFC822].
+
+   It is important to note that the octet count for a message on the
+   server host may differ from the octet count assigned to that message
+   due to local conventions for designating end-of-line.  Usually,
+   during the AUTHORIZATION state of the POP3 session, the POP3 server
+   can calculate the size of each message in octets when it opens the
+   maildrop.  For example, if the POP3 server host internally represents
+   end-of-line as a single character, then the POP3 server simply counts
+   each occurrence of this character in a message as two octets.  Note
+   that lines in the message which start with the termination octet need
+   not (and must not) be counted twice, since the POP3 client will
+   remove all byte-stuffed termination characters when it receives a
+   multi-line response.
+
+
+
+Myers & Rose                Standards Track                    [Page 19]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+12. References
+
+   [RFC821] Postel, J., "Simple Mail Transfer Protocol", STD 10, RFC
+       821, USC/Information Sciences Institute, August 1982.
+
+   [RFC822] Crocker, D., "Standard for the Format of ARPA-Internet Text
+       Messages", STD 11, RFC 822, University of Delaware, August 1982.
+
+   [RFC1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+       MIT Laboratory for Computer Science, April 1992.
+
+   [RFC1730] Crispin, M., "Internet Message Access Protocol - Version
+       4", RFC 1730, University of Washington, December 1994.
+
+   [RFC1734] Myers, J., "POP3 AUTHentication command", RFC 1734,
+       Carnegie Mellon, December 1994.
+
+13. Security Considerations
+
+   It is conjectured that use of the APOP command provides origin
+   identification and replay protection for a POP3 session.
+   Accordingly, a POP3 server which implements both the PASS and APOP
+   commands should not allow both methods of access for a given user;
+   that is, for a given mailbox name, either the USER/PASS command
+   sequence or the APOP command is allowed, but not both.
+
+   Further, note that as the length of the shared secret increases, so
+   does the difficulty of deriving it.
+
+   Servers that answer -ERR to the USER command are giving potential
+   attackers clues about which names are valid.
+
+   Use of the PASS command sends passwords in the clear over the
+   network.
+
+   Use of the RETR and TOP commands sends mail in the clear over the
+   network.
+
+   Otherwise, security issues are not discussed in this memo.
+
+14. Acknowledgements
+
+   The POP family has a long and checkered history.  Although primarily
+   a minor revision to RFC 1460, POP3 is based on the ideas presented in
+   RFCs 918, 937, and 1081.
+
+   In addition, Alfred Grimstad, Keith McCloghrie, and Neil Ostroff
+   provided significant comments on the APOP command.
+
+
+
+Myers & Rose                Standards Track                    [Page 20]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+15. Authors' Addresses
+
+   John G. Myers
+   Carnegie-Mellon University
+   5000 Forbes Ave
+   Pittsburgh, PA 15213
+
+   EMail: jgm+@cmu.edu
+
+
+   Marshall T. Rose
+   Dover Beach Consulting, Inc.
+   420 Whisman Court
+   Mountain View, CA  94043-2186
+
+   EMail: mrose@dbc.mtview.ca.us
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers & Rose                Standards Track                    [Page 21]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+Appendix A. Differences from RFC 1725
+
+   This memo is a revision to RFC 1725, a Draft Standard.  It makes the
+   following changes from that document:
+
+      - clarifies that command keywords are case insensitive.
+
+      - specifies that servers must send "+OK" and "-ERR" in
+        upper case.
+
+      - specifies that the initial greeting is a positive response,
+        instead of any string which should be a positive response.
+
+      - clarifies behavior for unimplemented commands.
+
+      - makes the USER and PASS commands optional.
+
+      - clarified the set of possible responses to the USER command.
+
+      - reverses the order of the examples in the USER and PASS
+        commands, to reduce confusion.
+
+      - clarifies that the PASS command may only be given immediately
+        after a successful USER command.
+
+      - clarified the persistence requirements of UIDs and added some
+        implementation notes.
+
+      - specifies a UID length limitation of one to 70 octets.
+
+      - specifies a status indicator length limitation
+        of 512 octets, including the CRLF.
+
+      - clarifies that LIST with no arguments on an empty mailbox
+        returns success.
+
+      - adds a reference from the LIST command to the Message Format
+        section
+
+      - clarifies the behavior of QUIT upon failure
+
+      - clarifies the security section to not imply the use of the
+        USER command with the APOP command.
+
+      - adds references to RFCs 1730 and 1734
+
+      - clarifies the method by which a UA may enter mail into the
+        transport system.
+
+
+
+Myers & Rose                Standards Track                    [Page 22]
+\f
+RFC 1939                          POP3                          May 1996
+
+
+      - clarifies that the second argument to the TOP command is a
+        number of lines.
+
+      - changes the suggestion in the Security Considerations section
+        for a server to not accept both PASS and APOP for a given user
+        from a "must" to a "should".
+
+      - adds a section on scaling and operational considerations
+
+Appendix B. Command Index
+
+       APOP .......................................................   15
+       DELE .......................................................    8
+       LIST .......................................................    6
+       NOOP .......................................................    9
+       PASS .......................................................   14
+       QUIT .......................................................    5
+       QUIT .......................................................   10
+       RETR .......................................................    8
+       RSET .......................................................    9
+       STAT .......................................................    6
+       TOP ........................................................   11
+       UIDL .......................................................   12
+       USER .......................................................   13
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers & Rose                Standards Track                    [Page 23]
+\f
diff --git a/doc/rfc2104.txt b/doc/rfc2104.txt
new file mode 100644 (file)
index 0000000..1fb8fe1
--- /dev/null
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group                                       H. Krawczyk
+Request for Comments: 2104                                          IBM
+Category: Informational                                      M. Bellare
+                                                                   UCSD
+                                                             R. Canetti
+                                                                    IBM
+                                                          February 1997
+
+
+             HMAC: Keyed-Hashing for Message Authentication
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+Abstract
+
+   This document describes HMAC, a mechanism for message authentication
+   using cryptographic hash functions. HMAC can be used with any
+   iterative cryptographic hash function, e.g., MD5, SHA-1, in
+   combination with a secret shared key.  The cryptographic strength of
+   HMAC depends on the properties of the underlying hash function.
+
+1. Introduction
+
+   Providing a way to check the integrity of information transmitted
+   over or stored in an unreliable medium is a prime necessity in the
+   world of open computing and communications. Mechanisms that provide
+   such integrity check based on a secret key are usually called
+   "message authentication codes" (MAC). Typically, message
+   authentication codes are used between two parties that share a secret
+   key in order to validate information transmitted between these
+   parties. In this document we present such a MAC mechanism based on
+   cryptographic hash functions. This mechanism, called HMAC, is based
+   on work by the authors [BCK1] where the construction is presented and
+   cryptographically analyzed. We refer to that work for the details on
+   the rationale and security analysis of HMAC, and its comparison to
+   other keyed-hash methods.
+
+
+
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 1]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+   HMAC can be used in combination with any iterated cryptographic hash
+   function. MD5 and SHA-1 are examples of such hash functions. HMAC
+   also uses a secret key for calculation and verification of the
+   message authentication values. The main goals behind this
+   construction are
+
+   * To use, without modifications, available hash functions.
+     In particular, hash functions that perform well in software,
+     and for which code is freely and widely available.
+
+   * To preserve the original performance of the hash function without
+     incurring a significant degradation.
+
+   * To use and handle keys in a simple way.
+
+   * To have a well understood cryptographic analysis of the strength of
+     the authentication mechanism based on reasonable assumptions on the
+     underlying hash function.
+
+   * To allow for easy replaceability of the underlying hash function in
+     case that faster or more secure hash functions are found or
+     required.
+
+   This document specifies HMAC using a generic cryptographic hash
+   function (denoted by H). Specific instantiations of HMAC need to
+   define a particular hash function. Current candidates for such hash
+   functions include SHA-1 [SHA], MD5 [MD5], RIPEMD-128/160 [RIPEMD].
+   These different realizations of HMAC will be denoted by HMAC-SHA1,
+   HMAC-MD5, HMAC-RIPEMD, etc.
+
+   Note: To the date of writing of this document MD5 and SHA-1 are the
+   most widely used cryptographic hash functions. MD5 has been recently
+   shown to be vulnerable to collision search attacks [Dobb].  This
+   attack and other currently known weaknesses of MD5 do not compromise
+   the use of MD5 within HMAC as specified in this document (see
+   [Dobb]); however, SHA-1 appears to be a cryptographically stronger
+   function. To this date, MD5 can be considered for use in HMAC for
+   applications where the superior performance of MD5 is critical.   In
+   any case, implementers and users need to be aware of possible
+   cryptanalytic developments regarding any of these cryptographic hash
+   functions, and the eventual need to replace the underlying hash
+   function. (See section 6 for more information on the security of
+   HMAC.)
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 2]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+2. Definition of HMAC
+
+   The definition of HMAC requires a cryptographic hash function, which
+   we denote by H, and a secret key K. We assume H to be a cryptographic
+   hash function where data is hashed by iterating a basic compression
+   function on blocks of data.   We denote by B the byte-length of such
+   blocks (B=64 for all the above mentioned examples of hash functions),
+   and by L the byte-length of hash outputs (L=16 for MD5, L=20 for
+   SHA-1).  The authentication key K can be of any length up to B, the
+   block length of the hash function.  Applications that use keys longer
+   than B bytes will first hash the key using H and then use the
+   resultant L byte string as the actual key to HMAC. In any case the
+   minimal recommended length for K is L bytes (as the hash output
+   length). See section 3 for more information on keys.
+
+   We define two fixed and different strings ipad and opad as follows
+   (the 'i' and 'o' are mnemonics for inner and outer):
+
+                   ipad = the byte 0x36 repeated B times
+                  opad = the byte 0x5C repeated B times.
+
+   To compute HMAC over the data `text' we perform
+
+                    H(K XOR opad, H(K XOR ipad, text))
+
+   Namely,
+
+    (1) append zeros to the end of K to create a B byte string
+        (e.g., if K is of length 20 bytes and B=64, then K will be
+         appended with 44 zero bytes 0x00)
+    (2) XOR (bitwise exclusive-OR) the B byte string computed in step
+        (1) with ipad
+    (3) append the stream of data 'text' to the B byte string resulting
+        from step (2)
+    (4) apply H to the stream generated in step (3)
+    (5) XOR (bitwise exclusive-OR) the B byte string computed in
+        step (1) with opad
+    (6) append the H result from step (4) to the B byte string
+        resulting from step (5)
+    (7) apply H to the stream generated in step (6) and output
+        the result
+
+   For illustration purposes, sample code based on MD5 is provided as an
+   appendix.
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 3]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+3. Keys
+
+   The key for HMAC can be of any length (keys longer than B bytes are
+   first hashed using H).  However, less than L bytes is strongly
+   discouraged as it would decrease the security strength of the
+   function.  Keys longer than L bytes are acceptable but the extra
+   length would not significantly increase the function strength. (A
+   longer key may be advisable if the randomness of the key is
+   considered weak.)
+
+   Keys need to be chosen at random (or using a cryptographically strong
+   pseudo-random generator seeded with a random seed), and periodically
+   refreshed.  (Current attacks do not indicate a specific recommended
+   frequency for key changes as these attacks are practically
+   infeasible.  However, periodic key refreshment is a fundamental
+   security practice that helps against potential weaknesses of the
+   function and keys, and limits the damage of an exposed key.)
+
+4. Implementation Note
+
+   HMAC is defined in such a way that the underlying hash function H can
+   be used with no modification to its code. In particular, it uses the
+   function H with the pre-defined initial value IV (a fixed value
+   specified by each iterative hash function to initialize its
+   compression function).  However, if desired, a performance
+   improvement can be achieved at the cost of (possibly) modifying the
+   code of H to support variable IVs.
+
+   The idea is that the intermediate results of the compression function
+   on the B-byte blocks (K XOR ipad) and (K XOR opad) can be precomputed
+   only once at the time of generation of the key K, or before its first
+   use. These intermediate results are stored and then used to
+   initialize the IV of H each time that a message needs to be
+   authenticated.  This method saves, for each authenticated message,
+   the application of the compression function of H on two B-byte blocks
+   (i.e., on (K XOR ipad) and (K XOR opad)). Such a savings may be
+   significant when authenticating short streams of data.  We stress
+   that the stored intermediate values need to be treated and protected
+   the same as secret keys.
+
+   Choosing to implement HMAC in the above way is a decision of the
+   local implementation and has no effect on inter-operability.
+
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 4]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+5. Truncated output
+
+   A well-known practice with message authentication codes is to
+   truncate the output of the MAC and output only part of the bits
+   (e.g., [MM, ANSI]).  Preneel and van Oorschot [PV] show some
+   analytical advantages of truncating the output of hash-based MAC
+   functions. The results in this area are not absolute as for the
+   overall security advantages of truncation. It has advantages (less
+   information on the hash result available to an attacker) and
+   disadvantages (less bits to predict for the attacker).  Applications
+   of HMAC can choose to truncate the output of HMAC by outputting the t
+   leftmost bits of the HMAC computation for some parameter t (namely,
+   the computation is carried in the normal way as defined in section 2
+   above but the end result is truncated to t bits). We recommend that
+   the output length t be not less than half the length of the hash
+   output (to match the birthday attack bound) and not less than 80 bits
+   (a suitable lower bound on the number of bits that need to be
+   predicted by an attacker).  We propose denoting a realization of HMAC
+   that uses a hash function H with t bits of output as HMAC-H-t. For
+   example, HMAC-SHA1-80 denotes HMAC computed using the SHA-1 function
+   and with the output truncated to 80 bits.  (If the parameter t is not
+   specified, e.g. HMAC-MD5, then it is assumed that all the bits of the
+   hash are output.)
+
+6. Security
+
+   The security of the message authentication mechanism presented here
+   depends on cryptographic properties of the hash function H: the
+   resistance to collision finding (limited to the case where the
+   initial value is secret and random, and where the output of the
+   function is not explicitly available to the attacker), and the
+   message authentication property of the compression function of H when
+   applied to single blocks (in HMAC these blocks are partially unknown
+   to an attacker as they contain the result of the inner H computation
+   and, in particular, cannot be fully chosen by the attacker).
+
+   These properties, and actually stronger ones, are commonly assumed
+   for hash functions of the kind used with HMAC. In particular, a hash
+   function for which the above properties do not hold would become
+   unsuitable for most (probably, all) cryptographic applications,
+   including alternative message authentication schemes based on such
+   functions.  (For a complete analysis and rationale of the HMAC
+   function the reader is referred to [BCK1].)
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 5]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+   Given the limited confidence gained so far as for the cryptographic
+   strength of candidate hash functions, it is important to observe the
+   following two properties of the HMAC construction and its secure use
+   for message authentication:
+
+   1. The construction is independent of the details of the particular
+   hash function H in use and then the latter can be replaced by any
+   other secure (iterative) cryptographic hash function.
+
+   2. Message authentication, as opposed to encryption, has a
+   "transient" effect. A published breaking of a message authentication
+   scheme would lead to the replacement of that scheme, but would have
+   no adversarial effect on information authenticated in the past.  This
+   is in sharp contrast with encryption, where information encrypted
+   today may suffer from exposure in the future if, and when, the
+   encryption algorithm is broken.
+
+   The strongest attack known against HMAC is based on the frequency of
+   collisions for the hash function H ("birthday attack") [PV,BCK2], and
+   is totally impractical for minimally reasonable hash functions.
+
+   As an example, if we consider a hash function like MD5 where the
+   output length equals L=16 bytes (128 bits) the attacker needs to
+   acquire the correct message authentication tags computed (with the
+   _same_ secret key K!) on about 2**64 known plaintexts.  This would
+   require the processing of at least 2**64 blocks under H, an
+   impossible task in any realistic scenario (for a block length of 64
+   bytes this would take 250,000 years in a continuous 1Gbps link, and
+   without changing the secret key K during all this time).  This attack
+   could become realistic only if serious flaws in the collision
+   behavior of the function H are discovered (e.g.  collisions found
+   after 2**30 messages). Such a discovery would determine the immediate
+   replacement of the function H (the effects of such failure would be
+   far more severe for the traditional uses of H in the context of
+   digital signatures, public key certificates, etc.).
+
+   Note: this attack needs to be strongly contrasted with regular
+   collision attacks on cryptographic hash functions where no secret key
+   is involved and where 2**64 off-line parallelizable (!) operations
+   suffice to find collisions.  The latter attack is approaching
+   feasibility [VW] while the birthday attack on HMAC is totally
+   impractical.  (In the above examples, if one uses a hash function
+   with, say, 160 bit of output then 2**64 should be replaced by 2**80.)
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 6]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+   A correct implementation of the above construction, the choice of
+   random (or cryptographically pseudorandom) keys, a secure key
+   exchange mechanism, frequent key refreshments, and good secrecy
+   protection of keys are all essential ingredients for the security of
+   the integrity verification mechanism provided by HMAC.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                      [Page 7]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+Appendix -- Sample Code
+
+   For the sake of illustration we provide the following sample code for
+   the implementation of HMAC-MD5 as well as some corresponding test
+   vectors (the code is based on MD5 code as described in [MD5]).
+
+/*
+** Function: hmac_md5
+*/
+
+void
+hmac_md5(text, text_len, key, key_len, digest)
+unsigned char*  text;                /* pointer to data stream */
+int             text_len;            /* length of data stream */
+unsigned char*  key;                 /* pointer to authentication key */
+int             key_len;             /* length of authentication key */
+caddr_t         digest;              /* caller digest to be filled in */
+
+{
+        MD5_CTX context;
+        unsigned char k_ipad[65];    /* inner padding -
+                                      * key XORd with ipad
+                                      */
+        unsigned char k_opad[65];    /* outer padding -
+                                      * key XORd with opad
+                                      */
+        unsigned char tk[16];
+        int i;
+        /* if key is longer than 64 bytes reset it to key=MD5(key) */
+        if (key_len > 64) {
+
+                MD5_CTX      tctx;
+
+                MD5Init(&tctx);
+                MD5Update(&tctx, key, key_len);
+                MD5Final(tk, &tctx);
+
+                key = tk;
+                key_len = 16;
+        }
+
+        /*
+         * the HMAC_MD5 transform looks like:
+         *
+         * MD5(K XOR opad, MD5(K XOR ipad, text))
+         *
+         * where K is an n byte key
+         * ipad is the byte 0x36 repeated 64 times
+
+
+
+Krawczyk, et. al.            Informational                      [Page 8]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+         * opad is the byte 0x5c repeated 64 times
+         * and text is the data being protected
+         */
+
+        /* start out by storing key in pads */
+        bzero( k_ipad, sizeof k_ipad);
+        bzero( k_opad, sizeof k_opad);
+        bcopy( key, k_ipad, key_len);
+        bcopy( key, k_opad, key_len);
+
+        /* XOR key with ipad and opad values */
+        for (i=0; i<64; i++) {
+                k_ipad[i] ^= 0x36;
+                k_opad[i] ^= 0x5c;
+        }
+        /*
+         * perform inner MD5
+         */
+        MD5Init(&context);                   /* init context for 1st
+                                              * pass */
+        MD5Update(&context, k_ipad, 64)      /* start with inner pad */
+        MD5Update(&context, text, text_len); /* then text of datagram */
+        MD5Final(digest, &context);          /* finish up 1st pass */
+        /*
+         * perform outer MD5
+         */
+        MD5Init(&context);                   /* init context for 2nd
+                                              * pass */
+        MD5Update(&context, k_opad, 64);     /* start with outer pad */
+        MD5Update(&context, digest, 16);     /* then results of 1st
+                                              * hash */
+        MD5Final(digest, &context);          /* finish up 2nd pass */
+}
+
+Test Vectors (Trailing '\0' of a character string not included in test):
+
+  key =         0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+  key_len =     16 bytes
+  data =        "Hi There"
+  data_len =    8  bytes
+  digest =      0x9294727a3638bb1c13f48ef8158bfc9d
+
+  key =         "Jefe"
+  data =        "what do ya want for nothing?"
+  data_len =    28 bytes
+  digest =      0x750c783e6ab0b503eaa86e310a5db738
+
+  key =         0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+
+
+Krawczyk, et. al.            Informational                      [Page 9]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+  key_len       16 bytes
+  data =        0xDDDDDDDDDDDDDDDDDDDD...
+                ..DDDDDDDDDDDDDDDDDDDD...
+                ..DDDDDDDDDDDDDDDDDDDD...
+                ..DDDDDDDDDDDDDDDDDDDD...
+                ..DDDDDDDDDDDDDDDDDDDD
+  data_len =    50 bytes
+  digest =      0x56be34521d144c88dbb8c733f0e8b3f6
+
+Acknowledgments
+
+   Pau-Chen Cheng, Jeff Kraemer, and Michael Oehler, have provided
+   useful comments on early drafts, and ran the first interoperability
+   tests of this specification. Jeff and Pau-Chen kindly provided the
+   sample code and test vectors that appear in the appendix.  Burt
+   Kaliski, Bart Preneel, Matt Robshaw, Adi Shamir, and Paul van
+   Oorschot have provided useful comments and suggestions during the
+   investigation of the HMAC construction.
+
+References
+
+   [ANSI]  ANSI X9.9, "American National Standard for Financial
+           Institution Message Authentication (Wholesale)," American
+           Bankers Association, 1981.   Revised 1986.
+
+   [Atk]   Atkinson, R., "IP Authentication Header", RFC 1826, August
+           1995.
+
+   [BCK1]  M. Bellare, R. Canetti, and H. Krawczyk,
+           "Keyed Hash Functions and Message Authentication",
+           Proceedings of Crypto'96, LNCS 1109, pp. 1-15.
+           (http://www.research.ibm.com/security/keyed-md5.html)
+
+   [BCK2]  M. Bellare, R. Canetti, and H. Krawczyk,
+           "Pseudorandom Functions Revisited: The Cascade Construction",
+           Proceedings of FOCS'96.
+
+   [Dobb]  H. Dobbertin, "The Status of MD5  After a Recent Attack",
+           RSA Labs' CryptoBytes, Vol. 2 No. 2, Summer 1996.
+           http://www.rsa.com/rsalabs/pubs/cryptobytes.html
+
+   [PV]    B. Preneel and P. van Oorschot, "Building fast MACs from hash
+           functions", Advances in Cryptology -- CRYPTO'95 Proceedings,
+           Lecture Notes in Computer Science, Springer-Verlag Vol.963,
+           1995, pp. 1-14.
+
+   [MD5]   Rivest, R., "The MD5 Message-Digest Algorithm",
+           RFC 1321, April 1992.
+
+
+
+Krawczyk, et. al.            Informational                     [Page 10]
+\f
+RFC 2104                          HMAC                     February 1997
+
+
+   [MM]    Meyer, S. and Matyas, S.M., Cryptography, New York Wiley,
+           1982.
+
+   [RIPEMD] H. Dobbertin, A. Bosselaers, and B. Preneel, "RIPEMD-160: A
+            strengthened version of RIPEMD", Fast Software Encryption,
+            LNCS Vol 1039, pp. 71-82.
+            ftp://ftp.esat.kuleuven.ac.be/pub/COSIC/bosselae/ripemd/.
+
+   [SHA]   NIST, FIPS PUB 180-1: Secure Hash Standard, April 1995.
+
+   [Tsu]   G. Tsudik, "Message authentication with one-way hash
+           functions", In Proceedings of Infocom'92, May 1992.
+           (Also in "Access Control and Policy Enforcement in
+            Internetworks", Ph.D. Dissertation, Computer Science
+            Department, University of Southern California, April 1991.)
+
+   [VW]    P. van Oorschot and M. Wiener, "Parallel Collision
+           Search with Applications to Hash Functions and Discrete
+           Logarithms", Proceedings of the 2nd ACM Conf. Computer and
+           Communications Security, Fairfax, VA, November 1994.
+
+Authors' Addresses
+
+   Hugo Krawczyk
+   IBM T.J. Watson Research Center
+   P.O.Box 704
+   Yorktown Heights, NY 10598
+
+   EMail: hugo@watson.ibm.com
+
+   Mihir Bellare
+   Dept of Computer Science and Engineering
+   Mail Code 0114
+   University of California at San Diego
+   9500 Gilman Drive
+   La Jolla, CA 92093
+
+   EMail: mihir@cs.ucsd.edu
+
+   Ran Canetti
+   IBM T.J. Watson Research Center
+   P.O.Box 704
+   Yorktown Heights, NY 10598
+
+   EMail: canetti@watson.ibm.com
+
+
+
+
+
+
+Krawczyk, et. al.            Informational                     [Page 11]
+\f
diff --git a/doc/rfc2195.txt b/doc/rfc2195.txt
new file mode 100644 (file)
index 0000000..4a2725b
--- /dev/null
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+Network Working Group                                       J. Klensin
+Request for Comments: 2195                                    R. Catoe
+Category: Standards Track                                 P. Krumviede
+Obsoletes: 2095                                                    MCI
+                                                        September 1997
+
+
+       IMAP/POP AUTHorize Extension for Simple Challenge/Response
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Abstract
+
+   While IMAP4 supports a number of strong authentication mechanisms as
+   described in RFC 1731, it lacks any mechanism that neither passes
+   cleartext, reusable passwords across the network nor requires either
+   a significant security infrastructure or that the mail server update
+   a mail-system-wide user authentication file on each mail access.
+   This specification provides a simple challenge-response
+   authentication protocol that is suitable for use with IMAP4.  Since
+   it utilizes Keyed-MD5 digests and does not require that the secret be
+   stored in the clear on the server, it may also constitute an
+   improvement on APOP for POP3 use as specified in RFC 1734.
+
+1. Introduction
+
+   Existing Proposed Standards specify an AUTHENTICATE mechanism for the
+   IMAP4 protocol [IMAP, IMAP-AUTH] and a parallel AUTH mechanism for
+   the POP3 protocol [POP3-AUTH].  The AUTHENTICATE mechanism is
+   intended to be extensible; the four methods specified in [IMAP-AUTH]
+   are all fairly powerful and require some security infrastructure to
+   support.  The base POP3 specification [POP3] also contains a
+   lightweight challenge-response mechanism called APOP.  APOP is
+   associated with most of the risks associated with such protocols: in
+   particular, it requires that both the client and server machines have
+   access to the shared secret in cleartext form. CRAM offers a method
+   for avoiding such cleartext storage while retaining the algorithmic
+   simplicity of APOP in using only MD5, though in a "keyed" method.
+
+
+
+
+
+
+
+Klensin, Catoe & Krumviede  Standards Track                     [Page 1]
+\f
+RFC 2195              IMAP/POP AUTHorize Extension        September 1997
+
+
+   At present, IMAP [IMAP] lacks any facility corresponding to APOP.
+   The only alternative to the strong mechanisms identified in [IMAP-
+   AUTH] is a presumably cleartext username and password, supported
+   through the LOGIN command in [IMAP].  This document describes a
+   simple challenge-response mechanism, similar to APOP and PPP CHAP
+   [PPP], that can be used with IMAP (and, in principle, with POP3).
+
+   This mechanism also has the advantage over some possible alternatives
+   of not requiring that the server maintain information about email
+   "logins" on a per-login basis.  While mechanisms that do require such
+   per-login history records may offer enhanced security, protocols such
+   as IMAP, which may have several connections between a given client
+   and server open more or less simultaneous, may make their
+   implementation particularly challenging.
+
+2. Challenge-Response Authentication Mechanism (CRAM)
+
+   The authentication type associated with CRAM is "CRAM-MD5".
+
+   The data encoded in the first ready response contains an
+   presumptively arbitrary string of random digits, a timestamp, and the
+   fully-qualified primary host name of the server.  The syntax of the
+   unencoded form must correspond to that of an RFC 822 'msg-id'
+   [RFC822] as described in [POP3].
+
+   The client makes note of the data and then responds with a string
+   consisting of the user name, a space, and a 'digest'.  The latter is
+   computed by applying the keyed MD5 algorithm from [KEYED-MD5] where
+   the key is a shared secret and the digested text is the timestamp
+   (including angle-brackets).
+
+   This shared secret is a string known only to the client and server.
+   The `digest' parameter itself is a 16-octet value which is sent in
+   hexadecimal format, using lower-case ASCII characters.
+
+   When the server receives this client response, it verifies the digest
+   provided.  If the digest is correct, the server should consider the
+   client authenticated and respond appropriately.
+
+   Keyed MD5 is chosen for this application because of the greater
+   security imparted to authentication of short messages. In addition,
+   the use of the techniques described in [KEYED-MD5] for precomputation
+   of intermediate results make it possible to avoid explicit cleartext
+   storage of the shared secret on the server system by instead storing
+   the intermediate results which are known as "contexts".
+
+
+
+
+
+
+Klensin, Catoe & Krumviede  Standards Track                     [Page 2]
+\f
+RFC 2195              IMAP/POP AUTHorize Extension        September 1997
+
+
+   CRAM does not support a protection mechanism.
+
+   Example:
+
+   The examples in this document show the use of the CRAM mechanism with
+   the IMAP4 AUTHENTICATE command [IMAP-AUTH].  The base64 encoding of
+   the challenges and responses is part of the IMAP4 AUTHENTICATE
+   command, not part of the CRAM specification itself.
+
+     S: * OK IMAP4 Server
+     C: A0001 AUTHENTICATE CRAM-MD5
+     S: + PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
+     C: dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
+     S: A0001 OK CRAM authentication successful
+
+      In this example, the shared secret is the string
+      'tanstaaftanstaaf'.  Hence, the Keyed MD5 digest is produced by
+      calculating
+
+        MD5((tanstaaftanstaaf XOR opad),
+            MD5((tanstaaftanstaaf XOR ipad),
+            <1896.697170952@postoffice.reston.mci.net>))
+
+      where ipad and opad are as defined in the keyed-MD5 Work in
+      Progress [KEYED-MD5] and the string shown in the challenge is the
+      base64 encoding of <1896.697170952@postoffice.reston.mci.net>. The
+      shared secret is null-padded to a length of 64 bytes. If the
+      shared secret is longer than 64 bytes, the MD5 digest of the
+      shared secret is used as a 16 byte input to the keyed MD5
+      calculation.
+
+      This produces a digest value (in hexadecimal) of
+
+           b913a602c7eda7a495b4e6e7334d3890
+
+      The user name is then prepended to it, forming
+
+           tim b913a602c7eda7a495b4e6e7334d3890
+
+      Which is then base64 encoded to meet the requirements of the IMAP4
+      AUTHENTICATE command (or the similar POP3 AUTH command), yielding
+
+           dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
+
+
+
+
+
+
+
+
+Klensin, Catoe & Krumviede  Standards Track                     [Page 3]
+\f
+RFC 2195              IMAP/POP AUTHorize Extension        September 1997
+
+
+3. References
+
+   [CHAP]  Lloyd, B., and W. Simpson, "PPP Authentication Protocols",
+       RFC 1334, October 1992.
+
+   [IMAP] Crispin, M., "Internet Message Access Protocol - Version
+       4rev1", RFC 2060, University of Washington, December 1996.
+
+   [IMAP-AUTH] Myers, J., "IMAP4 Authentication Mechanisms",
+       RFC 1731, Carnegie Mellon, December 1994.
+
+   [KEYED-MD5] Krawczyk, Bellare, Canetti, "HMAC: Keyed-Hashing for
+       Message Authentication", RFC 2104, February 1997.
+
+   [MD5]  Rivest, R., "The MD5 Message Digest Algorithm",
+       RFC 1321, MIT Laboratory for Computer Science, April 1992.
+
+   [POP3] Myers, J., and M. Rose, "Post Office Protocol - Version 3",
+       STD 53, RFC 1939, Carnegie Mellon, May 1996.
+
+   [POP3-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734,
+       Carnegie Mellon, December, 1994.
+
+4. Security Considerations
+
+   It is conjectured that use of the CRAM authentication mechanism
+   provides origin identification and replay protection for a session.
+   Accordingly, a server that implements both a cleartext password
+   command and this authentication type should not allow both methods of
+   access for a given user.
+
+   While the saving, on the server, of "contexts" (see section 2) is
+   marginally better than saving the shared secrets in cleartext as is
+   required by CHAP [CHAP] and APOP [POP3], it is not sufficient to
+   protect the secrets if the server itself is compromised.
+   Consequently, servers that store the secrets or contexts must both be
+   protected to a level appropriate to the potential information value
+   in user mailboxes and identities.
+
+   As the length of the shared secret increases, so does the difficulty
+   of deriving it.
+
+   While there are now suggestions in the literature that the use of MD5
+   and keyed MD5 in authentication procedures probably has a limited
+   effective lifetime, the technique is now widely deployed and widely
+   understood.  It is believed that this general understanding may
+   assist with the rapid replacement, by CRAM-MD5, of the current uses
+   of permanent cleartext passwords in IMAP.   This document has been
+
+
+
+Klensin, Catoe & Krumviede  Standards Track                     [Page 4]
+\f
+RFC 2195              IMAP/POP AUTHorize Extension        September 1997
+
+
+   deliberately written to permit easy upgrading to use SHA (or whatever
+   alternatives emerge) when they are considered to be widely available
+   and adequately safe.
+
+   Even with the use of CRAM, users are still vulnerable to active
+   attacks.  An example of an increasingly common active attack is 'TCP
+   Session Hijacking' as described in CERT Advisory CA-95:01 [CERT95].
+
+   See section 1 above for additional discussion.
+
+5. Acknowledgements
+
+   This memo borrows ideas and some text liberally from [POP3] and
+   [RFC-1731] and thanks are due the authors of those documents.  Ran
+   Atkinson made a number of valuable technical and editorial
+   contributions to the document.
+
+6. Authors' Addresses
+
+   John C. Klensin
+   MCI Telecommunications
+   800 Boylston St, 7th floor
+   Boston, MA 02199
+   USA
+
+   EMail: klensin@mci.net
+   Phone: +1 617 960 1011
+
+   Randy Catoe
+   MCI Telecommunications
+   2100 Reston Parkway
+   Reston, VA 22091
+   USA
+
+   EMail: randy@mci.net
+   Phone: +1 703 715 7366
+
+   Paul Krumviede
+   MCI Telecommunications
+   2100 Reston Parkway
+   Reston, VA 22091
+   USA
+
+   EMail: paul@mci.net
+   Phone: +1 703 715 7251
+
+
+
+
+
+
+Klensin, Catoe & Krumviede  Standards Track                     [Page 5]
+\f
diff --git a/doc/rfc2222.txt b/doc/rfc2222.txt
new file mode 100644 (file)
index 0000000..2b0a2ab
--- /dev/null
@@ -0,0 +1,899 @@
+
+
+
+
+
+
+Network Working Group                                           J. Myers
+Request for Comments: 2222                       Netscape Communications
+Category: Standards Track                                   October 1997
+
+
+            Simple Authentication and Security Layer (SASL)
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+Table of Contents
+
+   1.    Abstract ..............................................    2
+   2.    Organization of this Document .........................    2
+   2.1.  How to Read This Document .............................    2
+   2.2.  Conventions Used in this Document .....................    2
+   2.3.  Examples ..............................................    3
+   3.    Introduction and Overview .............................    3
+   4.    Profiling requirements ................................    4
+   5.    Specific issues .......................................    5
+   5.1.  Client sends data first ...............................    5
+   5.2.  Server returns success with additional data ...........    5
+   5.3.  Multiple authentications ..............................    5
+   6.    Registration procedures ...............................    6
+   6.1.  Comments on SASL mechanism registrations ..............    6
+   6.2.  Location of Registered SASL Mechanism List ............    6
+   6.3.  Change Control ........................................    7
+   6.4.  Registration Template .................................    7
+   7.    Mechanism definitions .................................    8
+   7.1.  Kerberos version 4 mechanism ..........................    8
+   7.2.  GSSAPI mechanism ......................................    9
+   7.2.1 Client side of authentication protocol exchange .......    9
+   7.2.2 Server side of authentication protocol exchange .......   10
+   7.2.3 Security layer ........................................   11
+   7.3.  S/Key mechanism .......................................   11
+   7.4.  External mechanism ....................................   12
+   8.    References ............................................   13
+   9.    Security Considerations ...............................   13
+   10.   Author's Address ......................................   14
+
+
+
+Myers                       Standards Track                     [Page 1]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   Appendix A. Relation of SASL to Transport Security ..........   15
+   Full Copyright Statement ....................................   16
+
+1.    Abstract
+
+   This document describes a method for adding authentication support to
+   connection-based protocols.  To use this specification, a protocol
+   includes a command for identifying and authenticating a user to a
+   server and for optionally negotiating protection of subsequent
+   protocol interactions.  If its use is negotiated, a security layer is
+   inserted between the protocol and the connection.  This document
+   describes how a protocol specifies such a command, defines several
+   mechanisms for use by the command, and defines the protocol used for
+   carrying a negotiated security layer over the connection.
+
+2.    Organization of this Document
+
+2.1.  How to Read This Document
+
+   This document is written to serve two different audiences, protocol
+   designers using this specification to support authentication in their
+   protocol, and implementors of clients or servers for those protocols
+   using this specification.
+
+   The sections "Introduction and Overview", "Profiling requirements",
+   and "Security Considerations" cover issues that protocol designers
+   need to understand and address in profiling this specification for
+   use in a specific protocol.
+
+   Implementors of a protocol using this specification need the
+   protocol-specific profiling information in addition to the
+   information in this document.
+
+2.2.  Conventions Used in this Document
+
+   In examples, "C:" and "S:" indicate lines sent by the client and
+   server respectively.
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [RFC 2119].
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 2]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+2.3.  Examples
+
+   Examples in this document are for the IMAP profile [RFC 2060] of this
+   specification.  The base64 encoding of challenges and responses, as
+   well as the "+ " preceding the responses are part of the IMAP4
+   profile, not part of the SASL specification itself.
+
+3.    Introduction and Overview
+
+   The Simple Authentication and Security Layer (SASL) is a method for
+   adding authentication support to connection-based protocols.  To use
+   this specification, a protocol includes a command for identifying and
+   authenticating a user to a server and for optionally negotiating a
+   security layer for subsequent protocol interactions.
+
+   The command has a required argument identifying a SASL mechanism.
+   SASL mechanisms are named by strings, from 1 to 20 characters in
+   length, consisting of upper-case letters, digits, hyphens, and/or
+   underscores.  SASL mechanism names must be registered with the IANA.
+   Procedures for registering new SASL mechanisms are given in the
+   section "Registration procedures"
+
+   If a server supports the requested mechanism, it initiates an
+   authentication protocol exchange.  This consists of a series of
+   server challenges and client responses that are specific to the
+   requested mechanism.  The challenges and responses are defined by the
+   mechanisms as binary tokens of arbitrary length.  The protocol's
+   profile then specifies how these binary tokens are then encoded for
+   transfer over the connection.
+
+   After receiving the authentication command or any client response, a
+   server may issue a challenge, indicate failure, or indicate
+   completion.  The protocol's profile specifies how the server
+   indicates which of the above it is doing.
+
+   After receiving a challenge, a client may issue a response or abort
+   the exchange.  The protocol's profile specifies how the client
+   indicates which of the above it is doing.
+
+   During the authentication protocol exchange, the mechanism performs
+   authentication, transmits an authorization identity (frequently known
+   as a userid) from the client to server, and negotiates the use of a
+   mechanism-specific security layer.  If the use of a security layer is
+   agreed upon, then the mechanism must also define or negotiate the
+   maximum cipher-text buffer size that each side is able to receive.
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 3]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The transmitted authorization identity may be different than the
+   identity in the client's authentication credentials.  This permits
+   agents such as proxy servers to authenticate using their own
+   credentials, yet request the access privileges of the identity for
+   which they are proxying.  With any mechanism, transmitting an
+   authorization identity of the empty string directs the server to
+   derive an authorization identity from the client's authentication
+   credentials.
+
+   If use of a security layer is negotiated, it is applied to all
+   subsequent data sent over the connection.  The security layer takes
+   effect immediately following the last response of the authentication
+   exchange for data sent by the client and the completion indication
+   for data sent by the server.  Once the security layer is in effect,
+   the protocol stream is processed by the security layer into buffers
+   of cipher-text.  Each buffer is transferred over the connection as a
+   stream of octets prepended with a four octet field in network byte
+   order that represents the length of the following buffer.  The length
+   of the cipher-text buffer must be no larger than the maximum size
+   that was defined or negotiated by the other side.
+
+4.    Profiling requirements
+
+   In order to use this specification, a protocol definition must supply
+   the following information:
+
+   1. A service name, to be selected from the IANA registry of "service"
+      elements for the GSSAPI host-based service name form [RFC 2078].
+
+   2. A definition of the command to initiate the authentication
+      protocol exchange.  This command must have as a parameter the
+      mechanism name being selected by the client.
+
+      The command SHOULD have an optional parameter giving an initial
+      response.  This optional parameter allows the client to avoid a
+      round trip when using a mechanism which is defined to have the
+      client send data first.  When this initial response is sent by the
+      client and the selected mechanism is defined to have the server
+      start with an initial challenge, the command fails.  See section
+      5.1 of this document for further information.
+
+   3. A definition of the method by which the authentication protocol
+      exchange is carried out, including how the challenges and
+      responses are encoded, how the server indicates completion or
+      failure of the exchange, how the client aborts an exchange, and
+      how the exchange method interacts with any line length limits in
+      the protocol.
+
+
+
+
+Myers                       Standards Track                     [Page 4]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   4. Identification of the octet where any negotiated security layer
+      starts to take effect, in both directions.
+
+   5. A specification of how the authorization identity passed from the
+      client to the server is to be interpreted.
+
+5.    Specific issues
+
+5.1.  Client sends data first
+
+   Some mechanisms specify that the first data sent in the
+   authentication protocol exchange is from the client to the server.
+
+   If a protocol's profile permits the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, this parameter SHOULD be used with such mechanisms.
+
+   If the initial client response parameter is not given, or if a
+   protocol's profile does not permit the command which initiates an
+   authentication protocol exchange to contain an initial client
+   response, then the server issues a challenge with no data.  The
+   client's response to this challenge is then used as the initial
+   client response.  (The server then proceeds to send the next
+   challenge, indicates completion, or indicates failure.)
+
+5.2.  Server returns success with additional data
+
+   Some mechanisms may specify that server challenge data be sent to the
+   client along with an indication of successful completion of the
+   exchange.  This data would, for example, authenticate the server to
+   the client.
+
+   If a protocol's profile does not permit this server challenge to be
+   returned with a success indication, then the server issues the server
+   challenge without an indication of successful completion.  The client
+   then responds with no data.  After receiving this empty response, the
+   server then indicates successful completion.
+
+5.3.  Multiple authentications
+
+   Unless otherwise stated by the protocol's profile, only one
+   successful SASL negotiation may occur in a protocol session.  In this
+   case, once an authentication protocol exchange has successfully
+   completed, further attempts to initiate an authentication protocol
+   exchange fail.
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 5]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   In the case that a profile explicitly permits multiple successful
+   SASL negotiations to occur, then in no case may multiple security
+   layers be simultaneously in effect.  If a security layer is in effect
+   and a subsequent SASL negotiation selects no security layer, the
+   original security layer remains in effect.  If a security layer is in
+   effect and a subsequent SASL negotiation selects a second security
+   layer, then the second security layer replaces the first.
+
+6.    Registration procedures
+
+   Registration of a SASL mechanism is done by filling in the template
+   in section 6.4 and sending it in to iana@isi.edu.  IANA has the right
+   to reject obviously bogus registrations, but will perform no review
+   of clams made in the registration form.
+
+   There is no naming convention for SASL mechanisms; any name that
+   conforms to the syntax of a SASL mechanism name can be registered.
+
+   While the registration procedures do not require it, authors of SASL
+   mechanisms are encouraged to seek community review and comment
+   whenever that is feasible.  Authors may seek community review by
+   posting a specification of their proposed mechanism as an internet-
+   draft.  SASL mechanisms intended for widespread use should be
+   standardized through the normal IETF process, when appropriate.
+
+6.1.  Comments on SASL mechanism registrations
+
+   Comments on registered SASL mechanisms should first be sent to the
+   "owner" of the mechanism.  Submitters of comments may, after a
+   reasonable attempt to contact the owner, request IANA to attach their
+   comment to the SASL mechanism registration itself.  If IANA approves
+   of this the comment will be made accessible in conjunction with the
+   SASL mechanism registration itself.
+
+6.2.  Location of Registered SASL Mechanism List
+
+   SASL mechanism registrations will be posted in the anonymous FTP
+   directory "ftp://ftp.isi.edu/in-notes/iana/assignments/sasl-
+   mechanisms/" and all registered SASL mechanisms will be listed in the
+   periodically issued "Assigned Numbers" RFC [currently STD 2, RFC
+   1700].  The SASL mechanism description and other supporting material
+   may also be published as an Informational RFC by sending it to "rfc-
+   editor@isi.edu" (please follow the instructions to RFC authors [RFC
+   2223]).
+
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 6]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+6.3.  Change Control
+
+   Once a SASL mechanism registration has been published by IANA, the
+   author may request a change to its definition.  The change request
+   follows the same procedure as the registration request.
+
+   The owner of a SASL mechanism may pass responsibility for the SASL
+   mechanism to another person or agency by informing IANA; this can be
+   done without discussion or review.
+
+   The IESG may reassign responsibility for a SASL mechanism. The most
+   common case of this will be to enable changes to be made to
+   mechanisms where the author of the registration has died, moved out
+   of contact or is otherwise unable to make changes that are important
+   to the community.
+
+   SASL mechanism registrations may not be deleted; mechanisms which are
+   no longer believed appropriate for use can be declared OBSOLETE by a
+   change to their "intended use" field; such SASL mechanisms will be
+   clearly marked in the lists published by IANA.
+
+   The IESG is considered to be the owner of all SASL mechanisms which
+   are on the IETF standards track.
+
+6.4.  Registration Template
+
+   To: iana@iana.org
+   Subject: Registration of SASL mechanism X
+
+   SASL mechanism name:
+
+   Security considerations:
+
+   Published specification (optional, recommended):
+
+   Person & email address to contact for further information:
+
+   Intended usage:
+
+   (One of COMMON, LIMITED USE or OBSOLETE)
+
+   Author/Change controller:
+
+   (Any other information that the author deems interesting may be
+   added below this line.)
+
+
+
+
+
+
+Myers                       Standards Track                     [Page 7]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+7.    Mechanism definitions
+
+   The following mechanisms are hereby defined.
+
+7.1.  Kerberos version 4 mechanism
+
+   The mechanism name associated with Kerberos version 4 is
+   "KERBEROS_V4".
+
+   The first challenge consists of a random 32-bit number in network
+   byte order.  The client responds with a Kerberos ticket and an
+   authenticator for the principal "service.hostname@realm", where
+   "service" is the service name specified in the protocol's profile,
+   "hostname" is the first component of the host name of the server with
+   all letters in lower case, and where "realm" is the Kerberos realm of
+   the server.  The encrypted checksum field included within the
+   Kerberos authenticator contains the server provided challenge in
+   network byte order.
+
+   Upon decrypting and verifying the ticket and authenticator, the
+   server verifies that the contained checksum field equals the original
+   server provided random 32-bit number.  Should the verification be
+   successful, the server must add one to the checksum and construct 8
+   octets of data, with the first four octets containing the incremented
+   checksum in network byte order, the fifth octet containing a bit-mask
+   specifying the security layers supported by the server, and the sixth
+   through eighth octets containing, in network byte order, the maximum
+   cipher-text buffer size the server is able to receive.  The server
+   must encrypt using DES ECB mode the 8 octets of data in the session
+   key and issue that encrypted data in a second challenge.  The client
+   considers the server authenticated if the first four octets of the
+   un-encrypted data is equal to one plus the checksum it previously
+   sent.
+
+   The client must construct data with the first four octets containing
+   the original server-issued checksum in network byte order, the fifth
+   octet containing the bit-mask specifying the selected security layer,
+   the sixth through eighth octets containing in network byte order the
+   maximum cipher-text buffer size the client is able to receive, and
+   the following octets containing the authorization identity.  The
+   client must then append from one to eight zero-valued octets so that
+   the length of the data is a multiple of eight octets. The client must
+   then encrypt using DES PCBC mode the data with the session key and
+   respond with the encrypted data.  The server decrypts the data and
+   verifies the contained checksum.  The server must verify that the
+   principal identified in the Kerberos ticket is authorized to connect
+   as that authorization identity.  After this verification, the
+   authentication process is complete.
+
+
+
+Myers                       Standards Track                     [Page 8]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The security layers and their corresponding bit-masks are as follows:
+
+      1 No security layer
+      2 Integrity (krb_mk_safe) protection
+      4 Privacy (krb_mk_priv) protection
+
+   Other bit-masks may be defined in the future; bits which are not
+   understood must be negotiated off.
+
+   EXAMPLE: The following are two Kerberos version 4 login scenarios to
+   the IMAP4 protocol (note that the line breaks in the sample
+   authenticators are for editorial clarity and are not in real
+   authenticators)
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE KERBEROS_V4
+     S: + AmFYig==
+     C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+        +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
+        WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
+     S: + or//EoAADZI=
+     C: DiAF5A4gA+oOIALuBkAAmw==
+     S: A001 OK Kerberos V4 authentication successful
+
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE KERBEROS_V4
+     S: + gcfgCA==
+     C: BAcAQU5EUkVXLkNNVS5FRFUAOCAsho84kLN3/IJmrMG+25a4DT
+        +nZImJjnTNHJUtxAA+o0KPKfHEcAFs9a3CL5Oebe/ydHJUwYFd
+        WwuQ1MWiy6IesKvjL5rL9WjXUb9MwT9bpObYLGOKi1Qh
+     S: A001 NO Kerberos V4 authentication failed
+
+7.2.  GSSAPI mechanism
+
+   The mechanism name associated with all mechanisms employing the
+   GSSAPI [RFC 2078] is "GSSAPI".
+
+7.2.1 Client side of authentication protocol exchange
+
+   The client calls GSS_Init_sec_context, passing in 0 for
+   input_context_handle (initially) and a targ_name equal to output_name
+   from GSS_Import_Name called with input_name_type of
+   GSS_C_NT_HOSTBASED_SERVICE and input_name_string of
+   "service@hostname" where "service" is the service name specified in
+   the protocol's profile, and "hostname" is the fully qualified host
+   name of the server.  The client then responds with the resulting
+   output_token.  If GSS_Init_sec_context returns GSS_S_CONTINUE_NEEDED,
+
+
+
+Myers                       Standards Track                     [Page 9]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   then the client should expect the server to issue a token in a
+   subsequent challenge.  The client must pass the token to another call
+   to GSS_Init_sec_context, repeating the actions in this paragraph.
+
+   When GSS_Init_sec_context returns GSS_S_COMPLETE, the client takes
+   the following actions: If the last call to GSS_Init_sec_context
+   returned an output_token, then the client responds with the
+   output_token, otherwise the client responds with no data.  The client
+   should then expect the server to issue a token in a subsequent
+   challenge.  The client passes this token to GSS_Unwrap and interprets
+   the first octet of resulting cleartext as a bit-mask specifying the
+   security layers supported by the server and the second through fourth
+   octets as the maximum size output_message to send to the server.  The
+   client then constructs data, with the first octet containing the
+   bit-mask specifying the selected security layer, the second through
+   fourth octets containing in network byte order the maximum size
+   output_message the client is able to receive, and the remaining
+   octets containing the authorization identity.  The client passes the
+   data to GSS_Wrap with conf_flag set to FALSE, and responds with the
+   generated output_message.  The client can then consider the server
+   authenticated.
+
+7.2.2 Server side of authentication protocol exchange
+
+   The server passes the initial client response to
+   GSS_Accept_sec_context as input_token, setting input_context_handle
+   to 0 (initially).  If GSS_Accept_sec_context returns
+   GSS_S_CONTINUE_NEEDED, the server returns the generated output_token
+   to the client in challenge and passes the resulting response to
+   another call to GSS_Accept_sec_context, repeating the actions in this
+   paragraph.
+
+   When GSS_Accept_sec_context returns GSS_S_COMPLETE, the client takes
+   the following actions: If the last call to GSS_Accept_sec_context
+   returned an output_token, the server returns it to the client in a
+   challenge and expects a reply from the client with no data.  Whether
+   or not an output_token was returned (and after receipt of any
+   response from the client to such an output_token), the server then
+   constructs 4 octets of data, with the first octet containing a bit-
+   mask specifying the security layers supported by the server and the
+   second through fourth octets containing in network byte order the
+   maximum size output_token the server is able to receive.  The server
+   must then pass the plaintext to GSS_Wrap with conf_flag set to FALSE
+   and issue the generated output_message to the client in a challenge.
+   The server must then pass the resulting response to GSS_Unwrap and
+   interpret the first octet of resulting cleartext as the bit-mask for
+   the selected security layer, the second through fourth octets as the
+   maximum size output_message to send to the client, and the remaining
+
+
+
+Myers                       Standards Track                    [Page 10]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   octets as the authorization identity.  The server must verify that
+   the src_name is authorized to authenticate as the authorization
+   identity.  After these verifications, the authentication process is
+   complete.
+
+7.2.3 Security layer
+
+   The security layers and their corresponding bit-masks are as follows:
+
+     1 No security layer
+     2 Integrity protection.
+       Sender calls GSS_Wrap with conf_flag set to FALSE
+     4 Privacy protection.
+       Sender calls GSS_Wrap with conf_flag set to TRUE
+
+   Other bit-masks may be defined in the future; bits which are not
+   understood must be negotiated off.
+
+7.3.  S/Key mechanism
+
+   The mechanism name associated with S/Key [RFC 1760] using the MD4
+   digest algorithm is "SKEY".
+
+   The client sends an initial response with the authorization identity.
+
+   The server then issues a challenge which contains the decimal
+   sequence number followed by a single space and the seed string for
+   the indicated authorization identity.  The client responds with the
+   one-time-password, as either a 64-bit value in network byte order or
+   encoded in the "six English words" format.
+
+   The server must verify the one-time-password.  After this
+   verification, the authentication process is complete.
+
+   S/Key authentication does not provide for any security layers.
+
+   EXAMPLE: The following are two S/Key login scenarios in the IMAP4
+   protocol.
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE SKEY
+     S: +
+     C: bW9yZ2Fu
+     S: + OTUgUWE1ODMwOA==
+     C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
+     S: A001 OK S/Key authentication successful
+
+
+
+
+
+Myers                       Standards Track                    [Page 11]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+     S: * OK IMAP4 Server
+     C: A001 AUTHENTICATE SKEY
+     S: +
+     C: c21pdGg=
+     S: + OTUgUWE1ODMwOA==
+     C: BsAY3g4gBNo=
+     S: A001 NO S/Key authentication failed
+
+   The following is an S/Key login scenario in an IMAP4-like protocol
+   which has an optional "initial response" argument to the AUTHENTICATE
+   command.
+
+     S: * OK IMAP4-Like Server
+     C: A001 AUTHENTICATE SKEY bW9yZ2Fu
+     S: + OTUgUWE1ODMwOA==
+     C: Rk9VUiBNQU5OIFNPT04gRklSIFZBUlkgTUFTSA==
+     S: A001 OK S/Key authentication successful
+
+7.4.  External mechanism
+
+   The mechanism name associated with external authentication is
+   "EXTERNAL".
+
+   The client sends an initial response with the authorization identity.
+
+   The server uses information, external to SASL, to determine whether
+   the client is authorized to authenticate as the authorization
+   identity.  If the client is so authorized, the server indicates
+   successful completion of the authentication exchange; otherwise the
+   server indicates failure.
+
+   The system providing this external information may be, for example,
+   IPsec or TLS.
+
+   If the client sends the empty string as the authorization identity
+   (thus requesting the authorization identity be derived from the
+   client's authentication credentials), the authorization identity is
+   to be derived from authentication credentials which exist in the
+   system which is providing the external authentication.
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 12]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+8.    References
+
+   [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [RFC 2078] Linn, J., "Generic Security Service Application Program
+              Interface, Version 2", RFC 2078, January 1997.
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", RFC 2119, March 1997.
+
+   [RFC 2223] Postel, J., and J. Reynolds, "Instructions to RFC
+              Authors", RFC 2223, October 1997.
+
+   [RFC 1760] Haller, N., "The S/Key One-Time Password System", RFC
+              1760, February 1995.
+
+   [RFC 1700] Reynolds, J., and J. Postel, "Assigned Numbers", STD 2,
+              RFC 1700, October 1994.
+
+9.    Security Considerations
+
+   Security issues are discussed throughout this memo.
+
+   The mechanisms that support integrity protection are designed such
+   that the negotiation of the security layer and authorization identity
+   is integrity protected.  When the client selects a security layer
+   with at least integrity protection, this protects against an active
+   attacker hijacking the connection and modifying the authentication
+   exchange to negotiate a plaintext connection.
+
+   When a server or client supports multiple authentication mechanisms,
+   each of which has a different security strength, it is possible for
+   an active attacker to cause a party to use the least secure mechanism
+   supported.  To protect against this sort of attack, a client or
+   server which supports mechanisms of different strengths should have a
+   configurable minimum strength that it will use.  It is not sufficient
+   for this minimum strength check to only be on the server, since an
+   active attacker can change which mechanisms the client sees as being
+   supported, causing the client to send authentication credentials for
+   its weakest supported mechanism.
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 13]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+   The client's selection of a SASL mechanism is done in the clear and
+   may be modified by an active attacker.  It is important for any new
+   SASL mechanisms to be designed such that an active attacker cannot
+   obtain an authentication with weaker security properties by modifying
+   the SASL mechanism name and/or the challenges and responses.
+
+   Any protocol interactions prior to authentication are performed in
+   the clear and may be modified by an active attacker.  In the case
+   where a client selects integrity protection, it is important that any
+   security-sensitive protocol negotiations be performed after
+   authentication is complete.  Protocols should be designed such that
+   negotiations performed prior to authentication should be either
+   ignored or revalidated once authentication is complete.
+
+10.   Author's Address
+
+   John G. Myers
+   Netscape Communications
+   501 E. Middlefield Road
+   Mail Stop MV-029
+   Mountain View, CA 94043-4042
+
+   EMail: jgmyers@netscape.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 14]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+Appendix A. Relation of SASL to Transport Security
+
+   Questions have been raised about the relationship between SASL and
+   various services (such as IPsec and TLS) which provide a secured
+   connection.
+
+   Two of the key features of SASL are:
+
+   1. The separation of the authorization identity from the identity in
+      the client's credentials.  This permits agents such as proxy
+      servers to authenticate using their own credentials, yet request
+      the access privileges of the identity for which they are proxying.
+
+   2. Upon successful completion of an authentication exchange, the
+      server knows the authorization identity the client wishes to use.
+      This allows servers to move to a "user is authenticated" state in
+      the protocol.
+
+   These features are extremely important to some application protocols,
+   yet Transport Security services do not always provide them.  To
+   define SASL mechanisms based on these services would be a very messy
+   task, as the framing of these services would be redundant with the
+   framing of SASL and some method of providing these important SASL
+   features would have to be devised.
+
+   Sometimes it is desired to enable within an existing connection the
+   use of a security service which does not fit the SASL model.  (TLS is
+   an example of such a service.)  This can be done by adding a command,
+   for example "STARTTLS", to the protocol.  Such a command is outside
+   the scope of SASL, and should be different from the command which
+   starts a SASL authentication protocol exchange.
+
+   In certain situations, it is reasonable to use SASL underneath one of
+   these Transport Security services.  The transport service would
+   secure the connection, either service would authenticate the client,
+   and SASL would negotiate the authorization identity.  The SASL
+   negotiation would be what moves the protocol from "unauthenticated"
+   to "authenticated" state.  The "EXTERNAL" SASL mechanism is
+   explicitly intended to handle the case where the transport service
+   secures the connection and authenticates the client and SASL
+   negotiates the authorization identity.
+
+   When using SASL underneath a sufficiently strong Transport Security
+   service, a SASL security layer would most likely be redundant.  The
+   client and server would thus probably want to negotiate off the use
+   of a SASL security layer.
+
+
+
+
+
+Myers                       Standards Track                    [Page 15]
+\f
+RFC 2222                          SASL                      October 1997
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implmentation may be prepared, copied, published
+   andand distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Myers                       Standards Track                    [Page 16]
+\f
diff --git a/doc/rfc2243.txt b/doc/rfc2243.txt
new file mode 100644 (file)
index 0000000..0ad5a63
--- /dev/null
@@ -0,0 +1,563 @@
+
+
+
+
+
+
+Network Working Group                                           C. Metz
+Request for Comments: 2243                                The Inner Net
+Category: Standards Track                                 November 1997
+
+
+
+
+                         OTP Extended Responses
+
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+Abstract
+
+   This document provides a specification for a type of response to an
+   OTP [RFC 1938] challenge that carries explicit indication of the
+   response's encoding. Codings for the two mandatory OTP data formats
+   using this new type of response are presented.
+
+   This document also provides a specification for a response that
+   allows an OTP generator to request that a server re-initialize a
+   sequence and change parameters such as the secret pass phrase.
+
+1. Conventions, Terms, and Notation
+
+   This document specifies the data formats and software behaviors
+   needed to use OTP extended responses. The data formats are described
+   three ways: using an ad-hoc UNIX manual page style syntax, using
+   augmented BNF described in sections two and three of RFC 822, and by
+   examples. Should there be any conflict between these descriptions,
+   the augmented BNF takes precedence. The software behaviors are
+   described in words, and specific behavior compliance requirements are
+   itemized using the requirements terminology (specifically, the words
+   MUST, SHOULD, and MAY) defined in RFC 2119.
+
+
+
+
+
+
+
+Metz                        Standards Track                     [Page 1]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+2. Extended Challenges and Extended Responses
+
+   This document builds on the protocol and terminology specified in RFC
+   1938 and assumes that you have already read this document and
+   understand its contents.
+
+   An extended challenge is a single line of printable text terminated
+   by either a new line sequence appropriate for the context of its use
+   (e.g., ASCII CR followed by ASCII LF) or a whitespace character. It
+   contains a standard OTP challenge, a whitespace character, and a list
+   that generators use to determine which extended responses are
+   supported by a server.
+
+   An extended response is a single line of printable text terminated by
+   a new line sequence appropriate for the context of its use. It
+   contains two or more tokens that are separated with a single colon
+   (':') character. The first token contains a type specifier that
+   indicates the format of the rest of the response. The tokens that
+   follow are argument data for the OTP extended response. At least one
+   token of data MUST be present.
+
+2.1. Syntax
+
+   In UNIX manual page like syntax, the general form of an extended
+   challenge could be described as:
+
+      <standard OTP challenge> ext[,<extension set id>[, ...]]
+
+   And the general form of an extended response could be described as:
+
+      <type-specifier>:<arg1>[:<arg2>[:...]]
+
+   In augmented BNF syntax, the syntax of the general form of an
+   extended challenge and an extended response is:
+
+   extended-challenge = otp-challenge 1*LWSP-char capability-list
+                        (NL / *LWSP-char)
+   otp-challenge     = <a standard OTP challenge>
+   capability-list   = "ext" *("," extension-set-id)
+   extension-set-id  = *<any CHAR except LWSP, CTLs, or ",">
+   extended-response = type 1*(":" argument) NL
+   type              = token
+   argument          = token
+   token             = 1*<any CHAR except ":" and CTLs>
+   NL                = <new line sequence appropriate for the context
+                        in which OTP is being used>
+
+
+
+
+
+Metz                        Standards Track                     [Page 2]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   An example of an extended challenge indicating support for OTP
+   extended responses and for a mythical response set "foo" is:
+
+      otp-md5 123 mi1234 ext,foo
+
+   An example of an extended response using a mythical type named "foo"
+   is:
+
+      foo:some data:some more data:12345
+
+2.2. Requirements
+
+   A server compliant with this specification:
+
+      1. MUST be able to receive and parse the general form of an
+         extended response
+      2. MUST be able to receive, parse, and correctly process all
+         extended responses specified in this document
+      3. MUST process the type field in a case-insensitive manner
+      4. MUST reject any authentication attempt using an extended
+         response if it does not support that type of response
+      5. SHOULD provide an appropriate indication to the generator
+         if the response was rejected because of (4)
+      6. MUST limit the length of the input reasonably
+      7. MUST accept otherwise arbitrary amounts of whitespace
+         wherever a response allows it
+      8. MUST be able to receive and correctly process standard OTP
+         responses
+
+   A generator compliant with this specification:
+
+      1. MUST be able to generate standard OTP responses
+      2. MUST use standard responses unless an extended challenge
+         has been received for the particular server AND seed
+      3. MUST generate the type field in lower case
+      4. MUST NOT send a response type for which the server has not
+         indicated support through an extended challenge
+
+   Extension set identifiers and extension type identifiers named with
+   the prefix "x-" are reserved for private use among mutually
+   consenting implementations. Implementations that do not recognise a
+   particular "x-" extension MUST ignore that extension. This means that
+   all "x-" extensions are likely to be non-interoperable with other
+   extensions. Careful consideration should be given to the possibility
+   of a server interacting with with a generator implementation which,
+   although it recognizes a given "x-" extension, uses it for a
+   different purpose. All of the remaining extension namespace is
+   reserved to IANA, which will only officially assign the extension
+
+
+
+Metz                        Standards Track                     [Page 3]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   into this namespace after the IESG approves of such an assignment.
+   During the lifetime of the OTP WG, it is recommended that the IESG
+   consult with the OTP WG prior to approving such an assignment.
+
+3. The "hex" and "word" Responses
+
+   There exists a very rare case in which a standard OTP response could
+   be a valid coding in both the hexadecimal and six-word formats. An
+   example of this is the response "ABE ACE ADA ADD BAD A."  The
+   solution to this problem mandated by the OTP specification is that
+   compliant servers MUST attempt to parse and verify a standard
+   response in both hexadecimal and six-word formats and must consider
+   the authentication successful if either succeeds.
+
+   This problem can be solved easily using extended responses. The "hex"
+   response and the "word" response are two response types that encode
+   an OTP in an extended response that explicitly describes the
+   encoding. These responses start with a type label of "hex" for a
+   hexadecimal OTP and "word" for a six-word coded OTP. These responses
+   contain one argument field that contains a standard OTP response
+   coded in the indicated format.
+
+3.1. Syntax
+
+   In UNIX manual page like syntax, the format of these responses could
+   be described as:
+
+      hex:<hexadecimal number>
+      word:<six dictionary words>
+
+   In augmented BNF syntax and with the definitions already provided,
+   the syntax of these responses is:
+
+      hex-response  = "hex:" hex-64bit NL
+      hex-64bit     = 16(hex-char *LWSP-char)
+      hex-char      = ("A" / "B" / "C" / "D" / "E" / "F" /
+                       "a" / "b" / "c" / "d" / "e" / "f" /
+                       "0" / "1" / "2" / "3" / "4" / "5" /
+                       "6" / "7" / "8" / "9")
+
+      word-response = "word:" word-64bit NL
+      word-64bit    = 6(otp-word 1*LWSP-char)
+      otp-word      = <any valid word in the standard OTP coding
+                      dictionary>
+
+
+
+
+
+
+
+Metz                        Standards Track                     [Page 4]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   Examples of these responses are:
+
+      hex:8720 33d4 6202 9172
+      word:VAST SAUL TAKE SODA SUCH BOLT
+
+3.2. Requirements
+
+   A server compliant with this specification:
+
+      1. MUST process all arguments in a case-insensitive manner
+
+   A generator compliant with this specification:
+
+      1. SHOULD generate otp-word tokens in upper case with single
+         spaces separating them
+      2. SHOULD generate hexadecimal numbers using only lower case
+         for letters
+
+4. The "init-hex" and "init-word" Responses
+
+   The OTP specification requires that implementations provide a means
+   for a client to re-initialize or change its OTP information with a
+   server but does not require any specific protocol for doing it.
+   Implementations that support the OTP extended responses described in
+   this document MUST support the response with the "init-hex" and
+   "init-word" type specifiers, which provide a standard way for a
+   client to re-initialize its OTP information with a server. This
+   response is intended to be used only by automated clients. Because of
+   this, the recommended form of this response uses the hexadecimal
+   encoding for binary data. It is possible for a user to type an "init-
+   hex" or "init-word" response.
+
+4.1. Syntax
+
+   In UNIX manual page like syntax, the format of these responses could
+   be described as:
+
+      init-hex:<current-OTP>:<new-params>:<new-OTP>
+      init-word:<current-OTP>:<new-params>:<new-OTP>
+
+   In augmented BNF syntax and with the definitions already provided,
+   the syntax of the "init-hex" response is:
+
+   init-hex-response = "init-hex:" current-OTP ":" new-params ":"
+                        new-OTP NL
+
+   current-OTP     = hex-64bit
+   new-OTP         = hex-64bit
+
+
+
+Metz                        Standards Track                     [Page 5]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   new-params      = algorithm SPACE sequence-number SPACE seed
+   algorithm       = "md4" / "md5" / "sha1"
+   sequence-number = 4*3DIGIT
+   seed            = 16*1(ALPHA / DIGIT)
+
+   In augmented BNF syntax and with the definitions already provided,
+   the syntax of the "init-word" response is:
+
+   init-word-response = "init-word:" current-OTP ":" new-params ":"
+                        new-OTP NL
+
+   current-OTP     = word-64bit
+   new-OTP         = word-64bit
+
+   new-params      = algorithm SPACE sequence-number SPACE seed
+   algorithm       = "md4" / "md5" / "sha1"
+   sequence-number = 4*3DIGIT
+   seed            = 16*1(ALPHA / DIGIT)
+
+   Note that all appropriate fields for the "init-hex" response MUST be
+   hexadecimally coded and that all appropriate fields for the "init-
+   word" response MUST be six-word coded.
+
+   Examples of these responses are:
+
+   init-hex:f6bd 6b33 89b8 7203:md5 499 ke6118:23d1 b253 5ae0 2b7e
+   init-hex:c9b2 12bb 6425 5a0f:md5 499 ke0986:fd17 cef1 b4df 093e
+
+   init-word:MOOD SOFT POP COMB BOLO LIFE:md5 499 ke1235:
+   ARTY WEAR TAD RUG HALO GIVE
+   init-word:END KERN BALM NICK EROS WAVY:md5 499 ke1235:
+   BABY FAIN OILY NIL TIDY DADE
+
+   (Note that all of these responses are one line. Due to their length,
+   they had to be split into multiple lines in order to be included
+   here. These responses MUST NOT span more than one line in actual use)
+
+4.2. Description of Fields
+
+   The current-OTP field contains the (RFC 1938) response to the OTP
+   challenge.  The new-params field contains the parameters for the
+   client's new requested challenge and the new-OTP field contains a
+   response to that challenge. If the re-initialization is successful, a
+   server MUST store the new OTP in its database as the last successful
+   OTP received and the sequence number in the next challenge presented
+   by the server MUST be one less than the sequence number specified in
+   the new-params field.
+
+
+
+
+Metz                        Standards Track                     [Page 6]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   The new-params field is hashed as a string the same way that a seed
+   or secret pass phrase would be. All other field values are hashed in
+   their uncoded binary forms, in network byte order and without any
+   padding.
+
+4.3. Requirements
+
+   A server compliant with this specification:
+
+      1. SHOULD NOT allow a user to use the same value for their
+         seed and secret pass phrase.
+      2. MUST disable all OTP access to any principal whose
+         sequence number would be less than one
+      3. MUST decrement the sequence number if a reinitialization
+         response includes a valid current-OTP, but the server is
+         unable to successfully process the new-params or new-OTP for
+         any reason.
+
+   A generator compliant with this specification:
+
+      1. SHOULD NOT allow a user to use the same value for their
+         seed and secret pass phrase
+      2. MUST take specific steps to prevent infinite loops of
+         re-initialization attempts in case of failure
+      3. SHOULD provide the user with some indication that the
+         re-initialization is taking place
+      4. SHOULD NOT do a re-initialization without the user's
+         permission, either for that specific instance or as a
+         configuration option
+      5. SHOULD NOT retry a failed re-initialization without a user's
+         permission
+      6. SHOULD warn the user if the sequence number falls below ten
+      7. MUST refuse to generate OTPs with a sequence number below one
+
+5. Security Considerations
+
+   All of the security considerations for the OTP system also apply to
+   the OTP system with extended responses.
+
+   These extended responses, like OTP itself, do not protect the user
+   against active attacks. The IPsec Authentication Header (RFC-1826)
+   (or another technique with at least as much strength as IPsec AH)
+   SHOULD be used to protect against such attacks.
+
+   The consequences of a successful active attack on the re-
+   initialization response may be more severe than simply hijacking a
+   single session. An attacker could substitute his own response for
+
+
+
+
+Metz                        Standards Track                     [Page 7]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+   that of a legitimate user. The attacker may then be able to use the
+   OTP system to authenticate himself as the user at will (at least
+   until detected).
+
+   Failure to implement server requirement 3 in section 4.3 opens an
+   implementation to an attack based on replay of the current-OTP part
+   of the response.
+
+6. Acknowledgments
+
+   Like RFC 1938, the protocol described in this document was created by
+   contributors in the IETF OTP working group. Specific contributions
+   were made by Neil Haller, who provided input on the overall design
+   requirements of a re-initialization protocol, Denis Pinkas, who
+   suggested several modifications to the originally proposed re-
+   initialization protocol, and Phil Servita, who opened the debate with
+   the first real protocol proposal and provided lots of specific input
+   on the design of this and earlier protocols. The extensions to the
+   OTP challenge were suggested by Chris Newman and John Valdes.
+
+   Randall Atkinson and Ted T'so also contributed their views to
+   discussions about details of the protocol extensions in this
+   document.
+
+References
+
+   [RFC 822]   Crocker, D., "Standard for the Format of ARPA Internet
+               Text Messages," RFC 822, August 1982.
+
+   [RFC 1825]  Atkinson, R., "Security Architecture for the Internet
+               Protocol," RFC 1825, August 1995.
+
+   [RFC 1938]  Haller, N. and C. Metz, "A One-Time Password System,"
+               RFC 1938, May 1996.
+
+   [RFC 2119]  Bradner, S., "Key words for use in RFCs to
+               Indicate Requirement Level," RFC 2119,
+               March 1997.
+
+Author's Address
+
+   Craig Metz
+   The Inner Net
+   Box 10314-1936
+   Blacksburg, VA 24062-0314
+   (DSN) 354-8590
+   cmetz@inner.net
+
+
+
+
+Metz                        Standards Track                     [Page 8]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+Appendix: Reference Responses
+
+   The following responses were generated by a development version of
+   the One-Time Passwords in Everything (OPIE) implementation of this
+   specification.
+
+   All of these are responses to the challenge:
+
+        otp-md5 499 ke1234 ext
+
+   Note that the re-initialization responses use the same secret pass
+   phrase for new and current and a new seed of "ke1235". Also, these
+   responses have been split for formatting purposes into multiple
+   lines; they MUST NOT be multiple lines in actual use.
+
+   The secret pass phrase for these responses is:
+
+        This is a test.
+
+   The OTP standard hexadecimal response is:
+
+        5bf0 75d9 959d 036f
+
+   The OTP standard six-word response is:
+
+        BOND FOGY DRAB NE RISE MART
+
+   The OTP extended "hex" response is:
+
+        hex:5Bf0 75d9 959d 036f
+
+   The OTP extended "word" response is:
+
+        word:BOND FOGY DRAB NE RISE MART
+
+   The OTP extended "init-hex" response is:
+
+        init-hex:5bf0 75d9 959d 036f:md5 499 ke1235:3712 dcb4 aa53 16c1
+
+   The OTP extended "init-word" response is:
+
+        init-word:BOND FOGY DRAB NE RISE MART:md5 499 ke1235:  RED HERD
+        NOW BEAN PA BURG
+
+
+
+
+
+
+
+
+Metz                        Standards Track                     [Page 9]
+\f
+RFC 2243                 OTP Extended Responses            November 1997
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Metz                        Standards Track                    [Page 10]
+\f
diff --git a/doc/rfc2245.txt b/doc/rfc2245.txt
new file mode 100644 (file)
index 0000000..1025a90
--- /dev/null
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+Network Working Group                                          C. Newman
+Request for Comments: 2245                                      Innosoft
+Category: Standards Track                                  November 1997
+
+
+                        Anonymous SASL Mechanism
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+Abstract
+
+   It is common practice on the Internet to permit anonymous access to
+   various services.  Traditionally, this has been done with a plain
+   text password mechanism using "anonymous" as the user name and
+   optional trace information, such as an email address, as the
+   password.  As plaintext login commands are not permitted in new IETF
+   protocols, a new way to provide anonymous login is needed within the
+   context of the SASL [SASL] framework.
+
+1. Conventions Used in this Document
+
+   The key words "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", and "MAY"
+   in this document are to be interpreted as defined in "Key words for
+   use in RFCs to Indicate Requirement Levels" [KEYWORDS].
+
+2. Anonymous SASL mechanism
+
+   The mechanism name associated with anonymous access is "ANONYMOUS".
+   The mechanism consists of a single message from the client to the
+   server.  The client sends optional trace information in the form of a
+   human readable string.  The trace information should take one of
+   three forms: an Internet email address, an opaque string which does
+   not contain the '@' character and can be interpreted by the system
+   administrator of the client's domain, or nothing.  For privacy
+   reasons, an Internet email address should only be used with
+   permission from the user.
+
+
+
+
+
+Newman                      Standards Track                     [Page 1]
+\f
+RFC 2245                Anonymous SASL Mechanism           November 1997
+
+
+   A server which permits anonymous access will announce support for the
+   ANONYMOUS mechanism, and allow anyone to log in using that mechanism,
+   usually with restricted access.
+
+   The formal grammar for the client message using Augmented BNF [ABNF]
+   follows.
+
+   message         = [email / token]
+
+   TCHAR           = %x20-3F / %x41-7E
+                     ;; any printable US-ASCII character except '@'
+
+   email           = addr-spec
+                     ;; as defined in [IMAIL], except with no free
+                     ;; insertion of linear-white-space, and the
+                     ;; local-part MUST either be entirely enclosed in
+                     ;; quotes or entirely unquoted
+
+   token           = 1*255TCHAR
+
+3. Example
+
+
+   Here is a sample anonymous login between an IMAP client and server.
+   In this example, "C:" and "S:" indicate lines sent by the client and
+   server respectively.  If such lines are wrapped without a new "C:" or
+   "S:" label, then the wrapping is for editorial clarity and is not
+   part of the command.
+
+   Note that this example uses the IMAP profile [IMAP4] of SASL.  The
+   base64 encoding of challenges and responses, as well as the "+ "
+   preceding the responses are part of the IMAP4 profile, not part of
+   SASL itself.  Newer profiles of SASL will include the client message
+   with the AUTHENTICATE command itself so the extra round trip below
+   (the server response with an empty "+ ") can be eliminated.
+
+   In this example, the user's opaque identification token is "sirhc".
+
+        S: * OK IMAP4 server ready
+        C: A001 CAPABILITY
+        S: * CAPABILITY IMAP4 IMAP4rev1 AUTH=CRAM-MD5 AUTH=ANONYMOUS
+        S: A001 OK done
+        C: A002 AUTHENTICATE ANONYMOUS
+        S: +
+        C: c2lyaGM=
+        S: A003 OK Welcome, trace information has been logged.
+
+
+
+
+
+Newman                      Standards Track                     [Page 2]
+\f
+RFC 2245                Anonymous SASL Mechanism           November 1997
+
+
+4. Security Considerations
+
+   The anonymous mechanism grants access to information by anyone.  For
+   this reason it should be disabled by default so the administrator can
+   make an explicit decision to enable it.
+
+   If the anonymous user has any write privileges, a denial of service
+   attack is possible by filling up all available space.  This can be
+   prevented by disabling all write access by anonymous users.
+
+   If anonymous users have read and write access to the same area, the
+   server can be used as a communication mechanism to anonymously
+   exchange information.  Servers which accept anonymous submissions
+   should implement the common "drop box" model which forbids anonymous
+   read access to the area where anonymous submissions are accepted.
+
+   If the anonymous user can run many expensive operations (e.g., an
+   IMAP SEARCH BODY command), this could enable a denial of service
+   attack.  Servers are encouraged to limit the number of anonymous
+   users and reduce their priority or limit their resource usage.
+
+   If there is no idle timeout for the anonymous user and there is a
+   limit on the number of anonymous users, a denial of service attack is
+   enabled.  Servers should implement an idle timeout for anonymous
+   users.
+
+   The trace information is not authenticated so it can be falsified.
+   This can be used as an attempt to get someone else in trouble for
+   access to questionable information.  Administrators trying to trace
+   abuse need to realize this information may be falsified.
+
+   A client which uses the user's correct email address as trace
+   information without explicit permission may violate that user's
+   privacy.  Information about who accesses an anonymous archive on a
+   sensitive subject (e.g., sexual abuse) has strong privacy needs.
+   Clients should not send the email address without explicit permission
+   of the user and should offer the option of supplying no trace token
+   -- thus only exposing the source IP address and time.  Anonymous
+   proxy servers could enhance this privacy, but would have to consider
+   the resulting potential denial of service attacks.
+
+   Anonymous connections are susceptible to man in the middle attacks
+   which view or alter the data transferred.  Clients and servers are
+   encouraged to support external integrity and encryption mechanisms.
+
+   Protocols which fail to require an explicit anonymous login are more
+   susceptible to break-ins given certain common implementation
+   techniques.  Specifically, Unix servers which offer user login may
+
+
+
+Newman                      Standards Track                     [Page 3]
+\f
+RFC 2245                Anonymous SASL Mechanism           November 1997
+
+
+   initially start up as root and switch to the appropriate user id
+   after an explicit login command.  Normally such servers refuse all
+   data access commands prior to explicit login and may enter a
+   restricted security environment (e.g., the Unix chroot function) for
+   anonymous users.  If anonymous access is not explicitly requested,
+   the entire data access machinery is exposed to external security
+   attacks without the chance for explicit protective measures.
+   Protocols which offer restricted data access should not allow
+   anonymous data access without an explicit login step.
+
+5. References
+
+   [ABNF] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+   Specifications: ABNF", RFC 2234, November 1997.
+
+   [IMAIL] Crocker, D., "Standard for the Format of Arpa Internet Text
+   Messages", STD 11, RFC 822, August 1982.
+
+   [IMAP4] Crispin, M., "Internet Message Access Protocol - Version
+   4rev1", RFC 2060, December 1996.
+
+   [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+   Requirement Levels", RFC 2119, March 1997.
+
+   [SASL] Myers, J., "Simple Authentication and Security Layer (SASL)",
+   RFC 2222, October 1997.
+
+6. Author's Address
+
+   Chris Newman
+   Innosoft International, Inc.
+   1050 Lakes Drive
+   West Covina, CA 91790 USA
+
+   Email: chris.newman@innosoft.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 4]
+\f
+RFC 2245                Anonymous SASL Mechanism           November 1997
+
+
+7.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1997).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 5]
+\f
diff --git a/doc/rfc2289.txt b/doc/rfc2289.txt
new file mode 100644 (file)
index 0000000..8d1d722
--- /dev/null
@@ -0,0 +1,1403 @@
+
+
+
+
+
+
+Network Working Group                                        N. Haller
+Request for Comments: 2289                                    Bellcore
+Obsoletes: 1938                                                C. Metz
+Category: Standards Track                   Kaman Sciences Corporation
+                                                             P. Nesser
+                                            Nesser & Nesser Consulting
+                                                              M. Straw
+                                                              Bellcore
+                                                         February 1998
+
+
+                       A One-Time Password System
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+1.0 ABSTRACT
+
+   This document describes a one-time password authentication system
+   (OTP). The system provides authentication for system access (login)
+   and other applications requiring authentication that is secure
+   against passive attacks based on replaying captured reusable
+   passwords. OTP evolved from the S/KEY (S/KEY is a trademark of
+   Bellcore) One-Time Password System that was released by Bellcore and
+   is described in references [3] and [5].
+
+2.0 OVERVIEW
+
+   One form of attack on networked computing systems is eavesdropping on
+   network connections to obtain authentication information such as the
+   login IDs and passwords of legitimate users. Once this information is
+   captured, it can be used at a later time to gain access to the
+   system. One-time password systems are designed to counter this type
+   of attack, called a "replay attack" [4].
+
+   The authentication system described in this document uses a secret
+   pass-phrase to generate a sequence of one-time (single use)
+   passwords.  With this system, the user's secret pass-phrase never
+   needs to cross the network at any time such as during authentication
+
+
+
+Haller                      Standards Track                     [Page 1]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   or during pass-phrase changes. Thus, it is not vulnerable to replay
+   attacks.  Added security is provided by the property that no secret
+   information need be stored on any system, including the server being
+   protected.
+
+   The OTP system protects against external passive attacks against the
+   authentication subsystem. It does not prevent a network eavesdropper
+   from gaining access to private information and does not provide
+   protection against either "social engineering" or active attacks [9].
+
+3.0 INTRODUCTION
+
+   There are two entities in the operation of the OTP one-time password
+   system. The generator must produce the appropriate one-time password
+   from the user's secret pass-phrase and from information provided in
+   the challenge from the server. The server must send a challenge that
+   includes the appropriate generation parameters to the generator, must
+   verify the one-time password received, must store the last valid
+   one-time password it received, and must store the corresponding one-
+   time password sequence number. The server must also facilitate the
+   changing of the user's secret pass-phrase in a secure manner.
+
+   The OTP system generator passes the user's secret pass-phrase, along
+   with a seed received from the server as part of the challenge,
+   through multiple iterations of a secure hash function to produce a
+   one-time password. After each successful authentication, the number
+   of secure hash function iterations is reduced by one.  Thus, a unique
+   sequence of passwords is generated.  The server verifies the one-time
+   password received from the generator by computing the secure hash
+   function once and comparing the result with the previously accepted
+   one-time password.  This technique was first suggested by Leslie
+   Lamport [1].
+
+4.0 REQUIREMENTS TERMINOLOGY
+
+   In this document, the words that are used to define the significance
+   of each particular requirement are usually capitalized.  These words
+   are:
+
+     - MUST
+
+       This word or the adjective "REQUIRED" means that the item is an
+       absolute requirement of the specification.
+
+
+
+
+
+
+
+
+Haller                      Standards Track                     [Page 2]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+     - SHOULD
+
+       This word or the adjective "RECOMMENDED" means that there might
+       exist valid reasons in particular circumstances to ignore this
+       item, but the full implications should be understood and the case
+       carefully weighed before taking a different course.
+
+     - MAY
+
+       This word or the adjective "OPTIONAL" means that this item is
+       truly optional.  One vendor might choose to include the item
+       because a particular marketplace requires it or because it
+       enhances the product, for example; another vendor may omit the
+       same item.
+
+5.0 SECURE HASH FUNCTION
+
+   The security of the OTP system is based on the non-invertability of a
+   secure hash function. Such a function must be tractable to compute in
+   the forward direction, but computationally infeasible to invert.
+
+   The interfaces are currently defined for three such hash algorithms,
+   MD4 [2] and MD5 [6] by Ronald Rivest, and SHA [7] by NIST.  All
+   conforming implementations of both server and generators MUST support
+   MD5.  They SHOULD support SHA and MAY also support MD4.  Clearly, the
+   generator and server must use the same algorithm in order to
+   interoperate. Other hash algorithms may be specified for use with
+   this system by publishing the appropriate interfaces.
+
+   The secure hash algorithms listed above have the property that they
+   accept an input that is arbitrarily long and produce a fixed size
+   output. The OTP system folds this output to 64 bits using the
+   algorithms in the Appendix A. 64 bits is also the length of the one-
+   time passwords. This is believed to be long enough to be secure and
+   short enough to be entered manually (see below, Form of Output) when
+   necessary.
+
+6.0 GENERATION OF ONE-TIME PASSWORDS
+
+   This section describes the generation of the one-time passwords.
+   This process consists of an initial step in which all inputs are
+   combined, a computation step where the secure hash function is
+   applied a specified number of times, and an output function where the
+   64 bit one-time password is converted to a human readable form.
+
+   Appendix C contains examples of the outputs given a collection of
+   inputs.  It provides implementors with a means of verification the
+   use of these algorithms.
+
+
+
+Haller                      Standards Track                     [Page 3]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   Initial Step
+
+   In principle, the user's secret pass-phrase may be of any length. To
+   reduce the risk from techniques such as exhaustive search or
+   dictionary attacks, character string pass-phrases MUST contain at
+   least 10 characters (see Form of Inputs below).  All implementations
+   MUST support a pass-phrases of at least 63 characters.  The secret
+   pass-phrase is frequently, but is not required to be, textual
+   information provided by a user.
+
+   In this step, the pass phrase is concatenated with a seed that is
+   transmitted from the server in clear text. This non-secret seed
+   allows clients to use the same secret pass-phrase on multiple
+   machines (using different seeds) and to safely recycle their secret
+   pass-phrases by changing the seed.
+
+   The result of the concatenation is passed through the secure hash
+   function and then is reduced to 64 bits using one of the function
+   dependent algorithms shown in Appendix A.
+
+   Computation Step
+
+   A sequence of one-time passwords is produced by applying the secure
+   hash function multiple times to the output of the initial step
+   (called S). That is, the first one-time password to be used is
+   produced by passing S through the secure hash function a number of
+   times (N) specified by the user. The next one-time password to be
+   used is generated by passing S though the secure hash function N-1
+   times. An eavesdropper who has monitored the transmission of a one-
+   time password would not be able to generate the next required
+   password because doing so would mean inverting the hash function.
+
+   Form of Inputs
+
+   The secret pass-phrase is seen only by the OTP generator. To allow
+   interchangeability of generators, all generators MUST support a
+   secret pass-phrase of 10 to 63 characters. Implementations MAY
+   support a longer pass-phrase, but such implementations risk the loss
+   of interchangeability with implementations supporting only the
+   minimum.
+
+   The seed MUST consist of purely alphanumeric characters and MUST be
+   of one to 16 characters in length. The seed is a string of characters
+   that MUST not contain any blanks and SHOULD consist of strictly
+   alphanumeric characters from the ISO-646 Invariant Code Set.  The
+   seed MUST be case insensitive and MUST be internally converted to
+   lower case before it is processed.
+
+
+
+
+Haller                      Standards Track                     [Page 4]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   The sequence number and seed together constitute a larger unit of
+   data called the challenge. The challenge gives the generator the
+   parameters it needs to calculate the correct one-time password from
+   the secret pass-phrase. The challenge MUST be in a standard syntax so
+   that automated generators can recognize the challenge in context and
+   extract these parameters. The syntax of the challenge is:
+
+           otp-<algorithm identifier> <sequence integer> <seed>
+
+   The three tokens MUST be separated by a white space (defined as any
+   number of spaces and/or tabs) and the entire challenge string MUST be
+   terminated with either a space or a new line. The string "otp-" MUST
+   be in lower case.  The algorithm identifier is case sensitive (the
+   existing identifiers are all lower case), and the seed is case
+   insensitive and converted before use to lower case.  If additional
+   algorithms are defined, appropriate identifiers (short, but not
+   limited to three or four characters) must be defined. The currently
+   defined algorithm identifiers are:
+
+       md4        MD4 Message Digest
+       md5        MD5 Message Digest
+       sha1       NIST Secure Hash Algorithm Revision 1
+
+   An example of an OTP challenge is:   otp-md5 487 dog2
+
+   Form of Output
+
+   The one-time password generated by the above procedure is 64 bits in
+   length. Entering a 64 bit number is a difficult and error prone
+   process. Some generators insert this password into the input stream
+   and some others make it available for system "cut and paste." Still
+   other arrangements require the one-time password to be entered
+   manually. The OTP system is designed to facilitate this manual entry
+   without impeding automatic methods. The one-time password therefore
+   MAY be converted to, and all servers MUST be capable of accepting it
+   as, a sequence of six short (1 to 4 letter) easily typed words that
+   only use characters from ISO-646 IVCS. Each word is chosen from a
+   dictionary of 2048 words; at 11 bits per word, all one-time passwords
+   may be encoded.
+
+   The two extra bits in this encoding are used to store a checksum.
+   The 64 bits of key are broken down into pairs of bits, then these
+   pairs are summed together. The two least significant bits of this sum
+   are encoded in the last two bits of the six word sequence with the
+   least significant bit of the sum as the last bit encoded. All OTP
+   generators MUST calculate this checksum and all OTP servers MUST
+   verify this checksum explicitly as part of the operation of decoding
+   this representation of the one-time password.
+
+
+
+Haller                      Standards Track                     [Page 5]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   Generators that produce the six-word format MUST present the words in
+   upper case with single spaces used as separators. All servers MUST
+   accept six-word format without regard to case and white space used as
+   a separator. The two lines below represent the same one-time
+   password.  The first is valid as output from a generator and as input
+   a server, the second is valid only as human input to a server.
+
+            OUST COAT FOAL MUG BEAK TOTE
+            oust coat foal  mug  beak  tote
+
+     Interoperability requires that all OTP servers and generators use
+     the same dictionary. The standard dictionary was originally
+     specified in the "S/KEY One Time Password System" that is described
+     in RFC 1760 [5].  This dictionary is included in this document as
+     Appendix D.
+
+     To facilitate the implementation of smaller generators, hexadecimal
+     output is an acceptable alternative for the presentation of the
+     one-time password. All implementations of the server software MUST
+     accept case-insensitive hexadecimal as well as six-word format. The
+     hexadecimal digits may be separated by white space so servers are
+     REQUIRED to ignore all white space.  If the representation is
+     partitioned by white space, leading zeros must be retained.
+     Examples of hexadecimal format are:
+
+           Representation                Value
+
+           3503785b369cda8b              0x3503785b369cda8b
+           e5cc a1b8 7c13 096b           0xe5cca1b87c13096b
+           C7 48 90 F4 27 7B A1 CF       0xc74890f4277ba1cf
+           47 9 A68 28 4C 9D 0 1BC       0x479a68284c9d01bc
+
+   In addition to accepting six-word and hexadecimal encodings of the
+   64 bit one-time password, servers SHOULD accept the alternate
+   dictionary encoding described in Appendix B.  The six words in this
+   encoding MUST not overlap the set of words in the standard
+   dictionary.  To avoid ambiguity with the hexadecimal representation,
+   words in the alternate dictionary MUST not be comprised solely of
+   the letters A-F.  Decoding words thus encoded does not require any
+   knowledge of the alternative dictionary used so the acceptance of
+   any alternate dictionary implies the acceptance of all alternate
+   dictionaries.  Words in the alternative dictionaries are case
+   sensitive.  Generators and servers MUST preserve the case in the
+   processing of these words.
+
+   In summary, all conforming servers MUST accept six-word input that
+   uses the Standard Dictionary (RFC 1760 and Appendix D), MUST accept
+   hexadecimal encoding, and SHOULD accept six-word input that uses the
+
+
+
+Haller                      Standards Track                     [Page 6]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   Alternative Dictionary technique (Appendix B).  As there is a remote
+   possibility that a hexadecimal encoding of a one-time password will
+   look like a valid six-word standard dictionary encoding, all
+   implementations MUST use the following scheme.  If a six-word
+   encoded one-time password is valid, it is accepted.  Otherwise, if
+   the one-time password can be interpreted as hexadecimal, and with
+   that decoding it is valid, then it is accepted.
+
+7.0 VERIFICATION OF ONE-TIME PASSWORDS
+
+   An application on the server system that requires OTP authentication
+   is expected to issue an OTP challenge as described above. Given the
+   parameters from this challenge and the secret pass-phrase, the
+   generator can compute (or lookup) the one-time password that is
+   passed to the server to be verified.
+
+   The server system has a database containing, for each user, the
+   one-time password from the last successful authentication or the
+   first OTP of a newly initialized sequence. To authenticate the user,
+   the server decodes the one-time password received from the generator
+   into a 64-bit key and then runs this key through the secure hash
+   function once. If the result of this operation matches the stored
+   previous OTP, the authentication is successful and the accepted
+   one-time password is stored for future use.
+
+8.0 PASS-PHRASE CHANGES
+
+   Because the number of hash function applications executed by the
+   generator decreases by one each time, at some point the user must
+   reinitialize the system or be unable to authenticate.
+
+   Although some installations may not permit users to initialize
+   remotely, implementations MUST provide a means to do so that does
+   not reveal the user's secret pass-phrase.  One way is to provide a
+   means to reinitialize the  sequence through explicit specification
+   of the first one-time password.
+
+   When the sequence of one-time passwords is reinitialized,
+   implementations MUST verify that the seed or the pass-phrase is
+   changed.  Installations SHOULD discourage any operation that sends
+   the secret pass-phrase over a network in clear-text as such practice
+   defeats the concept of a one-time password.
+
+   Implementations MAY use the following technique for
+   [re]initialization:
+
+
+
+
+
+
+Haller                      Standards Track                     [Page 7]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+      o  The user picks a new seed and hash count (default values may
+         be offered).  The user provides these, along with the
+         corresponding generated one-time password, to the host system.
+
+      o  The user MAY also provide the corresponding generated one
+         time password for count-1 as an error check.
+
+      o  The user SHOULD provide the generated one-time password for
+         the old seed and old hash count to protect an idle terminal
+         or workstation (this implies that when the count is 1, the
+         user can login but cannot then change the seed or count).
+
+   In the future a specific protocol may be defined for
+   reinitialization that will permit smooth and possibly automated
+   interoperation of all hosts and generators.
+
+9.0 PROTECTION AGAINST RACE ATTACK
+
+   All conforming server implementations MUST protect against the race
+   condition described in this section.  A defense against this attack
+   is outlined; implementations MAY use this approach or MAY select an
+   alternative defense.
+
+   It is possible for an attacker to listen to most of a one-time
+   password, guess the remainder, and then race the legitimate user to
+   complete the authentication.  Multiple guesses against the last word
+   of the six-word format are likely to succeed.
+
+   One possible defense is to prevent a user from starting multiple
+   simultaneous authentication sessions. This means that once the
+   legitimate user has initiated authentication, an attacker would be
+   blocked until the first authentication process has completed.  In
+   this approach, a timeout is necessary to thwart a denial of service
+   attack.
+
+10.0 SECURITY CONSIDERATIONS
+
+   This entire document discusses an authentication system that
+   improves security by limiting the danger of eavesdropping/replay
+   attacks that have been used against simple password systems [4].
+
+   The use of the OTP system only provides protections against passive
+   eavesdropping/replay attacks.  It does not provide for the privacy
+   of transmitted data, and it does not provide protection against
+   active attacks such as session hijacking that are known to be
+   present in the current Internet [9].  The use of IP Security
+   (IPsec), see [10], [11], and [12] is recommended to protect against
+   TCP session hijacking.
+
+
+
+Haller                      Standards Track                     [Page 8]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   The success of the OTP system to protect host systems is dependent
+   on the non-invertability of the secure hash functions used.  To our
+   knowledge, none of the hash algorithms have been broken, but it is
+   generally believed [6] that MD4 is not as strong as MD5.  If a
+   server supports multiple hash algorithms, it is only as secure as
+   the weakest algorithm.
+
+11.0 ACKNOWLEDGMENTS
+
+   The idea behind OTP authentication was first proposed by Leslie
+   Lamport [1]. Bellcore's S/KEY system, from which OTP is derived, was
+   proposed by Phil Karn, who also wrote most of the Bellcore reference
+   implementation.
+
+12.0 REFERENCES
+
+   [1]  Leslie Lamport, "Password Authentication with Insecure
+        Communication", Communications of the ACM 24.11 (November
+        1981), 770-772
+
+   [2]  Rivest, R., "The MD4 Message-Digest Algorithm", RFC 1320,
+        April 1992.
+
+   [3]  Neil Haller, "The S/KEY One-Time Password System", Proceedings
+        of the ISOC Symposium on Network and Distributed System
+        Security, February 1994, San Diego, CA
+
+   [4]  Haller, N., and R. Atkinson, "On Internet Authentication",
+        RFC 1704, October 1994.
+
+   [5]  Haller, N., "The S/KEY One-Time Password System",
+        RFC 1760, February 1995.
+
+   [6]  Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+        April 1992.
+
+   [7]  National Institute of Standards and Technology (NIST),
+        "Announcing the Secure Hash Standard", FIPS 180-1, U.S.
+        Department of Commerce, April 1995.
+
+   [8]  International Standard - Information Processing -- ISO 7-bit
+        coded character set for information interchange (Invariant Code
+        Set), ISO-646, International Standards Organization, Geneva,
+        Switzerland, 1983
+
+
+
+
+
+
+
+Haller                      Standards Track                     [Page 9]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   [9]  Computer Emergency Response Team (CERT), "IP Spoofing and
+        Hijacked Terminal Connections", CA-95:01, January 1995.
+        Available via anonymous ftp from info.cert.org in
+        /pub/cert_advisories.
+
+   [10] Atkinson, R., "Security Architecture for the Internet Protocol",
+        RFC 1825, August 1995.
+
+   [11] Atkinson, R., "IP Authentication Header", RFC 1826, August
+        1995.
+
+   [12] Atkinson, R., "IP Encapsulating Security Payload (ESP)", RFC
+        1827, August 1995.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 10]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+13.0 AUTHORS' ADDRESSES
+
+   Neil Haller
+   Bellcore
+   MCC 1C-265B
+   445 South Street
+   Morristown, NJ, 07960-6438, USA
+
+   Phone: +1 201 829-4478
+   Fax:   +1 201 829-2504
+   EMail: nmh@bellcore.com
+
+
+   Craig Metz
+   Kaman Sciences Corporation
+   For NRL Code 5544
+   4555 Overlook Avenue, S.W.
+   Washington, DC, 20375-5337, USA
+
+   Phone: +1 202 404-7122
+   Fax:   +1 202 404-7942
+   EMail: cmetz@cs.nrl.navy.mil
+
+
+   Philip J. Nesser II
+   Nesser & Nesser Consulting
+   13501 100th Ave NE
+   Suite 5202
+   Kirkland, WA 98034, USA
+
+   Phone: +1 206 481 4303
+   EMail: pjnesser@martigny.ai.mit.edu
+
+
+   Mike Straw
+   Bellcore
+   RRC 1A-225
+   445 Hoes Lane
+   Piscataway, NJ 08854-4182
+
+   Phone:  +1 908 699-5212
+   EMail:  mess@bellcore.com
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 11]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+Appendix A  -  Interfaces to Secure Hash Algorithms
+
+   Original interoperability tests provided valuable insights into the
+   subtle problems which occur when converting protocol specifications
+   into running code.  In particular, the manipulation of bit ordered
+   data is dependent on the architecture of the hardware, specifically
+   the way in which a computer stores multi-byte data.  The method is
+   typically called big or little "endian."  A big endian machine stores
+   data with the most significant byte first, while a little endian
+   machine stores the least significant byte first.  Thus, on a big
+   endian machine data is stored left to right, while little endian
+   machines store data right to left.
+
+   For example, the four byte value 0x11AABBCC is stored in a big endian
+   machine as the following series of four bytes, "0x11", "0xAA",
+   "0xBB", and "0xCC", while on a little endian machine the value would
+   be stored as "0xCC", "0xBB", "0xAA", and "0x11".
+
+   For historical reasons, and to promote interoperability with existing
+   implementations, it was decided that ALL hashes incorporated into the
+   OTP protocol MUST store the output of their hash function in LITTLE
+   ENDIAN format BEFORE the bit folding to 64 bits occurs.  This is done
+   in the implementations of MD4 and MD5 (see references [2] and [6]),
+   while it must be explicitly done for the implementation of SHA1 (see
+   reference [7]).
+
+   Any future hash functions implemented into the OTP protocol SHOULD
+   provide a similar reference fragment of code to allow independent
+   implementations to operate successfully.
+
+
+   MD4 Message Digest (see reference [2])
+
+     MD4_CTX md;
+     unsigned char result[16];
+
+     strcpy(buf, seed);     /* seed must be in lower case */
+     strcat(buf, passwd);
+     MD4Init(&md);
+     MD4Update(&md, (unsigned char *)buf, strlen(buf));
+     MD4Final(result, &md);
+
+     /* Fold the 128 bit result to 64 bits */
+     for (i = 0; i < 8; i++)
+             result[i] ^= result[i+8];
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 12]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+MD5 Message Digest (see reference [6])
+
+     MD5_CTX md;
+     unsigned char result[16];
+     strcpy(buf, seed);     /* seed must be in lower case */
+     strcat(buf, passwd);
+     MD5Init(&md);
+     MD5Update(&md, (unsigned char *)buf, strlen(buf));
+     MD5Final(result, &md);
+
+     /* Fold the 128 bit result to 64 bits */
+     for (i = 0; i < 8; i++)
+             result[i] ^= result[i+8];
+
+
+SHA Secure Hash Algorithm (see reference [7])
+
+     SHA_INFO sha;
+     unsigned char result[16];
+     strcpy(buf, seed);     /* seed must be in lower case */
+     strcat(buf, passwd);
+     sha_init(&sha);
+     sha_update(&sha, (unsigned char *)buf, strlen(buf));
+     sha_final(&sha);       /* NOTE:  no result buffer */
+
+     /* Fold the 160 bit result to 64 bits */
+     sha.digest[0] ^= sha.digest[2];
+     sha.digest[1] ^= sha.digest[3];
+     sha.digest[0] ^= sha.digest[4];
+
+     /*
+      * copy the resulting 64 bits to the result buffer in little endian
+      * fashion (analogous to the way MD4Final() and MD5Final() do).
+      */
+     for (i = 0, j = 0; j < 8; i++, j += 4)
+     {
+             result[j]   = (unsigned char)(sha.digest[i] & 0xff);
+             result[j+1] = (unsigned char)((sha.digest[i] >> 8) & 0xff);
+             result[j+2] = (unsigned char)((sha.digest[i] >> 16) & 0xff);
+             result[j+3] = (unsigned char)((sha.digest[i] >> 24) & 0xff);
+     }
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 13]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+Appendix B   -   Alternative Dictionary Algorithm
+
+   The purpose of alternative dictionary encoding of the OTP one-time
+   password is to allow the use of language specific or friendly words.
+   As case translation is not always well defined, the alternative
+   dictionary encoding is case sensitive.  Servers SHOULD accept this
+   encoding in addition to the standard 6-word and hexadecimal
+   encodings.
+
+
+   GENERATOR ENCODING USING AN ALTERNATE DICTIONARY
+
+     The standard 6-word encoding uses the placement of a word in the
+     dictionary to represent an 11-bit number. The 64-bit one-time
+     password can then be represented by six words.
+
+     An alternative dictionary of 2048 words may be created such that
+     each word W and position of the word in the dictionary N obey the
+     relationship:
+
+             alg( W ) % 2048 == N
+     where
+             alg is the hash algorithm used (e.g. MD4, MD5, SHA1).
+
+     In addition, no words in the standard dictionary may be chosen.
+
+     The generator expands the 64-bit one-time password to 66 bits by
+     computing parity as with the standard 6-word encoding.  The six 11-
+     bit numbers are then converted to words using the dictionary that
+     was created such that the above relationship holds.
+
+   SERVER DECODING OF ALTERNATE DICTIONARY ONE-TIME PASSWORDS
+
+     The server accepting alternative dictionary encoding converts each
+     word to an 11-bit number using the above encoding. These numbers
+     are then used in the same way as the decoded standard dictionary
+     words to form the 66-bit one-time password.
+
+     The server does not need to have access to the alternate dictionary
+     that was used to create the one-time password it is authenticating.
+     This is because the decoding from word to 11-bit number does not
+     make any use of the dictionary.  As a result of the independence of
+     the dictionary, a server accepting one alternate dictionary accept
+     all alternate dictionaries.
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 14]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+Appendix C  -  OTP Verification Examples
+
+   This appendix provides a series of inputs and correct outputs for all
+   three of the defined OTP cryptographic hashes, specifically MD4, MD5,
+   and SHA1.  This document is intended to be used by developers for
+   interoperability checks when creating generators or servers.  Output
+   is provided in both hexadecimal notation and the six word encoding
+   documented in Appendix D.
+
+   GENERAL CHECKS
+
+   Note that the output given for these checks is not intended to be
+   taken literally, but describes the type of action that should be
+   taken.
+
+   Pass Phrase Length
+
+ Input:
+   Pass Phrase: Too_short
+   Seed: iamvalid
+   Count: 99
+   Hash: ANY
+ Output:
+   ERROR:  Pass Phrase too short
+
+ Input:
+   Pass Phrase:
+     1234567890123456789012345678901234567890123456789012345678901234
+   Seed: iamvalid
+   Count: 99
+   Hash: ANY
+ Output:
+   WARNING: Pass Phrase longer than the recommended maximum length of
+63
+
+Seed Values
+
+ Input:
+   Pass Phrase:  A_Valid_Pass_Phrase
+   Seed: Length_Okay
+   Count: 99
+   Hash: ANY
+ Output:
+   ERROR: Seed must be purely alphanumeric
+
+ Input:
+   Pass Phrase:  A_Valid_Pass_Phrase
+   Seed: LengthOfSeventeen
+
+
+
+Haller                      Standards Track                    [Page 15]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+   Count: 99
+   Hash: ANY
+
+ Output:
+   ERROR: Seed must be between 1 and 16 characters in length
+
+ Input:
+   Pass Phrase:  A_Valid_Pass_Phrase
+   Seed: A Seed
+   Count: 99
+   Hash: ANY
+ Output:
+   ERROR: Seed must not contain any spaces
+
+Parity Calculations
+
+ Input:
+   Pass Phrase: A_Valid_Pass_Phrase
+   Seed: AValidSeed
+   Count: 99
+   Hash: MD5
+ Output:
+   Hex: 85c43ee03857765b
+   Six Word(CORRECT):          FOWL KID MASH DEAD DUAL OAF
+   Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL NUT
+   Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL O
+   Six Word(INCORRECT PARITY): FOWL KID MASH DEAD DUAL OAK
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 16]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+MD4 ENCODINGS
+
+Pass Phrase     Seed    Cnt Hex                 Six Word Format
+========================================================================
+This is a test. TeSt     0  D185 4218 EBBB 0B51
+                                           ROME MUG FRED SCAN LIVE LACE
+This is a test. TeSt     1  6347 3EF0 1CD0 B444
+                                           CARD SAD MINI RYE COL KIN
+This is a test. TeSt    99  C5E6 1277 6E6C 237A
+                                           NOTE OUT IBIS SINK NAVE MODE
+AbCdEfGhIjK     alpha1   0  5007 6F47 EB1A DE4E
+                                           AWAY SEN ROOK SALT LICE MAP
+AbCdEfGhIjK     alpha1   1  65D2 0D19 49B5 F7AB
+                                           CHEW GRIM WU HANG BUCK SAID
+AbCdEfGhIjK     alpha1  99  D150 C82C CE6F 62D1
+                                           ROIL FREE COG HUNK WAIT COCA
+OTP's are good  correct  0  849C 79D4 F6F5 5388
+                                           FOOL STEM DONE TOOL BECK NILE
+OTP's are good  correct  1  8C09 92FB 2508 47B1
+                                           GIST AMOS MOOT AIDS FOOD SEEM
+OTP's are good  correct 99  3F3B F4B4 145F D74B
+                                           TAG SLOW NOV MIN WOOL KENO
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 17]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+MD5 ENCODINGS
+
+Pass Phrase     Seed    Cnt Hex                 Six Word Format
+========================================================================
+This is a test. TeSt     0  9E87 6134 D904 99DD
+                                           INCH SEA ANNE LONG AHEM TOUR
+This is a test. TeSt     1  7965 E054 36F5 029F
+                                           EASE OIL FUM CURE AWRY AVIS
+This is a test. TeSt    99  50FE 1962 C496 5880
+                                           BAIL TUFT BITS GANG CHEF THY
+AbCdEfGhIjK     alpha1   0  8706 6DD9 644B F206
+                                           FULL PEW DOWN ONCE MORT ARC
+AbCdEfGhIjK     alpha1   1  7CD3 4C10 40AD D14B
+                                           FACT HOOF AT FIST SITE KENT
+AbCdEfGhIjK     alpha1  99  5AA3 7A81 F212 146C
+                                           BODE HOP JAKE STOW JUT RAP
+OTP's are good  correct  0  F205 7539 43DE 4CF9
+                                           ULAN NEW ARMY FUSE SUIT EYED
+OTP's are good  correct  1  DDCD AC95 6F23 4937
+                                           SKIM CULT LOB SLAM POE HOWL
+OTP's are good  correct 99  B203 E28F A525 BE47
+                                           LONG IVY JULY AJAR BOND LEE
+
+
+SHA1 ENCODINGS
+
+Pass Phrase     Seed    Cnt Hex                 Six Word Format
+========================================================================
+This is a test. TeSt     0  BB9E 6AE1 979D 8FF4
+                                           MILT VARY MAST OK SEES WENT
+This is a test. TeSt     1  63D9 3663 9734 385B
+                                           CART OTTO HIVE ODE VAT NUT
+This is a test. TeSt    99  87FE C776 8B73 CCF9
+                                           GAFF WAIT SKID GIG SKY EYED
+AbCdEfGhIjK     alpha1   0  AD85 F658 EBE3 83C9
+                                           LEST OR HEEL SCOT ROB SUIT
+AbCdEfGhIjK     alpha1   1  D07C E229 B5CF 119B
+                                           RITE TAKE GELD COST TUNE RECK
+AbCdEfGhIjK     alpha1  99  27BC 7103 5AAF 3DC6
+                                           MAY STAR TIN LYON VEDA STAN
+OTP's are good  correct  0  D51F 3E99 BF8E 6F0B
+                                           RUST WELT KICK FELL TAIL FRAU
+OTP's are good  correct  1  82AE B52D 9437 74E4
+                                           FLIT DOSE ALSO MEW DRUM DEFY
+OTP's are good  correct 99  4F29 6A74 FE15 67EC
+                                           AURA ALOE HURL WING BERG WAIT
+
+
+
+
+
+Haller                      Standards Track                    [Page 18]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+Appendix D   -   Dictionary for Converting Between 6-Word and Binary Formats
+
+   This dictionary is from the module put.c in the original Bellcore
+   reference distribution.
+
+{        "A",     "ABE",   "ACE",   "ACT",   "AD",    "ADA",   "ADD",
+"AGO",   "AID",   "AIM",   "AIR",   "ALL",   "ALP",   "AM",    "AMY",
+"AN",    "ANA",   "AND",   "ANN",   "ANT",   "ANY",   "APE",   "APS",
+"APT",   "ARC",   "ARE",   "ARK",   "ARM",   "ART",   "AS",    "ASH",
+"ASK",   "AT",    "ATE",   "AUG",   "AUK",   "AVE",   "AWE",   "AWK",
+"AWL",   "AWN",   "AX",   "AYE",   "BAD",   "BAG",   "BAH",   "BAM",
+"BAN",   "BAR",   "BAT",   "BAY",   "BE",    "BED",   "BEE",   "BEG",
+"BEN",   "BET",   "BEY",   "BIB",   "BID",   "BIG",   "BIN",   "BIT",
+"BOB",   "BOG",   "BON",   "BOO",   "BOP",   "BOW",   "BOY",   "BUB",
+"BUD",   "BUG",   "BUM",   "BUN",   "BUS",   "BUT",   "BUY",   "BY",
+"BYE",   "CAB",   "CAL",   "CAM",   "CAN",   "CAP",   "CAR",   "CAT",
+"CAW",   "COD",   "COG",   "COL",   "CON",   "COO",   "COP",   "COT",
+"COW",   "COY",   "CRY",   "CUB",   "CUE",   "CUP",   "CUR",   "CUT",
+"DAB",   "DAD",   "DAM",   "DAN",   "DAR",   "DAY",   "DEE",   "DEL",
+"DEN",   "DES",   "DEW",   "DID",   "DIE",   "DIG",   "DIN",   "DIP",
+"DO",    "DOE",   "DOG",   "DON",   "DOT",   "DOW",   "DRY",   "DUB",
+"DUD",   "DUE",   "DUG",   "DUN",   "EAR",   "EAT",   "ED",    "EEL",
+"EGG",   "EGO",   "ELI",   "ELK",   "ELM",   "ELY",   "EM",    "END",
+"EST",   "ETC",   "EVA",   "EVE",   "EWE",   "EYE",   "FAD",   "FAN",
+"FAR",   "FAT",   "FAY",   "FED",   "FEE",   "FEW",   "FIB",   "FIG",
+"FIN",   "FIR",   "FIT",   "FLO",   "FLY",   "FOE",   "FOG",   "FOR",
+"FRY",   "FUM",   "FUN",   "FUR",   "GAB",   "GAD",   "GAG",   "GAL",
+"GAM",   "GAP",   "GAS",   "GAY",   "GEE",   "GEL",   "GEM",   "GET",
+"GIG",   "GIL",   "GIN",   "GO",    "GOT",   "GUM",   "GUN",   "GUS",
+"GUT",   "GUY",   "GYM",   "GYP",   "HA",    "HAD",   "HAL",   "HAM",
+"HAN",   "HAP",   "HAS",   "HAT",   "HAW",   "HAY",   "HE",    "HEM",
+"HEN",   "HER",   "HEW",   "HEY",   "HI",    "HID",   "HIM",   "HIP",
+"HIS",   "HIT",   "HO",   "HOB",   "HOC",   "HOE",   "HOG",   "HOP",
+"HOT",   "HOW",   "HUB",   "HUE",   "HUG",   "HUH",   "HUM",   "HUT",
+"I",     "ICY",   "IDA",   "IF",    "IKE",   "ILL",   "INK",   "INN",
+"IO",    "ION",   "IQ",   "IRA",   "IRE",   "IRK",   "IS",    "IT",
+"ITS",   "IVY",   "JAB",   "JAG",   "JAM",   "JAN",   "JAR",   "JAW",
+"JAY",   "JET",   "JIG",   "JIM",   "JO",    "JOB",   "JOE",   "JOG",
+"JOT",   "JOY",   "JUG",   "JUT",   "KAY",   "KEG",   "KEN",   "KEY",
+"KID",   "KIM",   "KIN",   "KIT",   "LA",    "LAB",   "LAC",   "LAD",
+"LAG",   "LAM",   "LAP",   "LAW",   "LAY",   "LEA",   "LED",   "LEE",
+"LEG",   "LEN",   "LEO",   "LET",   "LEW",   "LID",   "LIE",   "LIN",
+"LIP",   "LIT",   "LO",   "LOB",   "LOG",   "LOP",   "LOS",   "LOT",
+"LOU",   "LOW",   "LOY",   "LUG",   "LYE",   "MA",    "MAC",   "MAD",
+"MAE",   "MAN",   "MAO",   "MAP",   "MAT",   "MAW",   "MAY",   "ME",
+"MEG",   "MEL",   "MEN",   "MET",   "MEW",   "MID",   "MIN",   "MIT",
+"MOB",   "MOD",   "MOE",   "MOO",   "MOP",   "MOS",   "MOT",   "MOW",
+"MUD",   "MUG",   "MUM",   "MY",    "NAB",   "NAG",   "NAN",   "NAP",
+
+
+
+Haller                      Standards Track                    [Page 19]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+"NAT",   "NAY",   "NE",   "NED",   "NEE",   "NET",   "NEW",   "NIB",
+"NIL",   "NIP",   "NIT",   "NO",    "NOB",   "NOD",   "NON",   "NOR",
+"NOT",   "NOV",   "NOW",   "NU",    "NUN",   "NUT",   "O",     "OAF",
+"OAK",   "OAR",   "OAT",   "ODD",   "ODE",   "OF",    "OFF",   "OFT",
+"OH",    "OIL",   "OK",   "OLD",   "ON",    "ONE",   "OR",    "ORB",
+"ORE",   "ORR",   "OS",   "OTT",   "OUR",   "OUT",   "OVA",   "OW",
+"OWE",   "OWL",   "OWN",   "OX",    "PA",    "PAD",   "PAL",   "PAM",
+"PAN",   "PAP",   "PAR",   "PAT",   "PAW",   "PAY",   "PEA",   "PEG",
+"PEN",   "PEP",   "PER",   "PET",   "PEW",   "PHI",   "PI",    "PIE",
+"PIN",   "PIT",   "PLY",   "PO",    "POD",   "POE",   "POP",   "POT",
+"POW",   "PRO",   "PRY",   "PUB",   "PUG",   "PUN",   "PUP",   "PUT",
+"QUO",   "RAG",   "RAM",   "RAN",   "RAP",   "RAT",   "RAW",   "RAY",
+"REB",   "RED",   "REP",   "RET",   "RIB",   "RID",   "RIG",   "RIM",
+"RIO",   "RIP",   "ROB",   "ROD",   "ROE",   "RON",   "ROT",   "ROW",
+"ROY",   "RUB",   "RUE",   "RUG",   "RUM",   "RUN",   "RYE",   "SAC",
+"SAD",   "SAG",   "SAL",   "SAM",   "SAN",   "SAP",   "SAT",   "SAW",
+"SAY",   "SEA",   "SEC",   "SEE",   "SEN",   "SET",   "SEW",   "SHE",
+"SHY",   "SIN",   "SIP",   "SIR",   "SIS",   "SIT",   "SKI",   "SKY",
+"SLY",   "SO",    "SOB",   "SOD",   "SON",   "SOP",   "SOW",   "SOY",
+"SPA",   "SPY",   "SUB",   "SUD",   "SUE",   "SUM",   "SUN",   "SUP",
+"TAB",   "TAD",   "TAG",   "TAN",   "TAP",   "TAR",   "TEA",   "TED",
+"TEE",   "TEN",   "THE",   "THY",   "TIC",   "TIE",   "TIM",   "TIN",
+"TIP",   "TO",    "TOE",   "TOG",   "TOM",   "TON",   "TOO",   "TOP",
+"TOW",   "TOY",   "TRY",   "TUB",   "TUG",   "TUM",   "TUN",   "TWO",
+"UN",    "UP",    "US",   "USE",   "VAN",   "VAT",   "VET",   "VIE",
+"WAD",   "WAG",   "WAR",   "WAS",   "WAY",   "WE",    "WEB",   "WED",
+"WEE",   "WET",   "WHO",   "WHY",   "WIN",   "WIT",   "WOK",   "WON",
+"WOO",   "WOW",   "WRY",   "WU",    "YAM",   "YAP",   "YAW",   "YE",
+"YEA",   "YES",   "YET",   "YOU",   "ABED",  "ABEL",  "ABET",  "ABLE",
+"ABUT",  "ACHE",  "ACID",  "ACME",  "ACRE",  "ACTA",  "ACTS",  "ADAM",
+"ADDS",  "ADEN",  "AFAR",  "AFRO",  "AGEE",  "AHEM",  "AHOY",  "AIDA",
+"AIDE",  "AIDS",  "AIRY",  "AJAR",  "AKIN",  "ALAN",  "ALEC",  "ALGA",
+"ALIA",  "ALLY",  "ALMA",  "ALOE",  "ALSO",  "ALTO",  "ALUM",  "ALVA",
+"AMEN",  "AMES",  "AMID",  "AMMO",  "AMOK",  "AMOS",  "AMRA",  "ANDY",
+"ANEW",  "ANNA",  "ANNE",  "ANTE",  "ANTI",  "AQUA",  "ARAB",  "ARCH",
+"AREA",  "ARGO",  "ARID",  "ARMY",  "ARTS",  "ARTY",  "ASIA",  "ASKS",
+"ATOM",  "AUNT",  "AURA",  "AUTO",  "AVER",  "AVID",  "AVIS",  "AVON",
+"AVOW",  "AWAY",  "AWRY",  "BABE",  "BABY",  "BACH",  "BACK",  "BADE",
+"BAIL",  "BAIT",  "BAKE",  "BALD",  "BALE",  "BALI",  "BALK",  "BALL",
+"BALM",  "BAND",  "BANE",  "BANG",  "BANK",  "BARB",  "BARD",  "BARE",
+"BARK",  "BARN",  "BARR",  "BASE",  "BASH",  "BASK",  "BASS",  "BATE",
+"BATH",  "BAWD",  "BAWL",  "BEAD",  "BEAK",  "BEAM",  "BEAN",  "BEAR",
+"BEAT",  "BEAU",  "BECK",  "BEEF",  "BEEN",  "BEER",  "BEET",  "BELA",
+"BELL",  "BELT",  "BEND",  "BENT",  "BERG",  "BERN",  "BERT",  "BESS",
+"BEST",  "BETA",  "BETH",  "BHOY",  "BIAS",  "BIDE",  "BIEN",  "BILE",
+"BILK",  "BILL",  "BIND",  "BING",  "BIRD",  "BITE",  "BITS",  "BLAB",
+"BLAT",  "BLED",  "BLEW",  "BLOB",  "BLOC",  "BLOT",  "BLOW",  "BLUE",
+"BLUM",  "BLUR",  "BOAR",  "BOAT",  "BOCA",  "BOCK",  "BODE",  "BODY",
+
+
+
+Haller                      Standards Track                    [Page 20]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+"BOGY",  "BOHR",  "BOIL",  "BOLD",  "BOLO",  "BOLT",  "BOMB",  "BONA",
+"BOND",  "BONE",  "BONG",  "BONN",  "BONY",  "BOOK",  "BOOM",  "BOON",
+"BOOT",  "BORE",  "BORG",  "BORN",  "BOSE",  "BOSS",  "BOTH",  "BOUT",
+"BOWL",  "BOYD",  "BRAD",  "BRAE",  "BRAG",  "BRAN",  "BRAY",  "BRED",
+"BREW",  "BRIG",  "BRIM",  "BROW",  "BUCK",  "BUDD",  "BUFF",  "BULB",
+"BULK",  "BULL",  "BUNK",  "BUNT",  "BUOY",  "BURG",  "BURL",  "BURN",
+"BURR",  "BURT",  "BURY",  "BUSH",  "BUSS",  "BUST",  "BUSY",  "BYTE",
+"CADY",  "CAFE",  "CAGE",  "CAIN",  "CAKE",  "CALF",  "CALL",  "CALM",
+"CAME",  "CANE",  "CANT",  "CARD",  "CARE",  "CARL",  "CARR",  "CART",
+"CASE",  "CASH",  "CASK",  "CAST",  "CAVE",  "CEIL",  "CELL",  "CENT",
+"CERN",  "CHAD",  "CHAR",  "CHAT",  "CHAW",  "CHEF",  "CHEN",  "CHEW",
+"CHIC",  "CHIN",  "CHOU",  "CHOW",  "CHUB",  "CHUG",  "CHUM",  "CITE",
+"CITY",  "CLAD",  "CLAM",  "CLAN",  "CLAW",  "CLAY",  "CLOD",  "CLOG",
+"CLOT",  "CLUB",  "CLUE",  "COAL",  "COAT",  "COCA",  "COCK",  "COCO",
+"CODA",  "CODE",  "CODY",  "COED",  "COIL",  "COIN",  "COKE",  "COLA",
+"COLD",  "COLT",  "COMA",  "COMB",  "COME",  "COOK",  "COOL",  "COON",
+"COOT",  "CORD",  "CORE",  "CORK",  "CORN",  "COST",  "COVE",  "COWL",
+"CRAB",  "CRAG",  "CRAM",  "CRAY",  "CREW",  "CRIB",  "CROW",  "CRUD",
+"CUBA",  "CUBE",  "CUFF",  "CULL",  "CULT",  "CUNY",  "CURB",  "CURD",
+"CURE",  "CURL",  "CURT",  "CUTS",  "DADE",  "DALE",  "DAME",  "DANA",
+"DANE",  "DANG",  "DANK",  "DARE",  "DARK",  "DARN",  "DART",  "DASH",
+"DATA",  "DATE",  "DAVE",  "DAVY",  "DAWN",  "DAYS",  "DEAD",  "DEAF",
+"DEAL",  "DEAN",  "DEAR",  "DEBT",  "DECK",  "DEED",  "DEEM",  "DEER",
+"DEFT",  "DEFY",  "DELL",  "DENT",  "DENY",  "DESK",  "DIAL",  "DICE",
+"DIED",  "DIET",  "DIME",  "DINE",  "DING",  "DINT",  "DIRE",  "DIRT",
+"DISC",  "DISH",  "DISK",  "DIVE",  "DOCK",  "DOES",  "DOLE",  "DOLL",
+"DOLT",  "DOME",  "DONE",  "DOOM",  "DOOR",  "DORA",  "DOSE",  "DOTE",
+"DOUG",  "DOUR",  "DOVE",  "DOWN",  "DRAB",  "DRAG",  "DRAM",  "DRAW",
+"DREW",  "DRUB",  "DRUG",  "DRUM",  "DUAL",  "DUCK",  "DUCT",  "DUEL",
+"DUET",  "DUKE",  "DULL",  "DUMB",  "DUNE",  "DUNK",  "DUSK",  "DUST",
+"DUTY",  "EACH",  "EARL",  "EARN",  "EASE",  "EAST",  "EASY",  "EBEN",
+"ECHO",  "EDDY",  "EDEN",  "EDGE",  "EDGY",  "EDIT",  "EDNA",  "EGAN",
+"ELAN",  "ELBA",  "ELLA",  "ELSE",  "EMIL",  "EMIT",  "EMMA",  "ENDS",
+"ERIC",  "EROS",  "EVEN",  "EVER",  "EVIL",  "EYED",  "FACE",  "FACT",
+"FADE",  "FAIL",  "FAIN",  "FAIR",  "FAKE",  "FALL",  "FAME",  "FANG",
+"FARM",  "FAST",  "FATE",  "FAWN",  "FEAR",  "FEAT",  "FEED",  "FEEL",
+"FEET",  "FELL",  "FELT",  "FEND",  "FERN",  "FEST",  "FEUD",  "FIEF",
+"FIGS",  "FILE",  "FILL",  "FILM",  "FIND",  "FINE",  "FINK",  "FIRE",
+"FIRM",  "FISH",  "FISK",  "FIST",  "FITS",  "FIVE",  "FLAG",  "FLAK",
+"FLAM",  "FLAT",  "FLAW",  "FLEA",  "FLED",  "FLEW",  "FLIT",  "FLOC",
+"FLOG",  "FLOW",  "FLUB",  "FLUE",  "FOAL",  "FOAM",  "FOGY",  "FOIL",
+"FOLD",  "FOLK",  "FOND",  "FONT",  "FOOD",  "FOOL",  "FOOT",  "FORD",
+"FORE",  "FORK",  "FORM",  "FORT",  "FOSS",  "FOUL",  "FOUR",  "FOWL",
+"FRAU",  "FRAY",  "FRED",  "FREE",  "FRET",  "FREY",  "FROG",  "FROM",
+"FUEL",  "FULL",  "FUME",  "FUND",  "FUNK",  "FURY",  "FUSE",  "FUSS",
+"GAFF",  "GAGE",  "GAIL",  "GAIN",  "GAIT",  "GALA",  "GALE",  "GALL",
+"GALT",  "GAME",  "GANG",  "GARB",  "GARY",  "GASH",  "GATE",  "GAUL",
+"GAUR",  "GAVE",  "GAWK",  "GEAR",  "GELD",  "GENE",  "GENT",  "GERM",
+
+
+
+Haller                      Standards Track                    [Page 21]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+"GETS",  "GIBE",  "GIFT",  "GILD",  "GILL",  "GILT",  "GINA",  "GIRD",
+"GIRL",  "GIST",  "GIVE",  "GLAD",  "GLEE",  "GLEN",  "GLIB",  "GLOB",
+"GLOM",  "GLOW",  "GLUE",  "GLUM",  "GLUT",  "GOAD",  "GOAL",  "GOAT",
+"GOER",  "GOES",  "GOLD",  "GOLF",  "GONE",  "GONG",  "GOOD",  "GOOF",
+"GORE",  "GORY",  "GOSH",  "GOUT",  "GOWN",  "GRAB",  "GRAD",  "GRAY",
+"GREG",  "GREW",  "GREY",  "GRID",  "GRIM",  "GRIN",  "GRIT",  "GROW",
+"GRUB",  "GULF",  "GULL",  "GUNK",  "GURU",  "GUSH",  "GUST",  "GWEN",
+"GWYN",  "HAAG",  "HAAS",  "HACK",  "HAIL",  "HAIR",  "HALE",  "HALF",
+"HALL",  "HALO",  "HALT",  "HAND",  "HANG",  "HANK",  "HANS",  "HARD",
+"HARK",  "HARM",  "HART",  "HASH",  "HAST",  "HATE",  "HATH",  "HAUL",
+"HAVE",  "HAWK",  "HAYS",  "HEAD",  "HEAL",  "HEAR",  "HEAT",  "HEBE",
+"HECK",  "HEED",  "HEEL",  "HEFT",  "HELD",  "HELL",  "HELM",  "HERB",
+"HERD",  "HERE",  "HERO",  "HERS",  "HESS",  "HEWN",  "HICK",  "HIDE",
+"HIGH",  "HIKE",  "HILL",  "HILT",  "HIND",  "HINT",  "HIRE",  "HISS",
+"HIVE",  "HOBO",  "HOCK",  "HOFF",  "HOLD",  "HOLE",  "HOLM",  "HOLT",
+"HOME",  "HONE",  "HONK",  "HOOD",  "HOOF",  "HOOK",  "HOOT",  "HORN",
+"HOSE",  "HOST",  "HOUR",  "HOVE",  "HOWE",  "HOWL",  "HOYT",  "HUCK",
+"HUED",  "HUFF",  "HUGE",  "HUGH",  "HUGO",  "HULK",  "HULL",  "HUNK",
+"HUNT",  "HURD",  "HURL",  "HURT",  "HUSH",  "HYDE",  "HYMN",  "IBIS",
+"ICON",  "IDEA",  "IDLE",  "IFFY",  "INCA",  "INCH",  "INTO",  "IONS",
+"IOTA",  "IOWA",  "IRIS",  "IRMA",  "IRON",  "ISLE",  "ITCH",  "ITEM",
+"IVAN",  "JACK",  "JADE",  "JAIL",  "JAKE",  "JANE",  "JAVA",  "JEAN",
+"JEFF",  "JERK",  "JESS",  "JEST",  "JIBE",  "JILL",  "JILT",  "JIVE",
+"JOAN",  "JOBS",  "JOCK",  "JOEL",  "JOEY",  "JOHN",  "JOIN",  "JOKE",
+"JOLT",  "JOVE",  "JUDD",  "JUDE",  "JUDO",  "JUDY",  "JUJU",  "JUKE",
+"JULY",  "JUNE",  "JUNK",  "JUNO",  "JURY",  "JUST",  "JUTE",  "KAHN",
+"KALE",  "KANE",  "KANT",  "KARL",  "KATE",  "KEEL",  "KEEN",  "KENO",
+"KENT",  "KERN",  "KERR",  "KEYS",  "KICK",  "KILL",  "KIND",  "KING",
+"KIRK",  "KISS",  "KITE",  "KLAN",  "KNEE",  "KNEW",  "KNIT",  "KNOB",
+"KNOT",  "KNOW",  "KOCH",  "KONG",  "KUDO",  "KURD",  "KURT",  "KYLE",
+"LACE",  "LACK",  "LACY",  "LADY",  "LAID",  "LAIN",  "LAIR",  "LAKE",
+"LAMB",  "LAME",  "LAND",  "LANE",  "LANG",  "LARD",  "LARK",  "LASS",
+"LAST",  "LATE",  "LAUD",  "LAVA",  "LAWN",  "LAWS",  "LAYS",  "LEAD",
+"LEAF",  "LEAK",  "LEAN",  "LEAR",  "LEEK",  "LEER",  "LEFT",  "LEND",
+"LENS",  "LENT",  "LEON",  "LESK",  "LESS",  "LEST",  "LETS",  "LIAR",
+"LICE",  "LICK",  "LIED",  "LIEN",  "LIES",  "LIEU",  "LIFE",  "LIFT",
+"LIKE",  "LILA",  "LILT",  "LILY",  "LIMA",  "LIMB",  "LIME",  "LIND",
+"LINE",  "LINK",  "LINT",  "LION",  "LISA",  "LIST",  "LIVE",  "LOAD",
+"LOAF",  "LOAM",  "LOAN",  "LOCK",  "LOFT",  "LOGE",  "LOIS",  "LOLA",
+"LONE",  "LONG",  "LOOK",  "LOON",  "LOOT",  "LORD",  "LORE",  "LOSE",
+"LOSS",  "LOST",  "LOUD",  "LOVE",  "LOWE",  "LUCK",  "LUCY",  "LUGE",
+"LUKE",  "LULU",  "LUND",  "LUNG",  "LURA",  "LURE",  "LURK",  "LUSH",
+"LUST",  "LYLE",  "LYNN",  "LYON",  "LYRA",  "MACE",  "MADE",  "MAGI",
+"MAID",  "MAIL",  "MAIN",  "MAKE",  "MALE",  "MALI",  "MALL",  "MALT",
+"MANA",  "MANN",  "MANY",  "MARC",  "MARE",  "MARK",  "MARS",  "MART",
+"MARY",  "MASH",  "MASK",  "MASS",  "MAST",  "MATE",  "MATH",  "MAUL",
+"MAYO",  "MEAD",  "MEAL",  "MEAN",  "MEAT",  "MEEK",  "MEET",  "MELD",
+"MELT",  "MEMO",  "MEND",  "MENU",  "MERT",  "MESH",  "MESS",  "MICE",
+
+
+
+Haller                      Standards Track                    [Page 22]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+"MIKE",  "MILD",  "MILE",  "MILK",  "MILL",  "MILT",  "MIMI",  "MIND",
+"MINE",  "MINI",  "MINK",  "MINT",  "MIRE",  "MISS",  "MIST",  "MITE",
+"MITT",  "MOAN",  "MOAT",  "MOCK",  "MODE",  "MOLD",  "MOLE",  "MOLL",
+"MOLT",  "MONA",  "MONK",  "MONT",  "MOOD",  "MOON",  "MOOR",  "MOOT",
+"MORE",  "MORN",  "MORT",  "MOSS",  "MOST",  "MOTH",  "MOVE",  "MUCH",
+"MUCK",  "MUDD",  "MUFF",  "MULE",  "MULL",  "MURK",  "MUSH",  "MUST",
+"MUTE",  "MUTT",  "MYRA",  "MYTH",  "NAGY",  "NAIL",  "NAIR",  "NAME",
+"NARY",  "NASH",  "NAVE",  "NAVY",  "NEAL",  "NEAR",  "NEAT",  "NECK",
+"NEED",  "NEIL",  "NELL",  "NEON",  "NERO",  "NESS",  "NEST",  "NEWS",
+"NEWT",  "NIBS",  "NICE",  "NICK",  "NILE",  "NINA",  "NINE",  "NOAH",
+"NODE",  "NOEL",  "NOLL",  "NONE",  "NOOK",  "NOON",  "NORM",  "NOSE",
+"NOTE",  "NOUN",  "NOVA",  "NUDE",  "NULL",  "NUMB",  "OATH",  "OBEY",
+"OBOE",  "ODIN",  "OHIO",  "OILY",  "OINT",  "OKAY",  "OLAF",  "OLDY",
+"OLGA",  "OLIN",  "OMAN",  "OMEN",  "OMIT",  "ONCE",  "ONES",  "ONLY",
+"ONTO",  "ONUS",  "ORAL",  "ORGY",  "OSLO",  "OTIS",  "OTTO",  "OUCH",
+"OUST",  "OUTS",  "OVAL",  "OVEN",  "OVER",  "OWLY",  "OWNS",  "QUAD",
+"QUIT",  "QUOD",  "RACE",  "RACK",  "RACY",  "RAFT",  "RAGE",  "RAID",
+"RAIL",  "RAIN",  "RAKE",  "RANK",  "RANT",  "RARE",  "RASH",  "RATE",
+"RAVE",  "RAYS",  "READ",  "REAL",  "REAM",  "REAR",  "RECK",  "REED",
+"REEF",  "REEK",  "REEL",  "REID",  "REIN",  "RENA",  "REND",  "RENT",
+"REST",  "RICE",  "RICH",  "RICK",  "RIDE",  "RIFT",  "RILL",  "RIME",
+"RING",  "RINK",  "RISE",  "RISK",  "RITE",  "ROAD",  "ROAM",  "ROAR",
+"ROBE",  "ROCK",  "RODE",  "ROIL",  "ROLL",  "ROME",  "ROOD",  "ROOF",
+"ROOK",  "ROOM",  "ROOT",  "ROSA",  "ROSE",  "ROSS",  "ROSY",  "ROTH",
+"ROUT",  "ROVE",  "ROWE",  "ROWS",  "RUBE",  "RUBY",  "RUDE",  "RUDY",
+"RUIN",  "RULE",  "RUNG",  "RUNS",  "RUNT",  "RUSE",  "RUSH",  "RUSK",
+"RUSS",  "RUST",  "RUTH",  "SACK",  "SAFE",  "SAGE",  "SAID",  "SAIL",
+"SALE",  "SALK",  "SALT",  "SAME",  "SAND",  "SANE",  "SANG",  "SANK",
+"SARA",  "SAUL",  "SAVE",  "SAYS",  "SCAN",  "SCAR",  "SCAT",  "SCOT",
+"SEAL",  "SEAM",  "SEAR",  "SEAT",  "SEED",  "SEEK",  "SEEM",  "SEEN",
+"SEES",  "SELF",  "SELL",  "SEND",  "SENT",  "SETS",  "SEWN",  "SHAG",
+"SHAM",  "SHAW",  "SHAY",  "SHED",  "SHIM",  "SHIN",  "SHOD",  "SHOE",
+"SHOT",  "SHOW",  "SHUN",  "SHUT",  "SICK",  "SIDE",  "SIFT",  "SIGH",
+"SIGN",  "SILK",  "SILL",  "SILO",  "SILT",  "SINE",  "SING",  "SINK",
+"SIRE",  "SITE",  "SITS",  "SITU",  "SKAT",  "SKEW",  "SKID",  "SKIM",
+"SKIN",  "SKIT",  "SLAB",  "SLAM",  "SLAT",  "SLAY",  "SLED",  "SLEW",
+"SLID",  "SLIM",  "SLIT",  "SLOB",  "SLOG",  "SLOT",  "SLOW",  "SLUG",
+"SLUM",  "SLUR",  "SMOG",  "SMUG",  "SNAG",  "SNOB",  "SNOW",  "SNUB",
+"SNUG",  "SOAK",  "SOAR",  "SOCK",  "SODA",  "SOFA",  "SOFT",  "SOIL",
+"SOLD",  "SOME",  "SONG",  "SOON",  "SOOT",  "SORE",  "SORT",  "SOUL",
+"SOUR",  "SOWN",  "STAB",  "STAG",  "STAN",  "STAR",  "STAY",  "STEM",
+"STEW",  "STIR",  "STOW",  "STUB",  "STUN",  "SUCH",  "SUDS",  "SUIT",
+"SULK",  "SUMS",  "SUNG",  "SUNK",  "SURE",  "SURF",  "SWAB",  "SWAG",
+"SWAM",  "SWAN",  "SWAT",  "SWAY",  "SWIM",  "SWUM",  "TACK",  "TACT",
+"TAIL",  "TAKE",  "TALE",  "TALK",  "TALL",  "TANK",  "TASK",  "TATE",
+"TAUT",  "TEAL",  "TEAM",  "TEAR",  "TECH",  "TEEM",  "TEEN",  "TEET",
+"TELL",  "TEND",  "TENT",  "TERM",  "TERN",  "TESS",  "TEST",  "THAN",
+"THAT",  "THEE",  "THEM",  "THEN",  "THEY",  "THIN",  "THIS",  "THUD",
+
+
+
+Haller                      Standards Track                    [Page 23]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+"THUG",  "TICK",  "TIDE",  "TIDY",  "TIED",  "TIER",  "TILE",  "TILL",
+"TILT",  "TIME",  "TINA",  "TINE",  "TINT",  "TINY",  "TIRE",  "TOAD",
+"TOGO",  "TOIL",  "TOLD",  "TOLL",  "TONE",  "TONG",  "TONY",  "TOOK",
+"TOOL",  "TOOT",  "TORE",  "TORN",  "TOTE",  "TOUR",  "TOUT",  "TOWN",
+"TRAG",  "TRAM",  "TRAY",  "TREE",  "TREK",  "TRIG",  "TRIM",  "TRIO",
+"TROD",  "TROT",  "TROY",  "TRUE",  "TUBA",  "TUBE",  "TUCK",  "TUFT",
+"TUNA",  "TUNE",  "TUNG",  "TURF",  "TURN",  "TUSK",  "TWIG",  "TWIN",
+"TWIT",  "ULAN",  "UNIT",  "URGE",  "USED",  "USER",  "USES",  "UTAH",
+"VAIL",  "VAIN",  "VALE",  "VARY",  "VASE",  "VAST",  "VEAL",  "VEDA",
+"VEIL",  "VEIN",  "VEND",  "VENT",  "VERB",  "VERY",  "VETO",  "VICE",
+"VIEW",  "VINE",  "VISE",  "VOID",  "VOLT",  "VOTE",  "WACK",  "WADE",
+"WAGE",  "WAIL",  "WAIT",  "WAKE",  "WALE",  "WALK",  "WALL",  "WALT",
+"WAND",  "WANE",  "WANG",  "WANT",  "WARD",  "WARM",  "WARN",  "WART",
+"WASH",  "WAST",  "WATS",  "WATT",  "WAVE",  "WAVY",  "WAYS",  "WEAK",
+"WEAL",  "WEAN",  "WEAR",  "WEED",  "WEEK",  "WEIR",  "WELD",  "WELL",
+"WELT",  "WENT",  "WERE",  "WERT",  "WEST",  "WHAM",  "WHAT",  "WHEE",
+"WHEN",  "WHET",  "WHOA",  "WHOM",  "WICK",  "WIFE",  "WILD",  "WILL",
+"WIND",  "WINE",  "WING",  "WINK",  "WINO",  "WIRE",  "WISE",  "WISH",
+"WITH",  "WOLF",  "WONT",  "WOOD",  "WOOL",  "WORD",  "WORE",  "WORK",
+"WORM",  "WORN",  "WOVE",  "WRIT",  "WYNN",  "YALE",  "YANG",  "YANK",
+"YARD",  "YARN",  "YAWL",  "YAWN",  "YEAH",  "YEAR",  "YELL",  "YOGA",
+"YOKE"   };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 24]
+\f
+RFC 2289               A One-Time Password System          February 1998
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Haller                      Standards Track                    [Page 25]
+\f
diff --git a/doc/rfc2444.txt b/doc/rfc2444.txt
new file mode 100644 (file)
index 0000000..80a65a2
--- /dev/null
@@ -0,0 +1,395 @@
+
+
+
+
+
+
+Network Working Group                                          C. Newman
+Request for Comments: 2444                                      Innosoft
+Updates: 2222                                               October 1998
+Category: Standards Track
+
+
+                  The One-Time-Password SASL Mechanism
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+Abstract
+
+   OTP [OTP] provides a useful authentication mechanism for situations
+   where there is limited client or server trust.  Currently, OTP is
+   added to protocols in an ad-hoc fashion with heuristic parsing.  This
+   specification defines an OTP SASL [SASL] mechanism so it can be
+   easily and formally integrated into many application protocols.
+
+1. How to Read This Document
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
+   "RECOMMENDED" and "MAY" in this document are to be interpreted as
+   defined in "Key words for use in RFCs to Indicate Requirement Levels"
+   [KEYWORDS].
+
+   This memo assumes the reader is familiar with OTP [OTP], OTP extended
+   responses [OTP-EXT] and SASL [SASL].
+
+2. Intended Use
+
+   The OTP SASL mechanism replaces the SKEY SASL mechanism [SASL].  OTP
+   is a good choice for usage scenarios where the client is untrusted
+   (e.g., a kiosk client), as a one-time password will only give the
+   client a single opportunity to act on behalf of the user.  OTP is
+   also a good choice for situations where interactive logins are
+   permitted to the server, as a compromised OTP authentication database
+   is only subject to dictionary attacks, unlike authentication
+   databases for other simple mechanisms such as CRAM-MD5 [CRAM-MD5].
+
+
+
+Newman                      Standards Track                     [Page 1]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+   It is important to note that each use of the OTP mechanism causes the
+   authentication database entry for a user to be updated.
+
+   This SASL mechanism provides a formal way to integrate OTP into
+   SASL-enabled protocols including IMAP [IMAP4], ACAP [ACAP], POP3
+   [POP-AUTH] and LDAPv3 [LDAPv3].
+
+3. Profiling OTP for SASL
+
+   OTP [OTP] and OTP extended responses [OTP-EXT] offer a number of
+   options.  However, for authentication to succeed, the client and
+   server need compatible option sets.  This specification defines a
+   single SASL mechanism: OTP.  The following rules apply to this
+   mechanism:
+
+   o   The extended response syntax MUST be used.
+
+   o   Servers MUST support the following four OTP extended responses:
+       "hex", "word", "init-hex" and "init-word".  Servers MUST support
+       the "word" and "init-word" responses for the standard dictionary
+       and SHOULD support alternate dictionaries.  Servers MUST NOT
+       require use of any additional OTP extensions or options.
+
+   o   Clients SHOULD support display of the OTP challenge to the user
+       and entry of an OTP in multi-word format.  Clients MAY also
+       support direct entry of the pass phrase and compute the "hex" or
+       "word" response.
+
+   o   Clients MUST indicate when authentication fails due to the
+       sequence number getting too low and SHOULD offer the user the
+       option to reset the sequence using the "init-hex" or "init-word"
+       response.
+
+   Support for the MD5 algorithm is REQUIRED, and support for the SHA1
+   algorithm is RECOMMENDED.
+
+4. OTP Authentication Mechanism
+
+   The mechanism does not provide any security layer.
+
+   The client begins by sending a message to the server containing the
+   following two pieces of information.
+
+   (1) An authorization identity.  When the empty string is used, this
+   defaults to the authentication identity.  This is used by system
+   administrators or proxy servers to login with a different user
+   identity.  This field may be up to 255 octets and is terminated by a
+   NUL (0) octet.  US-ASCII printable characters are preferred, although
+
+
+
+Newman                      Standards Track                     [Page 2]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+   UTF-8 [UTF-8] printable characters are permitted to support
+   international names.  Use of character sets other than US-ASCII and
+   UTF-8 is forbidden.
+
+   (2) An authentication identity.  The identity whose pass phrase will
+   be used.  This field may be up to 255 octets.  US-ASCII printable
+   characters are preferred, although UTF-8 [UTF-8] printable characters
+   are permitted to support international names.  Use of character sets
+   other than US-ASCII and UTF-8 is forbidden.
+
+   The server responds by sending a message containing the OTP challenge
+   as described in OTP [OTP] and OTP extended responses [OTP-EXT].
+
+   If a client sees an unknown hash algorithm name it will not be able
+   to process a pass phrase input by the user.  In this situation the
+   client MAY prompt for the six-word format, issue the cancel sequence
+   as specified by the SASL profile for the protocol in use and try a
+   different SASL mechanism, or close the connection and refuse to
+   authenticate.  As a result of this behavior, a server is restricted
+   to one OTP hash algorithm per user.
+
+   On success, the client generates an extended response in the "hex",
+   "word", "init-hex" or "init-word" format.  The client is not required
+   to terminate the response with a space or a newline and SHOULD NOT
+   include unnecessary whitespace.
+
+   Servers MUST tolerate input of arbitrary length, but MAY fail the
+   authentication if the length of client input exceeds reasonable size.
+
+5. Examples
+
+   In these example, "C:" represents lines sent from the client to the
+   server and "S:" represents lines sent from the server to the client.
+   The user name is "tim" and no authorization identity is provided.
+   The "<NUL>" below represents an ASCII NUL octet.
+
+   The following is an example of the OTP mechanism using the ACAP
+   [ACAP] profile of SASL.  The pass phrase used in this example is:
+             This is a test.
+
+          C: a001 AUTHENTICATE "OTP" {4}
+          C: <NUL>tim
+          S: + "otp-md5 499 ke1234 ext"
+          C: "hex:5bf075d9959d036f"
+          S: a001 OK "AUTHENTICATE completed"
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 3]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+        Here is the same example using the six-words response:
+
+          C: a001 AUTHENTICATE "OTP" {4}
+          C: <NUL>tim
+          S: + "otp-md5 499 ke1234 ext"
+          C: "word:BOND FOGY DRAB NE RISE MART"
+          S: a001 OK "AUTHENTICATE completed"
+
+        Here is the same example using the OTP-SHA1 mechanism:
+
+          C: a001 AUTHENTICATE "OTP" {4}
+          C: <NUL>tim
+          S: + "otp-sha1 499 ke1234 ext"
+          C: "hex:c90fc02cc488df5e"
+          S: a001 OK "AUTHENTICATE completed"
+
+        Here is the same example with the init-hex extended response
+
+          C: a001 AUTHENTICATE "OTP" {4}
+          C: <NUL>tim
+          S: + "otp-md5 499 ke1234 ext"
+          C: "init-hex:5bf075d9959d036f:md5 499 ke1235:3712dcb4aa5316c1"
+          S: a001 OK "OTP sequence reset, authentication complete"
+
+     The following is an example of the OTP mechanism using the IMAP
+     [IMAP4] profile of SASL.  The pass phrase used in this example is:
+          this is a test
+
+       C: a001 AUTHENTICATE OTP
+       S: +
+       C: AHRpbQ==
+       S: + b3RwLW1kNSAxMjMga2UxMjM0IGV4dA==
+       C: aGV4OjExZDRjMTQ3ZTIyN2MxZjE=
+       S: a001 OK AUTHENTICATE completed
+
+   Note that the lack of an initial client response and the base64
+   encoding are characteristics of the IMAP profile of SASL.  The server
+   challenge is "otp-md5 123 ke1234 ext" and the client response is
+   "hex:11d4c147e227c1f1".
+
+6. Security Considerations
+
+   This specification introduces no security considerations beyond those
+   those described in SASL [SASL], OTP [OTP] and OTP extended responses
+   [OTP-EXT].  A brief summary of these considerations follows:
+
+   This mechanism does not provide session privacy, server
+   authentication or protection from active attacks.
+
+
+
+Newman                      Standards Track                     [Page 4]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+   This mechanism is subject to passive dictionary attacks.  The
+   severity of this attack can be reduced by choosing pass phrases well.
+
+   The server authentication database necessary for use with OTP need
+   not be plaintext-equivalent.
+
+   Server implementations MUST protect against the race attack [OTP].
+
+7. Multinational Considerations
+
+   As remote access is a crucial service, users are encouraged to
+   restrict user names and pass phrases to the US-ASCII character set.
+   However, if characters outside the US-ASCII chracter set are used in
+   user names and pass phrases, then they are interpreted according to
+   UTF-8 [UTF-8].
+
+   Server support for alternate dictionaries is strongly RECOMMENDED to
+   permit use of the six-word format with non-English words.
+
+8. IANA Considerations
+
+   Here is the registration template for the OTP SASL mechanism:
+
+   SASL mechanism name: OTP
+   Security Considerations: See section 6 of this memo
+   Published specification: this memo
+   Person & email address to contact for futher information:
+     see author's address section below
+   Intended usage: COMMON
+   Author/Change controller: see author's address section below
+
+   This memo also amends the SKEY SASL mechanism registration [SASL] by
+   changing its intended usage to OBSOLETE.
+
+9. References
+
+   [ACAP]     Newman, C. and J. Myers, "ACAP -- Application
+              Configuration Access Protocol", RFC 2244, November 1997.
+
+   [CRAM-MD5] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+              AUTHorize Extension for Simple Challenge/Response", RFC
+              2195, September 1997.
+
+   [IMAP4]    Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+
+
+Newman                      Standards Track                     [Page 5]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+   [LDAPv3]   Wahl, M., Howes, T. and S. Kille, "Lightweight Directory
+              Access Protocol (v3)", RFC 2251, December 1997.
+
+   [MD5]      Rivest, R., "The MD5 Message Digest Algorithm", RFC 1321,
+              April 1992.
+
+   [OTP]      Haller, N., Metz, C., Nesser, P. and M. Straw, "A One-Time
+              Password System", RFC 2289, February 1998.
+
+   [OTP-EXT]  Metz, C., "OTP Extended Responses", RFC 2243, November
+              1997.
+
+   [POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734,
+              December 1994.
+
+   [SASL]     Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997.
+
+   [UTF-8]    Yergeau, F., "UTF-8, a transformation format of ISO
+              10646", RFC 2279, January 1998.
+
+10. Author's Address
+
+   Chris Newman
+   Innosoft International, Inc.
+   1050 Lakes Drive
+   West Covina, CA 91790 USA
+
+   EMail: chris.newman@innosoft.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 6]
+\f
+RFC 2444                   OTP SASL Mechanism               October 1998
+
+
+11.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (1998).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 7]
+\f
diff --git a/doc/rfc2595.txt b/doc/rfc2595.txt
new file mode 100644 (file)
index 0000000..3b2b4c5
--- /dev/null
@@ -0,0 +1,843 @@
+
+
+
+
+
+
+Network Working Group                                          C. Newman
+Request for Comments: 2595                                      Innosoft
+Category: Standards Track                                      June 1999
+
+
+                   Using TLS with IMAP, POP3 and ACAP
+
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+1. Motivation
+
+   The TLS protocol (formerly known as SSL) provides a way to secure an
+   application protocol from tampering and eavesdropping.  The option of
+   using such security is desirable for IMAP, POP and ACAP due to common
+   connection eavesdropping and hijacking attacks [AUTH].  Although
+   advanced SASL authentication mechanisms can provide a lightweight
+   version of this service, TLS is complimentary to simple
+   authentication-only SASL mechanisms or deployed clear-text password
+   login commands.
+
+   Many sites have a high investment in authentication infrastructure
+   (e.g., a large database of a one-way-function applied to user
+   passwords), so a privacy layer which is not tightly bound to user
+   authentication can protect against network eavesdropping attacks
+   without requiring a new authentication infrastructure and/or forcing
+   all users to change their password.  Recognizing that such sites will
+   desire simple password authentication in combination with TLS
+   encryption, this specification defines the PLAIN SASL mechanism for
+   use with protocols which lack a simple password authentication
+   command such as ACAP and SMTP.  (Note there is a separate RFC for the
+   STARTTLS command in SMTP [SMTPTLS].)
+
+   There is a strong desire in the IETF to eliminate the transmission of
+   clear-text passwords over unencrypted channels.  While SASL can be
+   used for this purpose, TLS provides an additional tool with different
+   deployability characteristics.  A server supporting both TLS with
+
+
+
+
+Newman                      Standards Track                     [Page 1]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   simple passwords and a challenge/response SASL mechanism is likely to
+   interoperate with a wide variety of clients without resorting to
+   unencrypted clear-text passwords.
+
+   The STARTTLS command rectifies a number of the problems with using a
+   separate port for a "secure" protocol variant.  Some of these are
+   mentioned in section 7.
+
+1.1. Conventions Used in this Document
+
+   The key words "REQUIRED", "MUST", "MUST NOT", "SHOULD", "SHOULD NOT",
+   "MAY", and "OPTIONAL" in this document are to be interpreted as
+   described in "Key words for use in RFCs to Indicate Requirement
+   Levels" [KEYWORDS].
+
+   Terms related to authentication are defined in "On Internet
+   Authentication" [AUTH].
+
+   Formal syntax is defined using ABNF [ABNF].
+
+   In examples, "C:" and "S:" indicate lines sent by the client and
+   server respectively.
+
+2. Basic Interoperability and Security Requirements
+
+   The following requirements apply to all implementations of the
+   STARTTLS extension for IMAP, POP3 and ACAP.
+
+2.1. Cipher Suite Requirements
+
+   Implementation of the TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [TLS] cipher
+   suite is REQUIRED.  This is important as it assures that any two
+   compliant implementations can be configured to interoperate.
+
+   All other cipher suites are OPTIONAL.
+
+2.2. Privacy Operational Mode Security Requirements
+
+   Both clients and servers SHOULD have a privacy operational mode which
+   refuses authentication unless successful activation of an encryption
+   layer (such as that provided by TLS) occurs prior to or at the time
+   of authentication and which will terminate the connection if that
+   encryption layer is deactivated.  Implementations are encouraged to
+   have flexibility with respect to the minimal encryption strength or
+   cipher suites permitted.  A minimalist approach to this
+   recommendation would be an operational mode where the
+   TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA cipher suite is mandatory prior to
+   permitting authentication.
+
+
+
+Newman                      Standards Track                     [Page 2]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   Clients MAY have an operational mode which uses encryption only when
+   it is advertised by the server, but authentication continues
+   regardless.  For backwards compatibility, servers SHOULD have an
+   operational mode where only the authentication mechanisms required by
+   the relevant base protocol specification are needed to successfully
+   authenticate.
+
+2.3. Clear-Text Password Requirements
+
+   Clients and servers which implement STARTTLS MUST be configurable to
+   refuse all clear-text login commands or mechanisms (including both
+   standards-track and nonstandard mechanisms) unless an encryption
+   layer of adequate strength is active.  Servers which allow
+   unencrypted clear-text logins SHOULD be configurable to refuse
+   clear-text logins both for the entire server, and on a per-user
+   basis.
+
+2.4. Server Identity Check
+
+   During the TLS negotiation, the client MUST check its understanding
+   of the server hostname against the server's identity as presented in
+   the server Certificate message, in order to prevent man-in-the-middle
+   attacks.  Matching is performed according to these rules:
+
+   - The client MUST use the server hostname it used to open the
+     connection as the value to compare against the server name as
+     expressed in the server certificate.  The client MUST NOT use any
+     form of the server hostname derived from an insecure remote source
+     (e.g., insecure DNS lookup).  CNAME canonicalization is not done.
+
+   - If a subjectAltName extension of type dNSName is present in the
+     certificate, it SHOULD be used as the source of the server's
+     identity.
+
+   - Matching is case-insensitive.
+
+   - A "*" wildcard character MAY be used as the left-most name
+     component in the certificate.  For example, *.example.com would
+     match a.example.com, foo.example.com, etc. but would not match
+     example.com.
+
+   - If the certificate contains multiple names (e.g. more than one
+     dNSName field), then a match with any one of the fields is
+     considered acceptable.
+
+   If the match fails, the client SHOULD either ask for explicit user
+   confirmation, or terminate the connection and indicate the server's
+   identity is suspect.
+
+
+
+Newman                      Standards Track                     [Page 3]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+2.5. TLS Security Policy Check
+
+   Both the client and server MUST check the result of the STARTTLS
+   command and subsequent TLS negotiation to see whether acceptable
+   authentication or privacy was achieved.  Ignoring this step
+   completely invalidates using TLS for security.  The decision about
+   whether acceptable authentication or privacy was achieved is made
+   locally, is implementation-dependent, and is beyond the scope of this
+   document.
+
+3. IMAP STARTTLS extension
+
+   When the TLS extension is present in IMAP, "STARTTLS" is listed as a
+   capability in response to the CAPABILITY command.  This extension
+   adds a single command, "STARTTLS" to the IMAP protocol which is used
+   to begin a TLS negotiation.
+
+3.1. STARTTLS Command
+
+   Arguments:  none
+
+   Responses:  no specific responses for this command
+
+   Result:     OK - begin TLS negotiation
+               BAD - command unknown or arguments invalid
+
+      A TLS negotiation begins immediately after the CRLF at the end of
+      the tagged OK response from the server.  Once a client issues a
+      STARTTLS command, it MUST NOT issue further commands until a
+      server response is seen and the TLS negotiation is complete.
+
+      The STARTTLS command is only valid in non-authenticated state.
+      The server remains in non-authenticated state, even if client
+      credentials are supplied during the TLS negotiation.  The SASL
+      [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS
+      client credentials are successfully exchanged, but servers
+      supporting the STARTTLS command are not required to support the
+      EXTERNAL mechanism.
+
+      Once TLS has been started, the client MUST discard cached
+      information about server capabilities and SHOULD re-issue the
+      CAPABILITY command.  This is necessary to protect against
+      man-in-the-middle attacks which alter the capabilities list prior
+      to STARTTLS.  The server MAY advertise different capabilities
+      after STARTTLS.
+
+      The formal syntax for IMAP is amended as follows:
+
+
+
+
+Newman                      Standards Track                     [Page 4]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+        command_any   =/  "STARTTLS"
+
+   Example:    C: a001 CAPABILITY
+               S: * CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED
+               S: a001 OK CAPABILITY completed
+               C: a002 STARTTLS
+               S: a002 OK Begin TLS negotiation now
+               <TLS negotiation, further commands are under TLS layer>
+               C: a003 CAPABILITY
+               S: * CAPABILITY IMAP4rev1 AUTH=EXTERNAL
+               S: a003 OK CAPABILITY completed
+               C: a004 LOGIN joe password
+               S: a004 OK LOGIN completed
+
+3.2. IMAP LOGINDISABLED capability
+
+   The current IMAP protocol specification (RFC 2060) requires the
+   implementation of the LOGIN command which uses clear-text passwords.
+   Many sites may choose to disable this command unless encryption is
+   active for security reasons.  An IMAP server MAY advertise that the
+   LOGIN command is disabled by including the LOGINDISABLED capability
+   in the capability response.  Such a server will respond with a tagged
+   "NO" response to any attempt to use the LOGIN command.
+
+   An IMAP server which implements STARTTLS MUST implement support for
+   the LOGINDISABLED capability on unencrypted connections.
+
+   An IMAP client which complies with this specification MUST NOT issue
+   the LOGIN command if this capability is present.
+
+   This capability is useful to prevent clients compliant with this
+   specification from sending an unencrypted password in an environment
+   subject to passive attacks.  It has no impact on an environment
+   subject to active attacks as a man-in-the-middle attacker can remove
+   this capability.  Therefore this does not relieve clients of the need
+   to follow the privacy mode recommendation in section 2.2.
+
+   Servers advertising this capability will fail to interoperate with
+   many existing compliant IMAP clients and will be unable to prevent
+   those clients from disclosing the user's password.
+
+4. POP3 STARTTLS extension
+
+   The POP3 STARTTLS extension adds the STLS command to POP3 servers.
+   If this is implemented, the POP3 extension mechanism [POP3EXT] MUST
+   also be implemented to avoid the need for client probing of multiple
+   commands.  The capability name "STLS" indicates this command is
+   present and permitted in the current state.
+
+
+
+Newman                      Standards Track                     [Page 5]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+      STLS
+
+         Arguments: none
+
+         Restrictions:
+             Only permitted in AUTHORIZATION state.
+
+         Discussion:
+             A TLS negotiation begins immediately after the CRLF at the
+             end of the +OK response from the server.  A -ERR response
+             MAY result if a security layer is already active.  Once a
+             client issues a STLS command, it MUST NOT issue further
+             commands until a server response is seen and the TLS
+             negotiation is complete.
+
+             The STLS command is only permitted in AUTHORIZATION state
+             and the server remains in AUTHORIZATION state, even if
+             client credentials are supplied during the TLS negotiation.
+             The AUTH command [POP-AUTH] with the EXTERNAL mechanism
+             [SASL] MAY be used to authenticate once TLS client
+             credentials are successfully exchanged, but servers
+             supporting the STLS command are not required to support the
+             EXTERNAL mechanism.
+
+             Once TLS has been started, the client MUST discard cached
+             information about server capabilities and SHOULD re-issue
+             the CAPA command.  This is necessary to protect against
+             man-in-the-middle attacks which alter the capabilities list
+             prior to STLS.  The server MAY advertise different
+             capabilities after STLS.
+
+         Possible Responses:
+             +OK -ERR
+
+         Examples:
+             C: STLS
+             S: +OK Begin TLS negotiation
+             <TLS negotiation, further commands are under TLS layer>
+               ...
+             C: STLS
+             S: -ERR Command not permitted when TLS active
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                     [Page 6]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+5. ACAP STARTTLS extension
+
+   When the TLS extension is present in ACAP, "STARTTLS" is listed as a
+   capability in the ACAP greeting.  No arguments to this capability are
+   defined at this time.  This extension adds a single command,
+   "STARTTLS" to the ACAP protocol which is used to begin a TLS
+   negotiation.
+
+5.1. STARTTLS Command
+
+   Arguments:  none
+
+   Responses:  no specific responses for this command
+
+   Result:     OK - begin TLS negotiation
+               BAD - command unknown or arguments invalid
+
+      A TLS negotiation begins immediately after the CRLF at the end of
+      the tagged OK response from the server.  Once a client issues a
+      STARTTLS command, it MUST NOT issue further commands until a
+      server response is seen and the TLS negotiation is complete.
+
+      The STARTTLS command is only valid in non-authenticated state.
+      The server remains in non-authenticated state, even if client
+      credentials are supplied during the TLS negotiation.  The SASL
+      [SASL] EXTERNAL mechanism MAY be used to authenticate once TLS
+      client credentials are successfully exchanged, but servers
+      supporting the STARTTLS command are not required to support the
+      EXTERNAL mechanism.
+
+      After the TLS layer is established, the server MUST re-issue an
+      untagged ACAP greeting.  This is necessary to protect against
+      man-in-the-middle attacks which alter the capabilities list prior
+      to STARTTLS.  The client MUST discard cached capability
+      information and replace it with the information from the new ACAP
+      greeting.  The server MAY advertise different capabilities after
+      STARTTLS.
+
+      The formal syntax for ACAP is amended as follows:
+
+        command_any   =/  "STARTTLS"
+
+   Example:    S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
+               C: a002 STARTTLS
+               S: a002 OK "Begin TLS negotiation now"
+               <TLS negotiation, further commands are under TLS layer>
+               S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL")
+
+
+
+
+Newman                      Standards Track                     [Page 7]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+6. PLAIN SASL mechanism
+
+   Clear-text passwords are simple, interoperate with almost all
+   existing operating system authentication databases, and are useful
+   for a smooth transition to a more secure password-based
+   authentication mechanism.  The drawback is that they are unacceptable
+   for use over an unencrypted network connection.
+
+   This defines the "PLAIN" SASL mechanism for use with ACAP and other
+   protocols with no clear-text login command.  The PLAIN SASL mechanism
+   MUST NOT be advertised or used unless a strong encryption layer (such
+   as the provided by TLS) is active or backwards compatibility dictates
+   otherwise.
+
+   The mechanism consists of a single message from the client to the
+   server.  The client sends the authorization identity (identity to
+   login as), followed by a US-ASCII NUL character, followed by the
+   authentication identity (identity whose password will be used),
+   followed by a US-ASCII NUL character, followed by the clear-text
+   password.  The client may leave the authorization identity empty to
+   indicate that it is the same as the authentication identity.
+
+   The server will verify the authentication identity and password with
+   the system authentication database and verify that the authentication
+   credentials permit the client to login as the authorization identity.
+   If both steps succeed, the user is logged in.
+
+   The server MAY also use the password to initialize any new
+   authentication database, such as one suitable for CRAM-MD5
+   [CRAM-MD5].
+
+   Non-US-ASCII characters are permitted as long as they are represented
+   in UTF-8 [UTF-8].  Use of non-visible characters or characters which
+   a user may be unable to enter on some keyboards is discouraged.
+
+   The formal grammar for the client message using Augmented BNF [ABNF]
+   follows.
+
+   message         = [authorize-id] NUL authenticate-id NUL password
+   authenticate-id = 1*UTF8-SAFE      ; MUST accept up to 255 octets
+   authorize-id    = 1*UTF8-SAFE      ; MUST accept up to 255 octets
+   password        = 1*UTF8-SAFE      ; MUST accept up to 255 octets
+   NUL             = %x00
+   UTF8-SAFE       = %x01-09 / %x0B-0C / %x0E-7F / UTF8-2 /
+                     UTF8-3 / UTF8-4 / UTF8-5 / UTF8-6
+   UTF8-1          = %x80-BF
+   UTF8-2          = %xC0-DF UTF8-1
+   UTF8-3          = %xE0-EF 2UTF8-1
+
+
+
+Newman                      Standards Track                     [Page 8]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   UTF8-4          = %xF0-F7 3UTF8-1
+   UTF8-5          = %xF8-FB 4UTF8-1
+   UTF8-6          = %xFC-FD 5UTF8-1
+
+   Here is an example of how this might be used to initialize a CRAM-MD5
+   authentication database for ACAP:
+
+   Example:    S: * ACAP (SASL "CRAM-MD5") (STARTTLS)
+               C: a001 AUTHENTICATE "CRAM-MD5"
+               S: + "<1896.697170952@postoffice.reston.mci.net>"
+               C: "tim b913a602c7eda7a495b4e6e7334d3890"
+               S: a001 NO (TRANSITION-NEEDED)
+                  "Please change your password, or use TLS to login"
+               C: a002 STARTTLS
+               S: a002 OK "Begin TLS negotiation now"
+               <TLS negotiation, further commands are under TLS layer>
+               S: * ACAP (SASL "CRAM-MD5" "PLAIN" "EXTERNAL")
+               C: a003 AUTHENTICATE "PLAIN" {21+}
+               C: <NUL>tim<NUL>tanstaaftanstaaf
+               S: a003 OK CRAM-MD5 password initialized
+
+   Note: In this example, <NUL> represents a single ASCII NUL octet.
+
+7. imaps and pop3s ports
+
+   Separate "imaps" and "pop3s" ports were registered for use with SSL.
+   Use of these ports is discouraged in favor of the STARTTLS or STLS
+   commands.
+
+   A number of problems have been observed with separate ports for
+   "secure" variants of protocols.  This is an attempt to enumerate some
+   of those problems.
+
+   - Separate ports lead to a separate URL scheme which intrudes into
+     the user interface in inappropriate ways.  For example, many web
+     pages use language like "click here if your browser supports SSL."
+     This is a decision the browser is often more capable of making than
+     the user.
+
+   - Separate ports imply a model of either "secure" or "not secure."
+     This can be misleading in a number of ways.  First, the "secure"
+     port may not in fact be acceptably secure as an export-crippled
+     cipher suite might be in use.  This can mislead users into a false
+     sense of security.  Second, the normal port might in fact be
+     secured by using a SASL mechanism which includes a security layer.
+     Thus the separate port distinction makes the complex topic of
+     security policy even more confusing.  One common result of this
+     confusion is that firewall administrators are often misled into
+
+
+
+Newman                      Standards Track                     [Page 9]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+     permitting the "secure" port and blocking the standard port.  This
+     could be a poor choice given the common use of SSL with a 40-bit
+     key encryption layer and plain-text password authentication is less
+     secure than strong SASL mechanisms such as GSSAPI with Kerberos 5.
+
+   - Use of separate ports for SSL has caused clients to implement only
+     two security policies: use SSL or don't use SSL.  The desirable
+     security policy "use TLS when available" would be cumbersome with
+     the separate port model, but is simple with STARTTLS.
+
+   - Port numbers are a limited resource.  While they are not yet in
+     short supply, it is unwise to set a precedent that could double (or
+     worse) the speed of their consumption.
+
+
+8. IANA Considerations
+
+   This constitutes registration of the "STARTTLS" and "LOGINDISABLED"
+   IMAP capabilities as required by section 7.2.1 of RFC 2060 [IMAP].
+
+   The registration for the POP3 "STLS" capability follows:
+
+   CAPA tag:                   STLS
+   Arguments:                  none
+   Added commands:             STLS
+   Standard commands affected: May enable USER/PASS as a side-effect.
+     CAPA command SHOULD be re-issued after successful completion.
+   Announced states/Valid states: AUTHORIZATION state only.
+   Specification reference:    this memo
+
+   The registration for the ACAP "STARTTLS" capability follows:
+
+   Capability name:            STARTTLS
+   Capability keyword:         STARTTLS
+   Capability arguments:       none
+   Published Specification(s): this memo
+   Person and email address for further information:
+       see author's address section below
+
+   The registration for the PLAIN SASL mechanism follows:
+
+   SASL mechanism name:        PLAIN
+   Security Considerations:    See section 9 of this memo
+   Published specification:    this memo
+   Person & email address to contact for further information:
+       see author's address section below
+   Intended usage:             COMMON
+   Author/Change controller:   see author's address section below
+
+
+
+Newman                      Standards Track                    [Page 10]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+9. Security Considerations
+
+   TLS only provides protection for data sent over a network connection.
+   Messages transferred over IMAP or POP3 are still available to server
+   administrators and usually subject to eavesdropping, tampering and
+   forgery when transmitted through SMTP or NNTP.  TLS is no substitute
+   for an end-to-end message security mechanism using MIME security
+   multiparts [MIME-SEC].
+
+   A man-in-the-middle attacker can remove STARTTLS from the capability
+   list or generate a failure response to the STARTTLS command.  In
+   order to detect such an attack, clients SHOULD warn the user when
+   session privacy is not active and/or be configurable to refuse to
+   proceed without an acceptable level of security.
+
+   A man-in-the-middle attacker can always cause a down-negotiation to
+   the weakest authentication mechanism or cipher suite available.  For
+   this reason, implementations SHOULD be configurable to refuse weak
+   mechanisms or cipher suites.
+
+   Any protocol interactions prior to the TLS handshake are performed in
+   the clear and can be modified by a man-in-the-middle attacker.  For
+   this reason, clients MUST discard cached information about server
+   capabilities advertised prior to the start of the TLS handshake.
+
+   Clients are encouraged to clearly indicate when the level of
+   encryption active is known to be vulnerable to attack using modern
+   hardware (such as encryption keys with 56 bits of entropy or less).
+
+   The LOGINDISABLED IMAP capability (discussed in section 3.2) only
+   reduces the potential for passive attacks, it provides no protection
+   against active attacks.  The responsibility remains with the client
+   to avoid sending a password over a vulnerable channel.
+
+   The PLAIN mechanism relies on the TLS encryption layer for security.
+   When used without TLS, it is vulnerable to a common network
+   eavesdropping attack.  Therefore PLAIN MUST NOT be advertised or used
+   unless a suitable TLS encryption layer is active or backwards
+   compatibility dictates otherwise.
+
+   When the PLAIN mechanism is used, the server gains the ability to
+   impersonate the user to all services with the same password
+   regardless of any encryption provided by TLS or other network privacy
+   mechanisms.  While many other authentication mechanisms have similar
+   weaknesses, stronger SASL mechanisms such as Kerberos address this
+   issue.  Clients are encouraged to have an operational mode where all
+   mechanisms which are likely to reveal the user's password to the
+   server are disabled.
+
+
+
+Newman                      Standards Track                    [Page 11]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   The security considerations for TLS apply to STARTTLS and the
+   security considerations for SASL apply to the PLAIN mechanism.
+   Additional security requirements are discussed in section 2.
+
+10. References
+
+   [ABNF]     Crocker, D. and P. Overell, "Augmented BNF for Syntax
+              Specifications: ABNF", RFC 2234, November 1997.
+
+   [ACAP]     Newman, C. and J. Myers, "ACAP -- Application
+              Configuration Access Protocol", RFC 2244, November 1997.
+
+   [AUTH]     Haller, N. and R. Atkinson, "On Internet Authentication",
+              RFC 1704, October 1994.
+
+   [CRAM-MD5] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+              AUTHorize Extension for Simple Challenge/Response", RFC
+              2195, September 1997.
+
+   [IMAP]     Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [MIME-SEC] Galvin, J., Murphy, S., Crocker, S. and N. Freed,
+              "Security Multiparts for MIME: Multipart/Signed and
+              Multipart/Encrypted", RFC 1847, October 1995.
+
+   [POP3]     Myers, J. and M. Rose, "Post Office Protocol - Version 3",
+              STD 53, RFC 1939, May 1996.
+
+   [POP3EXT]  Gellens, R., Newman, C. and L. Lundblade, "POP3 Extension
+              Mechanism", RFC 2449, November 1998.
+
+   [POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734,
+              December 1994.
+
+   [SASL]     Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997.
+
+   [SMTPTLS]  Hoffman, P., "SMTP Service Extension for Secure SMTP over
+              TLS", RFC 2487, January 1999.
+
+   [TLS]      Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+              RFC 2246, January 1999.
+
+
+
+
+
+Newman                      Standards Track                    [Page 12]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   [UTF-8]    Yergeau, F., "UTF-8, a transformation format of ISO
+              10646", RFC 2279, January 1998.
+
+
+11. Author's Address
+
+   Chris Newman
+   Innosoft International, Inc.
+   1050 Lakes Drive
+   West Covina, CA 91790 USA
+
+   EMail: chris.newman@innosoft.com
+
+
+A. Appendix -- Compliance Checklist
+
+   An implementation is not compliant if it fails to satisfy one or more
+   of the MUST requirements for the protocols it implements.  An
+   implementation that satisfies all the MUST and all the SHOULD
+   requirements for its protocols is said to be "unconditionally
+   compliant"; one that satisfies all the MUST requirements but not all
+   the SHOULD requirements for its protocols is said to be
+   "conditionally compliant".
+
+   Rules                                                 Section
+   -----                                                 -------
+   Mandatory-to-implement Cipher Suite                      2.1
+   SHOULD have mode where encryption required               2.2
+   server SHOULD have mode where TLS not required           2.2
+   MUST be configurable to refuse all clear-text login
+     commands or mechanisms                                 2.3
+   server SHOULD be configurable to refuse clear-text
+     login commands on entire server and on per-user basis  2.3
+   client MUST check server identity                        2.4
+   client MUST use hostname used to open connection         2.4
+   client MUST NOT use hostname from insecure remote lookup 2.4
+   client SHOULD support subjectAltName of dNSName type     2.4
+   client SHOULD ask for confirmation or terminate on fail  2.4
+   MUST check result of STARTTLS for acceptable privacy     2.5
+   client MUST NOT issue commands after STARTTLS
+      until server response and negotiation done        3.1,4,5.1
+   client MUST discard cached information             3.1,4,5.1,9
+   client SHOULD re-issue CAPABILITY/CAPA command       3.1,4
+   IMAP server with STARTTLS MUST implement LOGINDISABLED   3.2
+   IMAP client MUST NOT issue LOGIN if LOGINDISABLED        3.2
+   POP server MUST implement POP3 extensions                4
+   ACAP server MUST re-issue ACAP greeting                  5.1
+
+
+
+
+Newman                      Standards Track                    [Page 13]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+   client SHOULD warn when session privacy not active and/or
+     refuse to proceed without acceptable security level    9
+   SHOULD be configurable to refuse weak mechanisms or
+     cipher suites                                          9
+
+   The PLAIN mechanism is an optional part of this specification.
+   However if it is implemented the following rules apply:
+
+   Rules                                                 Section
+   -----                                                 -------
+   MUST NOT use PLAIN unless strong encryption active
+     or backwards compatibility dictates otherwise         6,9
+   MUST use UTF-8 encoding for characters in PLAIN          6
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                    [Page 14]
+\f
+RFC 2595           Using TLS with IMAP, POP3 and ACAP          June 1999
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (1999).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Newman                      Standards Track                    [Page 15]
+\f
diff --git a/doc/rfc2831.txt b/doc/rfc2831.txt
new file mode 100644 (file)
index 0000000..c1a54c4
--- /dev/null
@@ -0,0 +1,1515 @@
+
+
+
+
+
+
+Network Working Group                                           P. Leach
+Request for Comments: 2831                                     Microsoft
+Category: Standards Track                                      C. Newman
+                                                                Innosoft
+                                                                May 2000
+
+
+            Using Digest Authentication as a SASL Mechanism
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   This specification defines how HTTP Digest Authentication [Digest]
+   can be used as a SASL [RFC 2222] mechanism for any protocol that has
+   a SASL profile. It is intended both as an improvement over CRAM-MD5
+   [RFC 2195] and as a convenient way to support a single authentication
+   mechanism for web, mail, LDAP, and other protocols.
+
+Table of Contents
+
+   1 INTRODUCTION.....................................................2
+    1.1 CONVENTIONS AND NOTATION......................................2
+    1.2 REQUIREMENTS..................................................3
+   2 AUTHENTICATION...................................................3
+    2.1 INITIAL AUTHENTICATION........................................3
+     2.1.1 Step One...................................................3
+     2.1.2 Step Two...................................................6
+     2.1.3 Step Three................................................12
+    2.2 SUBSEQUENT AUTHENTICATION....................................12
+     2.2.1 Step one..................................................13
+     2.2.2 Step Two..................................................13
+    2.3 INTEGRITY PROTECTION.........................................13
+    2.4 CONFIDENTIALITY PROTECTION...................................14
+   3 SECURITY CONSIDERATIONS.........................................15
+    3.1 AUTHENTICATION OF CLIENTS USING DIGEST AUTHENTICATION........15
+    3.2 COMPARISON OF DIGEST WITH PLAINTEXT PASSWORDS................16
+    3.3 REPLAY ATTACKS...............................................16
+
+
+
+Leach & Newman              Standards Track                     [Page 1]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+    3.4 ONLINE DICTIONARY ATTACKS....................................16
+    3.5 OFFLINE DICTIONARY ATTACKS...................................16
+    3.6 MAN IN THE MIDDLE............................................17
+    3.7 CHOSEN PLAINTEXT ATTACKS.....................................17
+    3.8 SPOOFING BY COUNTERFEIT SERVERS..............................17
+    3.9 STORING PASSWORDS............................................17
+    3.10 MULTIPLE REALMS.............................................18
+    3.11 SUMMARY.....................................................18
+   4 EXAMPLE.........................................................18
+   5 REFERENCES......................................................20
+   6 AUTHORS' ADDRESSES..............................................21
+   7 ABNF............................................................21
+    7.1 AUGMENTED BNF................................................21
+    7.2 BASIC RULES..................................................23
+   8 SAMPLE CODE.....................................................25
+   9 FULL COPYRIGHT STATEMENT........................................27
+
+1  Introduction
+
+   This specification describes the use of HTTP Digest Access
+   Authentication as a SASL mechanism. The authentication type
+   associated with the Digest SASL mechanism is "DIGEST-MD5".
+
+   This specification is intended to be upward compatible with the
+   "md5-sess" algorithm of HTTP/1.1 Digest Access Authentication
+   specified in [Digest]. The only difference in the "md5-sess"
+   algorithm is that some directives not needed in a SASL mechanism have
+   had their values defaulted.
+
+   There is one new feature for use as a SASL mechanism: integrity
+   protection on application protocol messages after an authentication
+   exchange.
+
+   Also, compared to CRAM-MD5, DIGEST-MD5 prevents chosen plaintext
+   attacks, and permits the use of third party authentication servers,
+   mutual authentication, and optimized reauthentication if a client has
+   recently authenticated to a server.
+
+1.1  Conventions and Notation
+
+   This specification uses the same ABNF notation and lexical
+   conventions as HTTP/1.1 specification; see appendix A.
+
+   Let { a, b, ... } be the concatenation of the octet strings a, b, ...
+
+   Let H(s) be the 16 octet MD5 hash [RFC 1321] of the octet string s.
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 2]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Let KD(k, s) be H({k, ":", s}), i.e., the 16 octet hash of the string
+   k, a colon and the string s.
+
+   Let HEX(n) be the representation of the 16 octet MD5 hash n as a
+   string of 32 hex digits (with alphabetic characters always in lower
+   case, since MD5 is case sensitive).
+
+   Let HMAC(k, s) be the 16 octet HMAC-MD5 [RFC 2104] of the octet
+   string s using the octet string k as a key.
+
+   The value of a quoted string constant as an octet string does not
+   include any terminating null character.
+
+1.2  Requirements
+
+   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+   document are to be interpreted as described in RFC 2119 [RFC 2119].
+
+   An implementation is not compliant if it fails to satisfy one or more
+   of the MUST level requirements for the protocols it implements. An
+   implementation that satisfies all the MUST level and all the SHOULD
+   level requirements for its protocols is said to be "unconditionally
+   compliant"; one that satisfies all the MUST level requirements but
+   not all the SHOULD level requirements for its protocols is said to be
+   "conditionally compliant."
+
+2  Authentication
+
+   The following sections describe how to use Digest as a SASL
+   authentication mechanism.
+
+2.1  Initial Authentication
+
+   If the client has not recently authenticated to the server, then it
+   must perform "initial authentication", as defined in this section. If
+   it has recently authenticated, then a more efficient form is
+   available, defined in the next section.
+
+2.1.1  Step One
+
+   The server starts by sending a challenge. The data encoded in the
+   challenge contains a string formatted according to the rules for a
+   "digest-challenge" defined as follows:
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 3]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   digest-challenge  =
+         1#( realm | nonce | qop-options | stale | maxbuf | charset
+               algorithm | cipher-opts | auth-param )
+
+        realm             = "realm" "=" <"> realm-value <">
+        realm-value       = qdstr-val
+        nonce             = "nonce" "=" <"> nonce-value <">
+        nonce-value       = qdstr-val
+        qop-options       = "qop" "=" <"> qop-list <">
+        qop-list          = 1#qop-value
+        qop-value         = "auth" | "auth-int" | "auth-conf" |
+                             token
+        stale             = "stale" "=" "true"
+        maxbuf            = "maxbuf" "=" maxbuf-value
+        maxbuf-value      = 1*DIGIT
+        charset           = "charset" "=" "utf-8"
+        algorithm         = "algorithm" "=" "md5-sess"
+        cipher-opts       = "cipher" "=" <"> 1#cipher-value <">
+        cipher-value      = "3des" | "des" | "rc4-40" | "rc4" |
+                            "rc4-56" | token
+        auth-param        = token "=" ( token | quoted-string )
+
+   The meanings of the values of the directives used above are as
+   follows:
+
+   realm
+      Mechanistically, a string which can enable users to know which
+      username and password to use, in case they might have different
+      ones for different servers. Conceptually, it is the name of a
+      collection of accounts that might include the user's account. This
+      string should contain at least the name of the host performing the
+      authentication and might additionally indicate the collection of
+      users who might have access. An example might be
+      "registered_users@gotham.news.example.com".  This directive is
+      optional; if not present, the client SHOULD solicit it from the
+      user or be able to compute a default; a plausible default might be
+      the realm supplied by the user when they logged in to the client
+      system. Multiple realm directives are allowed, in which case the
+      user or client must choose one as the realm for which to supply to
+      username and password.
+
+   nonce
+      A server-specified data string which MUST be different each time a
+      digest-challenge is sent as part of initial authentication.  It is
+      recommended that this string be base64 or hexadecimal data. Note
+      that since the string is passed as a quoted string, the
+      double-quote character is not allowed unless escaped (see section
+      7.2). The contents of the nonce are implementation dependent. The
+
+
+
+Leach & Newman              Standards Track                     [Page 4]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. The nonce
+      is opaque to the client. This directive is required and MUST
+      appear exactly once; if not present, or if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   qop-options
+      A quoted string of one or more tokens indicating the "quality of
+      protection" values supported by the server.  The value "auth"
+      indicates authentication; the value "auth-int" indicates
+      authentication with integrity protection; the value "auth-conf"
+      indicates authentication with integrity protection and encryption.
+      This directive is optional; if not present it defaults to "auth".
+      The client MUST ignore unrecognized options; if the client
+      recognizes no option, it should abort the authentication exchange.
+
+   stale
+      The "stale" directive is not used in initial authentication. See
+      the next section for its use in subsequent authentications. This
+      directive may appear at most once; if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   maxbuf
+      A number indicating the size of the largest buffer the server is
+      able to receive when using "auth-int" or "auth-conf". If this
+      directive is missing, the default value is 65536. This directive
+      may appear at most once; if multiple instances are present, the
+      client should abort the authentication exchange.
+
+   charset
+      This directive, if present, specifies that the server supports
+      UTF-8 encoding for the username and password. If not present, the
+      username and password must be encoded in ISO 8859-1 (of which
+      US-ASCII is a subset). The directive is needed for backwards
+      compatibility with HTTP Digest, which only supports ISO 8859-1.
+      This directive may appear at most once; if multiple instances are
+      present, the client should abort the authentication exchange.
+
+   algorithm
+      This directive is required for backwards compatibility with HTTP
+      Digest., which supports other algorithms. . This directive is
+      required and MUST appear exactly once; if not present, or if
+      multiple instances are present, the client should abort the
+      authentication exchange.
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 5]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   cipher-opts
+      A list of ciphers that the server supports. This directive must be
+      present exactly once if "auth-conf" is offered in the
+      "qop-options" directive, in which case the "3des" and "des" modes
+      are mandatory-to-implement. The client MUST ignore unrecognized
+      options; if the client recognizes no option, it should abort the
+      authentication exchange.
+
+      des
+         the Data Encryption Standard (DES) cipher [FIPS] in cipher
+         block chaining (CBC) mode with a 56 bit key.
+
+      3des
+         the "triple DES" cipher in CBC mode with EDE with the same key
+         for each E stage (aka "two keys mode") for a total key length
+         of 112 bits.
+
+      rc4, rc4-40, rc4-56
+         the RC4 cipher with a 128 bit, 40 bit, and 56 bit key,
+         respectively.
+
+   auth-param This construct allows for future extensions; it may appear
+      more than once. The client MUST ignore any unrecognized
+      directives.
+
+   For use as a SASL mechanism, note that the following changes are made
+   to "digest-challenge" from HTTP: the following Digest options (called
+   "directives" in HTTP terminology) are unused (i.e., MUST NOT be sent,
+   and MUST be ignored if received):
+
+    opaque
+    domain
+
+   The size of a digest-challenge MUST be less than 2048 bytes.
+
+2.1.2  Step Two
+
+   The client makes note of the "digest-challenge" and then responds
+   with a string formatted and computed according to the rules for a
+   "digest-response" defined as follows:
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 6]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   digest-response  = 1#( username | realm | nonce | cnonce |
+                          nonce-count | qop | digest-uri | response |
+                          maxbuf | charset | cipher | authzid |
+                          auth-param )
+
+       username         = "username" "=" <"> username-value <">
+       username-value   = qdstr-val
+       cnonce           = "cnonce" "=" <"> cnonce-value <">
+       cnonce-value     = qdstr-val
+       nonce-count      = "nc" "=" nc-value
+       nc-value         = 8LHEX
+       qop              = "qop" "=" qop-value
+       digest-uri       = "digest-uri" "=" <"> digest-uri-value <">
+       digest-uri-value  = serv-type "/" host [ "/" serv-name ]
+       serv-type        = 1*ALPHA
+       host             = 1*( ALPHA | DIGIT | "-" | "." )
+       serv-name        = host
+       response         = "response" "=" response-value
+       response-value   = 32LHEX
+       LHEX             = "0" | "1" | "2" | "3" |
+                          "4" | "5" | "6" | "7" |
+                          "8" | "9" | "a" | "b" |
+                          "c" | "d" | "e" | "f"
+       cipher           = "cipher" "=" cipher-value
+       authzid          = "authzid" "=" <"> authzid-value <">
+       authzid-value    = qdstr-val
+
+
+   username
+      The user's name in the specified realm, encoded according to the
+      value of the "charset" directive. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+   realm
+      The realm containing the user's account. This directive is
+      required if the server provided any realms in the
+      "digest-challenge", in which case it may appear exactly once and
+      its value SHOULD be one of those realms. If the directive is
+      missing, "realm-value" will set to the empty string when computing
+      A1 (see below for details).
+
+   nonce
+      The server-specified data string received in the preceding
+      digest-challenge. This directive is required and MUST be present
+      exactly once; otherwise, authentication fails.
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 7]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   cnonce
+      A client-specified data string which MUST be different each time a
+      digest-response is sent as part of initial authentication. The
+      cnonce-value is an opaque quoted string value provided by the
+      client and used by both client and server to avoid chosen
+      plaintext attacks, and to provide mutual authentication. The
+      security of the implementation depends on a good choice. It is
+      RECOMMENDED that it contain at least 64 bits of entropy. This
+      directive is required and MUST be present exactly once; otherwise,
+      authentication fails.
+
+   nonce-count
+      The nc-value is the hexadecimal count of the number of requests
+      (including the current request) that the client has sent with the
+      nonce value in this request.  For example, in the first request
+      sent in response to a given nonce value, the client sends
+      "nc=00000001". The purpose of this directive is to allow the
+      server to detect request replays by maintaining its own copy of
+      this count - if the same nc-value is seen twice, then the request
+      is a replay.   See the description below of the construction of
+      the response value. This directive may appear at most once; if
+      multiple instances are present, the client should abort the
+      authentication exchange.
+
+   qop
+      Indicates what "quality of protection" the client accepted. If
+      present, it may appear exactly once and  its value MUST be one of
+      the alternatives in qop-options. If not present, it defaults to
+      "auth". These values affect the computation of the response. Note
+      that this is a single token, not a quoted list of alternatives.
+
+   serv-type
+      Indicates the type of service, such as "www" for web service,
+      "ftp" for FTP service, "smtp" for mail delivery service, etc. The
+      service name as defined in the SASL profile for the protocol see
+      section 4 of [RFC 2222], registered in the IANA registry of
+      "service" elements for the GSSAPI host-based service name form
+      [RFC 2078].
+
+   host
+      The DNS host name or IP address for the service requested.  The
+      DNS host name must be the fully-qualified canonical name of the
+      host. The DNS host name is the preferred form; see notes on server
+      processing of the digest-uri.
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                     [Page 8]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   serv-name
+      Indicates the name of the service if it is replicated. The service
+      is considered to be replicated if the client's service-location
+      process involves resolution using standard DNS lookup operations,
+      and if these operations involve DNS records (such as SRV, or MX)
+      which resolve one DNS name into a set of other DNS names. In this
+      case, the initial name used by the client is the "serv-name", and
+      the final name is the "host" component. For example, the incoming
+      mail service for "example.com" may be replicated through the use
+      of MX records stored in the DNS, one of which points at an SMTP
+      server called "mail3.example.com"; it's "serv-name" would be
+      "example.com", it's "host" would be "mail3.example.com". If the
+      service is not replicated, or the serv-name is identical to the
+      host, then the serv-name component MUST be omitted.
+
+   digest-uri
+      Indicates the principal name of the service with which the client
+      wishes to connect, formed from the serv-type, host, and serv-name.
+      For example, the FTP service on "ftp.example.com" would have a
+      "digest-uri" value of "ftp/ftp.example.com"; the SMTP server from
+      the example above would have a "digest-uri" value of
+      "smtp/mail3.example.com/example.com".
+
+   Servers SHOULD check that the supplied value is correct. This will
+   detect accidental connection to the incorrect server. It is also so
+   that clients will be trained to provide values that will work with
+   implementations that use a shared back-end authentication service
+   that can provide server authentication.
+
+   The serv-type component should match the service being offered. The
+   host component should match one of the host names of the host on
+   which the service is running, or it's IP address. Servers SHOULD NOT
+   normally support the IP address form, because server authentication
+   by IP address is not very useful; they should only do so if the DNS
+   is unavailable or unreliable. The serv-name component should match
+   one of the service's configured service names.
+
+   This directive may appear at most once; if multiple instances are
+   present, the client should abort the authentication exchange.
+
+   Note: In the HTTP use of Digest authentication, the digest-uri is the
+   URI (usually a URL) of the resource requested -- hence the name of
+   the directive.
+
+   response
+      A string of 32 hex digits computed as defined below, which proves
+      that the user knows a password. This directive is required and
+      MUST be present exactly once; otherwise, authentication fails.
+
+
+
+Leach & Newman              Standards Track                     [Page 9]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   maxbuf
+      A number indicating the size of the largest buffer the client is
+      able to receive. If this directive is missing, the default value
+      is 65536. This directive may appear at most once; if multiple
+      instances are present, the server should abort the authentication
+      exchange.
+
+   charset
+      This directive, if present, specifies that the client has used
+      UTF-8 encoding for the username and password. If not present, the
+      username and password must be encoded in ISO 8859-1 (of which
+      US-ASCII is a subset). The client should send this directive only
+      if the server has indicated it supports UTF-8. The directive is
+      needed for backwards compatibility with HTTP Digest, which only
+      supports ISO 8859-1.
+
+   LHEX
+      32 hex digits, where the alphabetic characters MUST be lower case,
+      because MD5 is not case insensitive.
+
+   cipher
+      The cipher chosen by the client. This directive MUST appear
+      exactly once if "auth-conf" is negotiated; if required and not
+      present, authentication fails.
+
+   authzid
+      The "authorization ID" as per RFC 2222, encoded in UTF-8. This
+      directive is optional. If present, and the authenticating user has
+      sufficient privilege, and the server supports it, then after
+      authentication the server will use this identity for making all
+      accesses and access checks. If the client specifies it, and the
+      server does not support it, then the response-value will be
+      incorrect, and authentication will fail.
+
+   The size of a digest-response MUST be less than 4096 bytes.
+
+2.1.2.1   Response-value
+
+   The definition of "response-value" above indicates the encoding for
+   its value -- 32 lower case hex characters. The following definitions
+   show how the value is computed.
+
+   Although qop-value and components of digest-uri-value may be
+   case-insensitive, the case which the client supplies in step two is
+   preserved for the purpose of computing and verifying the
+   response-value.
+
+      response-value  =
+
+
+
+Leach & Newman              Standards Track                    [Page 10]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+         HEX( KD ( HEX(H(A1)),
+                 { nonce-value, ":" nc-value, ":",
+                   cnonce-value, ":", qop-value, ":", HEX(H(A2)) }))
+
+   If authzid is specified, then A1 is
+
+
+      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
+           ":", nonce-value, ":", cnonce-value, ":", authzid-value }
+
+   If authzid is not specified, then A1 is
+
+
+      A1 = { H( { username-value, ":", realm-value, ":", passwd } ),
+           ":", nonce-value, ":", cnonce-value }
+
+   where
+
+         passwd   = *OCTET
+
+   The "username-value", "realm-value" and "passwd" are encoded
+   according to the value of the "charset" directive. If "charset=UTF-8"
+   is present, and all the characters of either "username-value" or
+   "passwd" are in the ISO 8859-1 character set, then it must be
+   converted to ISO 8859-1 before being hashed. This is so that
+   authentication databases that store the hashed username, realm and
+   password (which is common) can be shared compatibly with HTTP, which
+   specifies ISO 8859-1. A sample implementation of this conversion is
+   in section 8.
+
+   If the "qop" directive's value is "auth", then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value }
+
+   If the "qop" value is "auth-int" or "auth-conf" then A2 is:
+
+      A2       = { "AUTHENTICATE:", digest-uri-value,
+               ":00000000000000000000000000000000" }
+
+   Note that "AUTHENTICATE:" must be in upper case, and the second
+   string constant is a string with a colon followed by 32 zeros.
+
+   These apparently strange values of A2 are for compatibility with
+   HTTP; they were arrived at by setting "Method" to "AUTHENTICATE" and
+   the hash of the entity body to zero in the HTTP digest calculation of
+   A2.
+
+   Also, in the HTTP usage of Digest, several directives in the
+
+
+
+Leach & Newman              Standards Track                    [Page 11]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   "digest-challenge" sent by the server have to be returned by the
+   client in the "digest-response". These are:
+
+    opaque
+    algorithm
+
+   These directives are not needed when Digest is used as a SASL
+   mechanism (i.e., MUST NOT be sent, and MUST be ignored if received).
+
+2.1.3  Step Three
+
+   The server receives and validates the "digest-response". The server
+   checks that the nonce-count is "00000001". If it supports subsequent
+   authentication (see section 2.2), it saves the value of the nonce and
+   the nonce-count. It sends a message formatted as follows:
+
+    response-auth = "rspauth" "=" response-value
+
+   where response-value is calculated as above, using the values sent in
+   step two, except that if qop is "auth", then A2 is
+
+       A2 = { ":", digest-uri-value }
+
+   And if qop is "auth-int" or "auth-conf" then A2 is
+
+       A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
+
+   Compared to its use in HTTP, the following Digest directives in the
+   "digest-response" are unused:
+
+       nextnonce
+       qop
+       cnonce
+       nonce-count
+
+2.2  Subsequent Authentication
+
+   If the client has previously authenticated to the server, and
+   remembers the values of username, realm, nonce, nonce-count, cnonce,
+   and qop that it used in that authentication, and the SASL profile for
+   a protocol permits an initial client response, then it MAY perform
+   "subsequent authentication", as defined in this section.
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 12]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+2.2.1  Step one
+
+   The client uses the values from the previous authentication and sends
+   an initial response with a string formatted and computed according to
+   the rules for a "digest-response", as defined above, but with a
+   nonce-count one greater than used in the last "digest-response".
+
+2.2.2  Step Two
+
+   The server receives the "digest-response". If the server does not
+   support subsequent authentication, then it sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication. If the server has no saved nonce and nonce-count from
+   a previous authentication, then it sends a "digest-challenge", and
+   authentication proceeds as in initial authentication. Otherwise, the
+   server validates the "digest-response", checks that the nonce-count
+   is one greater than that used in the previous authentication using
+   that nonce, and saves the new value of nonce-count.
+
+   If the response is invalid, then the server sends a
+   "digest-challenge", and authentication proceeds as in initial
+   authentication (and should be configurable to log an authentication
+   failure in some sort of security audit log, since the failure may be
+   a symptom of an attack). The nonce-count MUST NOT be incremented in
+   this case: to do so would allow a denial of service attack by sending
+   an out-of-order nonce-count.
+
+   If the response is valid, the server MAY choose to deem that
+   authentication has succeeded. However, if it has been too long since
+   the previous authentication, or for any other reason, the server MAY
+   send a new "digest-challenge" with a new value for nonce. The
+   challenge MAY contain a "stale" directive with value "true", which
+   says that the client may respond to the challenge using the password
+   it used in the previous response; otherwise, the client must solicit
+   the password anew from the user. This permits the server to make sure
+   that the user has presented their password recently. (The directive
+   name refers to the previous nonce being stale, not to the last use of
+   the password.) Except for the handling of "stale", after sending the
+   "digest-challenge" authentication proceeds as in the case of initial
+   authentication.
+
+2.3   Integrity Protection
+
+   If the server offered "qop=auth-int" and the client responded
+   "qop=auth-int", then subsequent messages, up to but not including the
+   next subsequent authentication, between the client and the server
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 13]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   MUST be integrity protected. Using as a base session key the value of
+   H(A1) as defined above the client and server calculate a pair of
+   message integrity keys as follows.
+
+   The key for integrity protecting messages from client to server is:
+
+   Kic = MD5({H(A1),
+   "Digest session key to client-to-server signing key magic constant"})
+
+   The key for integrity protecting messages from server to client is:
+
+   Kis = MD5({H(A1),
+   "Digest session key to server-to-client signing key magic constant"})
+
+   where MD5 is as specified in [RFC 1321]. If message integrity is
+   negotiated, a MAC block for each message is appended to the message.
+   The MAC block is 16 bytes: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. The message type is to allow for future extensions such as
+   rekeying.
+
+   MAC(Ki, SeqNum, msg) = (HMAC(Ki, {SeqNum, msg})[0..9], 0x0001,
+   SeqNum)
+
+   where Ki is Kic for messages sent by the client and Kis for those
+   sent by the server. The sequence number is initialized to zero, and
+   incremented by one for each message sent.
+
+   Upon receipt, MAC(Ki, SeqNum, msg) is computed and compared with the
+   received value; the message is discarded if they differ.
+
+2.4   Confidentiality Protection
+
+   If the server sent a "cipher-opts" directive and the client responded
+   with a "cipher" directive, then subsequent messages between the
+   client and the server MUST be confidentiality protected. Using as a
+   base session key the value of H(A1) as defined above the client and
+   server calculate a pair of message integrity keys as follows.
+
+   The key for confidentiality protecting messages from client to server
+   is:
+
+   Kcc = MD5({H(A1)[0..n],
+   "Digest H(A1) to client-to-server sealing key magic constant"})
+
+   The key for confidentiality protecting messages from server to client
+   is:
+
+
+
+Leach & Newman              Standards Track                    [Page 14]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Kcs = MD5({H(A1)[0..n],
+   "Digest H(A1) to server-to-client sealing key magic constant"})
+
+   where MD5 is as specified in [RFC 1321]. For cipher "rc4-40" n is 5;
+   for "rc4-56" n is 7; for the rest n is 16. The key for the "rc-*"
+   ciphers is all 16 bytes of Kcc or Kcs; the key for "des" is the first
+   7 bytes; the key for "3des" is the first 14 bytes. The IV for "des"
+   and "3des" is the last 8 bytes of Kcc or Kcs.
+
+   If message confidentiality is negotiated, each message is encrypted
+   with the chosen cipher and a MAC block is appended to the message.
+
+   The MAC block is a variable length padding prefix followed by 16
+   bytes formatted as follows: the first 10 bytes of the HMAC-MD5 [RFC
+   2104] of the message, a 2-byte message type number in network byte
+   order with value 1, and the 4-byte sequence number in network byte
+   order. If the blocksize of the chosen cipher is not 1 byte, the
+   padding prefix is one or more octets each containing the number of
+   padding bytes, such that total length of the encrypted part of the
+   message is a multiple of the blocksize. The padding and first 10
+   bytes of the MAC block are encrypted along with the message.
+
+   SEAL(Ki, Kc, SeqNum, msg) =
+         {CIPHER(Kc, {msg, pad, HMAC(Ki, {SeqNum, msg})[0..9])}), 0x0001,
+          SeqNum}
+
+   where CIPHER is the chosen cipher, Ki and Kc are Kic and Kcc for
+   messages sent by the client and Kis and Kcs for those sent by the
+   server. The sequence number is initialized to zero, and incremented
+   by one for each message sent.
+
+   Upon receipt, the message is decrypted, HMAC(Ki, {SeqNum, msg}) is
+   computed and compared with the received value; the message is
+   discarded if they differ.
+
+3  Security Considerations
+
+3.1   Authentication of Clients using Digest Authentication
+
+   Digest Authentication does not provide a strong authentication
+   mechanism, when compared to public key based mechanisms, for example.
+   However, since it prevents chosen plaintext attacks, it is stronger
+   than (e.g.) CRAM-MD5, which has been proposed for use with LDAP [10],
+   POP and IMAP (see RFC 2195 [9]).   It is intended to replace the much
+   weaker and even more dangerous use of plaintext passwords; however,
+   since it is still a password based mechanism it avoids some of the
+   potential deployabilty issues with public-key, OTP or similar
+   mechanisms.
+
+
+
+Leach & Newman              Standards Track                    [Page 15]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   Digest Authentication offers no confidentiality protection beyond
+   protecting the actual password. All of the rest of the challenge and
+   response are available to an eavesdropper, including the user's name
+   and authentication realm.
+
+3.2   Comparison of Digest with Plaintext Passwords
+
+   The greatest threat to the type of transactions for which these
+   protocols are used is network snooping. This kind of transaction
+   might involve, for example, online access to a mail service whose use
+   is restricted to paying subscribers. With plaintext password
+   authentication an eavesdropper can obtain the password of the user.
+   This not only permits him to access anything in the database, but,
+   often worse, will permit access to anything else the user protects
+   with the same password.
+
+3.3   Replay Attacks
+
+   Replay attacks are defeated if the client or the server chooses a
+   fresh nonce for each authentication, as this specification requires.
+
+3.4  Online dictionary attacks
+
+   If the attacker can eavesdrop, then it can test any overheard
+   nonce/response pairs against a (potentially very large) list of
+   common words. Such a list is usually much smaller than the total
+   number of possible passwords. The cost of computing the response for
+   each password on the list is paid once for each challenge.
+
+   The server can mitigate this attack by not allowing users to select
+   passwords that are in a dictionary.
+
+3.5  Offline dictionary attacks
+
+   If the attacker can choose the challenge, then it can precompute the
+   possible responses to that challenge for a list of common words. Such
+   a list is usually much smaller than the total number of possible
+   passwords. The cost of computing the response for each password on
+   the list is paid just once.
+
+   Offline dictionary attacks are defeated if the client chooses a fresh
+   nonce for each authentication, as this specification requires.
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 16]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+3.6  Man in the Middle
+
+   Digest authentication is vulnerable to "man in the middle" (MITM)
+   attacks. Clearly, a MITM would present all the problems of
+   eavesdropping. But it also offers some additional opportunities to
+   the attacker.
+
+   A possible man-in-the-middle attack would be to substitute a weaker
+   qop scheme for the one(s) sent by the server; the server will not be
+   able to detect this attack. For this reason, the client should always
+   use the strongest scheme that it understands from the choices
+   offered, and should never choose a scheme that does not meet its
+   minimum requirements.
+
+3.7  Chosen plaintext attacks
+
+   A chosen plaintext attack is where a MITM or a malicious server can
+   arbitrarily choose the challenge that the client will use to compute
+   the response. The ability to choose the challenge is known to make
+   cryptanalysis much easier [8].
+
+   However, Digest does not permit the attack to choose the challenge as
+   long as the client chooses a fresh nonce for each authentication, as
+   this specification requires.
+
+3.8  Spoofing by Counterfeit Servers
+
+   If a user can be led to believe that she is connecting to a host
+   containing information protected by a password she knows, when in
+   fact she is connecting to a hostile server, then the hostile server
+   can obtain challenge/response pairs where it was able to partly
+   choose the challenge. There is no known way that this can be
+   exploited.
+
+3.9  Storing passwords
+
+   Digest authentication requires that the authenticating agent (usually
+   the server) store some data derived from the user's name and password
+   in a "password file" associated with a given realm. Normally this
+   might contain pairs consisting of username and H({ username-value,
+   ":", realm-value, ":", passwd }), which is adequate to compute H(A1)
+   as described above without directly exposing the user's password.
+
+   The security implications of this are that if this password file is
+   compromised, then an attacker gains immediate access to documents on
+   the server using this realm. Unlike, say a standard UNIX password
+   file, this information need not be decrypted in order to access
+   documents in the server realm associated with this file. On the other
+
+
+
+Leach & Newman              Standards Track                    [Page 17]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   hand, decryption, or more likely a brute force attack, would be
+   necessary to obtain the user's password. This is the reason that the
+   realm is part of the digested data stored in the password file. It
+   means that if one Digest authentication password file is compromised,
+   it does not automatically compromise others with the same username
+   and password (though it does expose them to brute force attack).
+
+   There are two important security consequences of this. First the
+   password file must be protected as if it contained plaintext
+   passwords, because for the purpose of accessing documents in its
+   realm, it effectively does.
+
+   A second consequence of this is that the realm string should be
+   unique among all realms that any single user is likely to use. In
+   particular a realm string should include the name of the host doing
+   the authentication.
+
+3.10  Multiple realms
+
+   Use of multiple realms may mean both that compromise of a the
+   security database for a single realm does not compromise all
+   security, and that there are more things to protect in order to keep
+   the whole system secure.
+
+3.11  Summary
+
+   By modern cryptographic standards Digest Authentication is weak,
+   compared to (say) public key based mechanisms. But for a large range
+   of purposes it is valuable as a replacement for plaintext passwords.
+   Its strength may vary depending on the implementation.
+
+4  Example
+
+   This example shows the use of the Digest SASL mechanism with the
+   IMAP4 AUTHENTICATE command [RFC 2060].
+
+   In this example, "C:" and "S:" represent a line sent by the client or
+   server respectively including a CRLF at the end.  Linebreaks and
+   indentation within a "C:" or "S:" are editorial and not part of the
+   protocol. The password in this example was "secret".  Note that the
+   base64 encoding of the challenges and responses is part of the IMAP4
+   AUTHENTICATE command, not part of the Digest specification itself.
+
+    S: * OK elwood.innosoft.com PMDF IMAP4rev1 V6.0-9
+    C: c CAPABILITY
+    S: * CAPABILITY IMAP4 IMAP4rev1 ACL LITERAL+ NAMESPACE QUOTA
+                UIDPLUS AUTH=CRAM-MD5 AUTH=DIGEST-MD5 AUTH=PLAIN
+    S: c OK Completed
+
+
+
+Leach & Newman              Standards Track                    [Page 18]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+    C: a AUTHENTICATE DIGEST-MD5
+    S: + cmVhbG09ImVsd29vZC5pbm5vc29mdC5jb20iLG5vbmNlPSJPQTZNRzl0
+         RVFHbTJoaCIscW9wPSJhdXRoIixhbGdvcml0aG09bWQ1LXNlc3MsY2hh
+         cnNldD11dGYtOA==
+    C: Y2hhcnNldD11dGYtOCx1c2VybmFtZT0iY2hyaXMiLHJlYWxtPSJlbHdvb2
+       QuaW5ub3NvZnQuY29tIixub25jZT0iT0E2TUc5dEVRR20yaGgiLG5jPTAw
+       MDAwMDAxLGNub25jZT0iT0E2TUhYaDZWcVRyUmsiLGRpZ2VzdC11cmk9Im
+       ltYXAvZWx3b29kLmlubm9zb2Z0LmNvbSIscmVzcG9uc2U9ZDM4OGRhZDkw
+       ZDRiYmQ3NjBhMTUyMzIxZjIxNDNhZjcscW9wPWF1dGg=
+    S: + cnNwYXV0aD1lYTQwZjYwMzM1YzQyN2I1NTI3Yjg0ZGJhYmNkZmZmZA==
+    C:
+    S: a OK User logged in
+    ---
+
+    The base64-decoded version of the SASL exchange is:
+
+    S: realm="elwood.innosoft.com",nonce="OA6MG9tEQGm2hh",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA6MG9tEQGm2hh",nc=00000001,cnonce="OA6MHXh6VqTrRk",
+       digest-uri="imap/elwood.innosoft.com",
+       response=d388dad90d4bbd760a152321f2143af7,qop=auth
+    S: rspauth=ea40f60335c427b5527b84dbabcdfffd
+
+    The password in this example was "secret".
+
+   This example shows the use of the Digest SASL mechanism with the
+   ACAP, using the same notational conventions and password as in the
+   previous example. Note that ACAP does not base64 encode and uses
+   fewer round trips that IMAP4.
+
+    S: * ACAP (IMPLEMENTATION "Test ACAP server") (SASL "CRAM-MD5"
+               "DIGEST-MD5" "PLAIN")
+    C: a AUTHENTICATE "DIGEST-MD5"
+    S: + {94}
+    S: realm="elwood.innosoft.com",nonce="OA9BSXrbuRhWay",qop="auth",
+       algorithm=md5-sess,charset=utf-8
+    C: {206}
+    C: charset=utf-8,username="chris",realm="elwood.innosoft.com",
+       nonce="OA9BSXrbuRhWay",nc=00000001,cnonce="OA9BSuZWMSpW8m",
+       digest-uri="acap/elwood.innosoft.com",
+       response=6084c6db3fede7352c551284490fd0fc,qop=auth
+    S: a OK (SASL {40}
+    S: rspauth=2f0b3d7c3c2e486600ef710726aa2eae) "AUTHENTICATE
+    Completed"
+    ---
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 19]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The server uses the values of all the directives, plus knowledge of
+   the users password (or the hash of the user's name, server's realm
+   and the user's password) to verify the computations above. If they
+   check, then the user has authenticated.
+
+5   References
+
+   [Digest]   Franks, J., et al., "HTTP Authentication: Basic and Digest
+              Access Authentication", RFC 2617, June 1999.
+
+   [ISO-8859] ISO-8859. International Standard--Information Processing--
+              8-bit Single-Byte Coded Graphic Character Sets --
+              Part 1: Latin alphabet No. 1, ISO-8859-1:1987.
+              Part 2: Latin alphabet No. 2, ISO-8859-2, 1987.
+              Part 3: Latin alphabet No. 3, ISO-8859-3, 1988.
+              Part 4: Latin alphabet No. 4, ISO-8859-4, 1988.
+              Part 5: Latin/Cyrillic alphabet, ISO-8859-5, 1988.
+              Part 6: Latin/Arabic alphabet, ISO-8859-6, 1987.
+              Part 7: Latin/Greek alphabet, ISO-8859-7, 1987.
+              Part 8: Latin/Hebrew alphabet, ISO-8859-8, 1988.
+              Part 9: Latin alphabet No. 5, ISO-8859-9, 1990.
+
+   [RFC 822]  Crocker, D., "Standard for The Format of ARPA Internet
+              Text Messages," STD 11, RFC 822, August 1982.
+
+   [RFC 1321] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+              April 1992.
+
+   [RFC 2047] Moore, K., "MIME (Multipurpose Internet Mail Extensions)
+              Part Three: Message Header Extensions for Non-ASCII Text",
+              RFC 2047, November 1996.
+
+   [RFC 2052] Gulbrandsen, A. and P. Vixie, "A DNS RR for specifying the
+              location of services (DNS SRV)", RFC 2052, October 1996.
+
+   [RFC 2060] Crispin, M., "Internet Message Access Protocol - Version
+              4rev1", RFC 2060, December 1996.
+
+   [RFC 2104] Krawczyk, H., Bellare, M. and R. Canetti, "HMAC:  Keyed-
+              Hashing for  Message Authentication", RFC 2104, February
+              1997.
+
+   [RFC 2195] Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+              AUTHorize Extension for Simple Challenge/Response", RFC
+              2195, September 1997.
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 20]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate
+              Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+   [RFC 2222] Myers, J., "Simple Authentication and Security Layer
+              (SASL)", RFC 2222, October 1997.
+
+   [USASCII]  US-ASCII. Coded Character Set - 7-Bit American Standard
+              Code for Information Interchange. Standard ANSI X3.4-1986,
+              ANSI, 1986.
+
+6  Authors' Addresses
+
+   Paul Leach
+   Microsoft
+   1 Microsoft Way
+   Redmond, WA  98052
+
+   EMail: paulle@microsoft.com
+
+
+   Chris Newman
+   Innosoft International, Inc.
+   1050 Lakes Drive
+   West Covina, CA 91790 USA
+
+   EMail: chris.newman@innosoft.com
+
+7  ABNF
+
+   What follows is the definition of the notation as is used in the
+   HTTP/1.1 specification (RFC 2616) and the HTTP authentication
+   specification (RFC 2617); it is reproduced here for ease of
+   reference. Since it is intended that a single Digest implementation
+   can support both HTTP and SASL-based protocols, the same notation is
+   used in both to facilitate comparison and prevention of unwanted
+   differences. Since it is cut-and-paste from the HTTP specifications,
+   not all productions may be used in this specification. It is also not
+   quite legal ABNF; again, the errors were copied from the HTTP
+   specifications.
+
+7.1   Augmented BNF
+
+   All of the mechanisms specified in this document are described in
+   both prose and an augmented Backus-Naur Form (BNF) similar to that
+   used by RFC 822 [RFC 822]. Implementers will need to be familiar with
+   the notation in order to understand this specification.
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 21]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The augmented BNF includes the following constructs:
+
+   name = definition
+      The name of a rule is simply the name itself (without any
+      enclosing "<" and ">") and is separated from its definition by the
+      equal "=" character. White space is only significant in that
+      indentation of continuation lines is used to indicate a rule
+      definition that spans more than one line. Certain basic rules are
+      in uppercase, such as SP, LWS, HT, CRLF, DIGIT, ALPHA, etc. Angle
+      brackets are used within definitions whenever their presence will
+      facilitate discerning the use of rule names.
+
+   "literal"
+      Quotation marks surround literal text. Unless stated otherwise,
+      the text is case-insensitive.
+
+   rule1 | rule2
+      Elements separated by a bar ("|") are alternatives, e.g., "yes |
+      no" will accept yes or no.
+
+   (rule1 rule2)
+      Elements enclosed in parentheses are treated as a single element.
+      Thus, "(elem (foo | bar) elem)" allows the token sequences
+      "elem foo elem" and "elem bar elem".
+
+   *rule
+      The character "*" preceding an element indicates repetition. The
+      full form is "<n>*<m>element" indicating at least <n> and at most
+      <m> occurrences of element. Default values are 0 and infinity so
+      that "*(element)" allows any number, including zero; "1*element"
+      requires at least one; and "1*2element" allows one or two.
+
+   [rule]
+      Square brackets enclose optional elements; "[foo bar]" is
+      equivalent to "*1(foo bar)".
+
+   N rule
+      Specific repetition: "<n>(element)" is equivalent to
+      "<n>*<n>(element)"; that is, exactly <n> occurrences of (element).
+      Thus 2DIGIT is a 2-digit number, and 3ALPHA is a string of three
+      alphabetic characters.
+
+   #rule
+      A construct "#" is defined, similar to "*", for defining lists of
+      elements. The full form is "<n>#<m>element" indicating at least
+      <n> and at most <m> elements, each separated by one or more commas
+      (",") and OPTIONAL linear white space (LWS). This makes the usual
+      form of lists very easy; a rule such as
+
+
+
+Leach & Newman              Standards Track                    [Page 22]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+        ( *LWS element *( *LWS "," *LWS element ))
+      can be shown as
+        1#element
+      Wherever this construct is used, null elements are allowed, but do
+      not contribute to the count of elements present. That is,
+      "(element), , (element) " is permitted, but counts as only two
+      elements.  Therefore, where at least one element is required, at
+      least one non-null element MUST be present. Default values are 0
+      and infinity so that "#element" allows any number, including zero;
+      "1#element" requires at least one; and "1#2element" allows one or
+      two.
+
+   ; comment
+      A semi-colon, set off some distance to the right of rule text,
+      starts a comment that continues to the end of line. This is a
+      simple way of including useful notes in parallel with the
+      specifications.
+
+   implied *LWS
+      The grammar described by this specification is word-based. Except
+      where noted otherwise, linear white space (LWS) can be included
+      between any two adjacent words (token or quoted-string), and
+      between adjacent words and separators, without changing the
+      interpretation of a field. At least one delimiter (LWS and/or
+      separators) MUST exist between any two tokens (for the definition
+      of "token" below), since they would otherwise be interpreted as a
+      single token.
+
+7.2   Basic Rules
+
+   The following rules are used throughout this specification to
+   describe basic parsing constructs. The US-ASCII coded character set
+   is defined by ANSI X3.4-1986 [USASCII].
+
+       OCTET          = <any 8-bit sequence of data>
+       CHAR           = <any US-ASCII character (octets 0 - 127)>
+       UPALPHA        = <any US-ASCII uppercase letter "A".."Z">
+       LOALPHA        = <any US-ASCII lowercase letter "a".."z">
+       ALPHA          = UPALPHA | LOALPHA
+       DIGIT          = <any US-ASCII digit "0".."9">
+       CTL            = <any US-ASCII control character
+                        (octets 0 - 31) and DEL (127)>
+       CR             = <US-ASCII CR, carriage return (13)>
+       LF             = <US-ASCII LF, linefeed (10)>
+       SP             = <US-ASCII SP, space (32)>
+       HT             = <US-ASCII HT, horizontal-tab (9)>
+       <">            = <US-ASCII double-quote mark (34)>
+       CRLF           = CR LF
+
+
+
+Leach & Newman              Standards Track                    [Page 23]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+
+   All linear white space, including folding, has the same semantics as
+   SP. A recipient MAY replace any linear white space with a single SP
+   before interpreting the field value or forwarding the message
+   downstream.
+
+       LWS            = [CRLF] 1*( SP | HT )
+
+   The TEXT rule is only used for descriptive field contents and values
+   that are not intended to be interpreted by the message parser. Words
+   of *TEXT MAY contain characters from character sets other than
+   ISO-8859-1 [ISO 8859] only when encoded according to the rules of RFC
+   2047 [RFC 2047].
+
+       TEXT           = <any OCTET except CTLs,
+                        but including LWS>
+
+   A CRLF is allowed in the definition of TEXT only as part of a header
+   field continuation. It is expected that the folding LWS will be
+   replaced with a single SP before interpretation of the TEXT value.
+
+   Hexadecimal numeric characters are used in several protocol elements.
+
+       HEX            = "A" | "B" | "C" | "D" | "E" | "F"
+                      | "a" | "b" | "c" | "d" | "e" | "f" | DIGIT
+
+   Many HTTP/1.1 header field values consist of words separated by LWS
+   or special characters. These special characters MUST be in a quoted
+   string to be used within a parameter value.
+
+       token          = 1*<any CHAR except CTLs or separators>
+       separators     = "(" | ")" | "<" | ">" | "@"
+                      | "," | ";" | ":" | "\" | <">
+                      | "/" | "[" | "]" | "?" | "="
+                      | "{" | "}" | SP | HT
+
+   A string of text is parsed as a single word if it is quoted using
+   double-quote marks.
+
+      quoted-string  = ( <"> qdstr-val <"> )
+      qdstr-val      = *( qdtext | quoted-pair )
+      qdtext         = <any TEXT except <">>
+
+   Note that LWS is NOT implicit between the double-quote marks (<">)
+   surrounding a qdstr-val and the qdstr-val; any LWS will be considered
+   part of the qdstr-val.  This is also the case for quotation marks
+   surrounding any other construct.
+
+
+
+
+Leach & Newman              Standards Track                    [Page 24]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+   The backslash character ("\") MAY be used as a single-character
+   quoting mechanism only within qdstr-val and comment constructs.
+
+       quoted-pair    = "\" CHAR
+
+   The value of this construct is CHAR. Note that an effect of this rule
+   is that backslash must be quoted.
+
+8  Sample Code
+
+   The sample implementation in [Digest] also applies to DIGEST-MD5.
+
+   The following code implements the conversion from UTF-8 to 8859-1 if
+   necessary.
+
+    /* if the string is entirely in the 8859-1 subset of UTF-8, then
+     * translate to 8859-1 prior to MD5
+     */
+    void MD5_UTF8_8859_1(MD5_CTX *ctx, const unsigned char *base,
+        int len)
+    {
+        const unsigned char *scan, *end;
+        unsigned char cbuf;
+
+        end = base + len;
+        for (scan = base; scan < end; ++scan) {
+            if (*scan > 0xC3) break; /* abort if outside 8859-1 */
+            if (*scan >= 0xC0 && *scan <= 0xC3) {
+                if (++scan == end || *scan < 0x80 || *scan > 0xBF)
+                    break;
+            }
+        }
+        /* if we found a character outside 8859-1, don't alter string
+         */
+        if (scan < end) {
+            MD5Update(ctx, base, len);
+            return;
+        }
+
+        /* convert to 8859-1 prior to applying hash
+         */
+        do {
+            for (scan = base; scan < end && *scan < 0xC0; ++scan)
+                ;
+            if (scan != base) MD5Update(ctx, base, scan - base);
+            if (scan + 1 >= end) break;
+            cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
+            MD5Update(ctx, &cbuf, 1);
+
+
+
+Leach & Newman              Standards Track                    [Page 25]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+            base = scan + 2;
+        } while (base < end);
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 26]
+\f
+RFC 2831                 Digest SASL Mechanism                  May 2000
+
+
+9  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Leach & Newman              Standards Track                    [Page 27]
+\f
diff --git a/doc/rfc2945.txt b/doc/rfc2945.txt
new file mode 100644 (file)
index 0000000..983c441
--- /dev/null
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+Network Working Group                                              T. Wu
+Request for Comments: 2945                           Stanford University
+Category: Standards Track                                 September 2000
+
+
+             The SRP Authentication and Key Exchange System
+
+Status of this Memo
+
+   This document specifies an Internet standards track protocol for the
+   Internet community, and requests discussion and suggestions for
+   improvements.  Please refer to the current edition of the "Internet
+   Official Protocol Standards" (STD 1) for the standardization state
+   and status of this protocol.  Distribution of this memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+Abstract
+
+   This document describes a cryptographically strong network
+   authentication mechanism known as the Secure Remote Password (SRP)
+   protocol.  This mechanism is suitable for negotiating secure
+   connections using a user-supplied password, while eliminating the
+   security problems traditionally associated with reusable passwords.
+   This system also performs a secure key exchange in the process of
+   authentication, allowing security layers (privacy and/or integrity
+   protection) to be enabled during the session.  Trusted key servers
+   and certificate infrastructures are not required, and clients are not
+   required to store or manage any long-term keys.  SRP offers both
+   security and deployment advantages over existing challenge-response
+   techniques, making it an ideal drop-in replacement where secure
+   password authentication is needed.
+
+1. Introduction
+
+   The lack of a secure authentication mechanism that is also easy to
+   use has been a long-standing problem with the vast majority of
+   Internet protocols currently in use.  The problem is two-fold: Users
+   like to use passwords that they can remember, but most password-based
+   authentication systems offer little protection against even passive
+   attackers, especially if weak and easily-guessed passwords are used.
+
+   Eavesdropping on a TCP/IP network can be carried out very easily and
+   very effectively against protocols that transmit passwords in the
+   clear.  Even so-called "challenge-response" techniques like the one
+   described in [RFC 2095] and [RFC 1760], which are designed to defeat
+
+
+
+Wu                          Standards Track                     [Page 1]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   simple sniffing attacks, can be compromised by what is known as a
+   "dictionary attack".  This occurs when an attacker captures the
+   messages exchanged during a legitimate run of the protocol and uses
+   that information to verify a series of guessed passwords taken from a
+   precompiled "dictionary" of common passwords.  This works because
+   users often choose simple, easy-to-remember passwords, which
+   invariably are also easy to guess.
+
+   Many existing mechanisms also require the password database on the
+   host to be kept secret because the password P or some private hash
+   h(P) is stored there and would compromise security if revealed.  That
+   approach often degenerates into "security through obscurity" and goes
+   against the UNIX convention of keeping a "public" password file whose
+   contents can be revealed without destroying system security.
+
+   SRP meets the strictest requirements laid down in [RFC 1704] for a
+   non-disclosing authentication protocol.  It offers complete
+   protection against both passive and active attacks, and accomplishes
+   this efficiently using a single Diffie-Hellman-style round of
+   computation, making it feasible to use in both interactive and non-
+   interactive authentication for a wide range of Internet protocols.
+   Since it retains its security when used with low-entropy passwords,
+   it can be seamlessly integrated into existing user applications.
+
+2. Conventions and Terminology
+
+   The protocol described by this document is sometimes referred to as
+   "SRP-3" for historical purposes.  This particular protocol is
+   described in [SRP] and is believed to have very good logical and
+   cryptographic resistance to both eavesdropping and active attacks.
+
+   This document does not attempt to describe SRP in the context of any
+   particular Internet protocol; instead it describes an abstract
+   protocol that can be easily fitted to a particular application.  For
+   example, the specific format of messages (including padding) is not
+   specified.  Those issues have been left to the protocol implementor
+   to decide.
+
+   The one implementation issue worth specifying here is the mapping
+   between strings and integers.  Internet protocols are byte-oriented,
+   while SRP performs algebraic operations on its messages, so it is
+   logical to define at least one method by which integers can be
+   converted into a string of bytes and vice versa.
+
+   An n-byte string S can be converted to an integer as follows:
+
+   i = S[n-1] + 256 * S[n-2] + 256^2 * S[n-3] + ... + 256^(n-1) * S[0]
+
+
+
+
+Wu                          Standards Track                     [Page 2]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   where i is the integer and S[x] is the value of the x'th byte of S.
+   In human terms, the string of bytes is the integer expressed in base
+   256, with the most significant digit first.  When converting back to
+   a string, S[0] must be non-zero (padding is considered to be a
+   separate, independent process).  This conversion method is suitable
+   for file storage, in-memory representation, and network transmission
+   of large integer values.  Unless otherwise specified, this mapping
+   will be assumed.
+
+   If implementations require padding a string that represents an
+   integer value, it is recommended that they use zero bytes and add
+   them to the beginning of the string.  The conversion back to integer
+   automatically discards leading zero bytes, making this padding scheme
+   less prone to error.
+
+   The SHA hash function, when used in this document, refers to the
+   SHA-1 message digest algorithm described in [SHA1].
+
+3. The SRP-SHA1 mechanism
+
+   This section describes an implementation of the SRP authentication
+   and key-exchange protocol that employs the SHA hash function to
+   generate session keys and authentication proofs.
+
+   The host stores user passwords as triplets of the form
+
+        { <username>, <password verifier>, <salt> }
+
+   Password entries are generated as follows:
+
+        <salt> = random()
+        x = SHA(<salt> | SHA(<username> | ":" | <raw password>))
+        <password verifier> = v = g^x % N
+
+   The | symbol indicates string concatenation, the ^ operator is the
+   exponentiation operation, and the % operator is the integer remainder
+   operation.  Most implementations perform the exponentiation and
+   remainder in a single stage to avoid generating unwieldy intermediate
+   results.  Note that the 160-bit output of SHA is implicitly converted
+   to an integer before it is operated upon.
+
+   Authentication is generally initiated by the client.
+
+      Client                             Host
+     --------                           ------
+      U = <username>              -->
+                                     <--    s = <salt from passwd file>
+
+
+
+
+Wu                          Standards Track                     [Page 3]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   Upon identifying himself to the host, the client will receive the
+   salt stored on the host under his username.
+
+      a = random()
+      A = g^a % N                 -->
+                                         v = <stored password verifier>
+                                         b = random()
+                                  <--    B = (v + g^b) % N
+
+      p = <raw password>
+      x = SHA(s | SHA(U | ":" | p))
+
+      S = (B - g^x) ^ (a + u * x) % N    S = (A * v^u) ^ b % N
+      K = SHA_Interleave(S)              K = SHA_Interleave(S)
+      (this function is described
+       in the next section)
+
+   The client generates a random number, raises g to that power modulo
+   the field prime, and sends the result to the host.  The host does the
+   same thing and also adds the public verifier before sending it to the
+   client.  Both sides then construct the shared session key based on
+   the respective formulae.
+
+   The parameter u is a 32-bit unsigned integer which takes its value
+   from the first 32 bits of the SHA1 hash of B, MSB first.
+
+   The client MUST abort authentication if B % N is zero.
+
+   The host MUST abort the authentication attempt if A % N is zero.  The
+   host MUST send B after receiving A from the client, never before.
+
+   At this point, the client and server should have a common session key
+   that is secure (i.e. not known to an outside party).  To finish
+   authentication, they must prove to each other that their keys are
+   identical.
+
+        M = H(H(N) XOR H(g) | H(U) | s | A | B | K)
+                                    -->
+                                    <--    H(A | M | K)
+
+   The server will calculate M using its own K and compare it against
+   the client's response.  If they do not match, the server MUST abort
+   and signal an error before it attempts to answer the client's
+   challenge.  Not doing so could compromise the security of the user's
+   password.
+
+
+
+
+
+
+Wu                          Standards Track                     [Page 4]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   If the server receives a correct response, it issues its own proof to
+   the client.  The client will compute the expected response using its
+   own K to verify the authenticity of the server.  If the client
+   responded correctly, the server MUST respond with its hash value.
+
+   The transactions in this protocol description do not necessarily have
+   a one-to-one correspondence with actual protocol messages.  This
+   description is only intended to illustrate the relationships between
+   the different parameters and how they are computed.  It is possible,
+   for example, for an implementation of the SRP-SHA1 mechanism to
+   consolidate some of the flows as follows:
+
+        Client                             Host
+       --------                           ------
+        U, A                        -->
+                                    <--    s, B
+        H(H(N) XOR H(g) | H(U) | s | A | B | K)
+                                    -->
+                                    <--    H(A | M | K)
+
+   The values of N and g used in this protocol must be agreed upon by
+   the two parties in question.  They can be set in advance, or the host
+   can supply them to the client.  In the latter case, the host should
+   send the parameters in the first message along with the salt.  For
+   maximum security, N should be a safe prime (i.e. a number of the form
+   N = 2q + 1, where q is also prime).  Also, g should be a generator
+   modulo N (see [SRP] for details), which means that for any X where 0
+   < X < N, there exists a value x for which g^x % N == X.
+
+3.1.  Interleaved SHA
+
+   The SHA_Interleave function used in SRP-SHA1 is used to generate a
+   session key that is twice as long as the 160-bit output of SHA1.  To
+   compute this function, remove all leading zero bytes from the input.
+   If the length of the resulting string is odd, also remove the first
+   byte.  Call the resulting string T.  Extract the even-numbered bytes
+   into a string E and the odd-numbered bytes into a string F, i.e.
+
+     E = T[0] | T[2] | T[4] | ...
+     F = T[1] | T[3] | T[5] | ...
+
+   Both E and F should be exactly half the length of T.  Hash each one
+   with regular SHA1, i.e.
+
+     G = SHA(E)
+     H = SHA(F)
+
+
+
+
+
+Wu                          Standards Track                     [Page 5]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   Interleave the two hashes back together to form the output, i.e.
+
+     result = G[0] | H[0] | G[1] | H[1] | ... | G[19] | H[19]
+
+   The result will be 40 bytes (320 bits) long.
+
+3.2.  Other Hash Algorithms
+
+   SRP can be used with hash functions other than SHA.  If the hash
+   function produces an output of a different length than SHA (20
+   bytes), it may change the length of some of the messages in the
+   protocol, but the fundamental operation will be unaffected.
+
+   Earlier versions of the SRP mechanism used the MD5 hash function,
+   described in [RFC 1321].  Keyed hash transforms are also recommended
+   for use with SRP; one possible construction uses HMAC [RFC 2104],
+   using K to key the hash in each direction instead of concatenating it
+   with the other parameters.
+
+   Any hash function used with SRP should produce an output of at least
+   16 bytes and have the property that small changes in the input cause
+   significant nonlinear changes in the output.  [SRP] covers these
+   issues in more depth.
+
+4. Security Considerations
+
+   This entire memo discusses an authentication and key-exchange system
+   that protects passwords and exchanges keys across an untrusted
+   network.  This system improves security by eliminating the need to
+   send cleartext passwords over the network and by enabling encryption
+   through its secure key-exchange mechanism.
+
+   The private values for a and b correspond roughly to the private
+   values in a Diffie-Hellman exchange and have similar constraints of
+   length and entropy.  Implementations may choose to increase the
+   length of the parameter u, as long as both client and server agree,
+   but it is not recommended that it be shorter than 32 bits.
+
+   SRP has been designed not only to counter the threat of casual
+   password-sniffing, but also to prevent a determined attacker equipped
+   with a dictionary of passwords from guessing at passwords using
+   captured network traffic.  The SRP protocol itself also resists
+   active network attacks, and implementations can use the securely
+   exchanged keys to protect the session against hijacking and provide
+   confidentiality.
+
+
+
+
+
+
+Wu                          Standards Track                     [Page 6]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+   SRP also has the added advantage of permitting the host to store
+   passwords in a form that is not directly useful to an attacker.  Even
+   if the host's password database were publicly revealed, the attacker
+   would still need an expensive dictionary search to obtain any
+   passwords.  The exponential computation required to validate a guess
+   in this case is much more time-consuming than the hash currently used
+   by most UNIX systems.  Hosts are still advised, though, to try their
+   best to keep their password files secure.
+
+5. References
+
+   [RFC 1321]  Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
+               April 1992.
+
+   [RFC 1704]  Haller, N. and R. Atkinson, "On Internet Authentication",
+               RFC 1704, October 1994.
+
+   [RFC 1760]  Haller, N., "The S/Key One-Time Password System", RFC
+               1760, Feburary 1995.
+
+   [RFC 2095]  Klensin, J., Catoe, R. and P. Krumviede, "IMAP/POP
+               AUTHorize Extension for Simple Challenge/Response", RFC
+               2095, January 1997.
+
+   [RFC 2104]  Krawczyk, H., Bellare, M. and  R. Canetti, "HMAC: Keyed-
+               Hashing for Message Authentication", RFC 2104, February
+               1997.
+
+   [SHA1]      National Institute of Standards and Technology (NIST),
+               "Announcing the Secure Hash Standard", FIPS 180-1, U.S.
+               Department of Commerce, April 1995.
+
+   [SRP]       T. Wu, "The Secure Remote Password Protocol", In
+               Proceedings of the 1998 Internet Society Symposium on
+               Network and Distributed Systems Security, San Diego, CA,
+               pp. 97-111.
+
+6. Author's Address
+
+   Thomas Wu
+   Stanford University
+   Stanford, CA 94305
+
+   EMail: tjw@cs.Stanford.EDU
+
+
+
+
+
+
+
+Wu                          Standards Track                     [Page 7]
+\f
+RFC 2945        SRP Authentication & Key Exchange System  September 2000
+
+
+7.  Full Copyright Statement
+
+   Copyright (C) The Internet Society (2000).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wu                          Standards Track                     [Page 8]
+\f
diff --git a/doc/rfc3174.txt b/doc/rfc3174.txt
new file mode 100644 (file)
index 0000000..ebe515d
--- /dev/null
@@ -0,0 +1,1235 @@
+
+
+
+
+
+
+Network Working Group                                   D. Eastlake, 3rd
+Request for Comments: 3174                                      Motorola
+Category: Informational                                         P. Jones
+                                                           Cisco Systems
+                                                          September 2001
+
+
+                   US Secure Hash Algorithm 1 (SHA1)
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2001).  All Rights Reserved.
+
+Abstract
+
+   The purpose of this document is to make the SHA-1 (Secure Hash
+   Algorithm 1) hash algorithm conveniently available to the Internet
+   community.  The United States of America has adopted the SHA-1 hash
+   algorithm described herein as a Federal Information Processing
+   Standard.  Most of the text herein was taken by the authors from FIPS
+   180-1.  Only the C code implementation is "original".
+
+Acknowledgements
+
+   Most of the text herein was taken from [FIPS 180-1].  Only the C code
+   implementation is "original" but its style is similar to the
+   previously published MD4 and MD5 RFCs [RFCs 1320, 1321].
+
+   The SHA-1 is based on principles similar to those used by Professor
+   Ronald L. Rivest of MIT when designing the MD4 message digest
+   algorithm [MD4] and is modeled after that algorithm [RFC 1320].
+
+   Useful comments from the following, which have been incorporated
+   herein, are gratefully acknowledged:
+
+      Tony Hansen
+      Garrett Wollman
+
+
+
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 1]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+Table of Contents
+
+   1. Overview of Contents...........................................  2
+   2. Definitions of Bit Strings and Integers........................  3
+   3. Operations on Words............................................  3
+   4. Message Padding................................................  4
+   5. Functions and Constants Used...................................  6
+   6. Computing the Message Digest...................................  6
+   6.1 Method 1......................................................  6
+   6.2 Method 2......................................................  7
+   7. C Code.........................................................  8
+   7.1 .h file.......................................................  8
+   7.2 .c file....................................................... 10
+   7.3 Test Driver................................................... 18
+   8. Security Considerations........................................ 20
+   References........................................................ 21
+   Authors' Addresses................................................ 21
+   Full Copyright Statement.......................................... 22
+
+1. Overview of Contents
+
+   NOTE: The text below is mostly taken from [FIPS 180-1] and assertions
+   therein of the security of SHA-1 are made by the US Government, the
+   author of [FIPS 180-1], and not by the authors of this document.
+
+   This document specifies a Secure Hash Algorithm, SHA-1, for computing
+   a condensed representation of a message or a data file.  When a
+   message of any length < 2^64 bits is input, the SHA-1 produces a
+   160-bit output called a message digest.  The message digest can then,
+   for example, be input to a signature algorithm which generates or
+   verifies the signature for the message.  Signing the message digest
+   rather than the message often improves the efficiency of the process
+   because the message digest is usually much smaller in size than the
+   message.  The same hash algorithm must be used by the verifier of a
+   digital signature as was used by the creator of the digital
+   signature.  Any change to the message in transit will, with very high
+   probability, result in a different message digest, and the signature
+   will fail to verify.
+
+   The SHA-1 is called secure because it is computationally infeasible
+   to find a message which corresponds to a given message digest, or to
+   find two different messages which produce the same message digest.
+   Any change to a message in transit will, with very high probability,
+   result in a different message digest, and the signature will fail to
+   verify.
+
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 2]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+   Section 2 below defines the terminology and functions used as
+   building blocks to form SHA-1.
+
+2. Definitions of Bit Strings and Integers
+
+   The following terminology related to bit strings and integers will be
+   used:
+
+   a. A hex digit is an element of the set {0, 1, ... , 9, A, ... , F}.
+      A hex digit is the representation of a 4-bit string.  Examples:  7
+      = 0111, A = 1010.
+
+   b. A word equals a 32-bit string which may be represented as a
+      sequence of 8 hex digits.  To convert a word to 8 hex digits each
+      4-bit string is converted to its hex equivalent as described in
+      (a) above.  Example:
+
+      1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23.
+
+   c. An integer between 0 and 2^32 - 1 inclusive may be represented as
+      a word.  The least significant four bits of the integer are
+      represented by the right-most hex digit of the word
+      representation.  Example: the integer 291 = 2^8+2^5+2^1+2^0 =
+      256+32+2+1 is represented by the hex word, 00000123.
+
+      If z is an integer, 0 <= z < 2^64, then z = (2^32)x + y where 0 <=
+      x < 2^32 and 0 <= y < 2^32.  Since x and y can be represented as
+      words X and Y, respectively, z can be represented as the pair of
+      words (X,Y).
+
+   d. block = 512-bit string.  A block (e.g., B) may be represented as a
+      sequence of 16 words.
+
+3. Operations on Words
+
+   The following logical operators will be applied to words:
+
+   a. Bitwise logical word operations
+
+      X AND Y  =  bitwise logical "and" of  X and Y.
+
+      X OR Y   =  bitwise logical "inclusive-or" of X and Y.
+
+      X XOR Y  =  bitwise logical "exclusive-or" of X and Y.
+
+      NOT X    =  bitwise logical "complement" of X.
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 3]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+      Example:
+
+               01101100101110011101001001111011
+         XOR   01100101110000010110100110110111
+               --------------------------------
+           =   00001001011110001011101111001100
+
+   b. The operation X + Y is defined as follows:  words X and Y
+      represent integers x and y, where 0 <= x < 2^32 and 0 <= y < 2^32.
+      For positive integers n and m, let n mod m be the remainder upon
+      dividing n by m.  Compute
+
+         z  =  (x + y) mod 2^32.
+
+      Then 0 <= z < 2^32.  Convert z to a word,  Z, and define Z = X +
+      Y.
+
+   c. The circular left shift operation S^n(X), where X is a word and n
+      is an integer with 0 <= n < 32, is defined by
+
+         S^n(X)  =  (X << n) OR (X >> 32-n).
+
+      In the above, X << n is obtained as follows: discard the left-most
+      n bits of X and then pad the result with n zeroes on the right
+      (the result will still be 32 bits).  X >> n is obtained by
+      discarding the right-most n bits of X and then padding the result
+      with n zeroes on the left.  Thus S^n(X) is equivalent to a
+      circular shift of X by n positions to the left.
+
+4. Message Padding
+
+   SHA-1 is used to compute a message digest for a message or data file
+   that is provided as input.  The message or data file should be
+   considered to be a bit string.  The length of the message is the
+   number of bits in the message (the empty message has length 0).  If
+   the number of bits in a message is a multiple of 8, for compactness
+   we can represent the message in hex.  The purpose of message padding
+   is to make the total length of a padded message a multiple of 512.
+   SHA-1 sequentially processes blocks of 512 bits when computing the
+   message digest.  The following specifies how this padding shall be
+   performed.  As a summary, a "1" followed by m "0"s followed by a 64-
+   bit integer are appended to the end of the message to produce a
+   padded message of length 512 * n.  The 64-bit integer is the length
+   of the original message.  The padded message is then processed by the
+   SHA-1 as n 512-bit blocks.
+
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 4]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+   Suppose a message has length l < 2^64.  Before it is input to the
+   SHA-1, the message is padded on the right as follows:
+
+   a. "1" is appended.  Example: if the original message is "01010000",
+      this is padded to "010100001".
+
+   b. "0"s are appended.  The number of "0"s will depend on the original
+      length of the message.  The last 64 bits of the last 512-bit block
+      are reserved
+
+      for the length l of the original message.
+
+      Example:  Suppose the original message is the bit string
+
+         01100001 01100010 01100011 01100100 01100101.
+
+      After step (a) this gives
+
+         01100001 01100010 01100011 01100100 01100101 1.
+
+      Since l = 40, the number of bits in the above is 41 and 407 "0"s
+      are appended, making the total now 448.  This gives (in hex)
+
+         61626364 65800000 00000000 00000000
+         00000000 00000000 00000000 00000000
+         00000000 00000000 00000000 00000000
+         00000000 00000000.
+
+   c. Obtain the 2-word representation of l, the number of bits in the
+      original message.  If l < 2^32 then the first word is all zeroes.
+      Append these two words to the padded message.
+
+      Example: Suppose the original message is as in (b).  Then l = 40
+      (note that l is computed before any padding).  The two-word
+      representation of 40 is hex 00000000 00000028.  Hence the final
+      padded message is hex
+
+         61626364 65800000 00000000 00000000
+         00000000 00000000 00000000 00000000
+         00000000 00000000 00000000 00000000
+         00000000 00000000 00000000 00000028.
+
+      The padded message will contain 16 * n words for some n > 0.
+      The padded message is regarded as a sequence of n blocks M(1) ,
+      M(2), first characters (or bits) of the message.
+
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 5]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+5. Functions and Constants Used
+
+   A sequence of logical functions f(0), f(1),..., f(79) is used in
+   SHA-1.  Each f(t), 0 <= t <= 79, operates on three 32-bit words B, C,
+   D and produces a 32-bit word as output.  f(t;B,C,D) is defined as
+   follows: for words B, C, D,
+
+      f(t;B,C,D) = (B AND C) OR ((NOT B) AND D)         ( 0 <= t <= 19)
+
+      f(t;B,C,D) = B XOR C XOR D                        (20 <= t <= 39)
+
+      f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D)  (40 <= t <= 59)
+
+      f(t;B,C,D) = B XOR C XOR D                        (60 <= t <= 79).
+
+   A sequence of constant words K(0), K(1), ... , K(79) is used in the
+   SHA-1.  In hex these are given by
+
+      K(t) = 5A827999         ( 0 <= t <= 19)
+
+      K(t) = 6ED9EBA1         (20 <= t <= 39)
+
+      K(t) = 8F1BBCDC         (40 <= t <= 59)
+
+      K(t) = CA62C1D6         (60 <= t <= 79).
+
+6. Computing the Message Digest
+
+   The methods given in 6.1 and 6.2 below yield the same message digest.
+   Although using method 2 saves sixty-four 32-bit words of storage, it
+   is likely to lengthen execution time due to the increased complexity
+   of the address computations for the { W[t] } in step (c).  There are
+   other computation methods which give identical results.
+
+6.1 Method 1
+
+   The message digest is computed using the message padded as described
+   in section 4.  The computation is described using two buffers, each
+   consisting of five 32-bit words, and a sequence of eighty 32-bit
+   words.  The words of the first 5-word buffer are labeled A,B,C,D,E.
+   The words of the second 5-word buffer are labeled H0, H1, H2, H3, H4.
+   The words of the 80-word sequence are labeled W(0), W(1),..., W(79).
+   A single word buffer TEMP is also employed.
+
+   To generate the message digest, the 16-word blocks M(1), M(2),...,
+   M(n) defined in section 4 are processed in order.  The processing of
+   each M(i) involves 80 steps.
+
+
+
+
+Eastlake & Jones             Informational                      [Page 6]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+   Before processing any blocks, the H's are initialized as follows: in
+   hex,
+
+      H0 = 67452301
+
+      H1 = EFCDAB89
+
+      H2 = 98BADCFE
+
+      H3 = 10325476
+
+      H4 = C3D2E1F0.
+
+   Now M(1), M(2), ... , M(n) are processed.  To process M(i), we
+   proceed as follows:
+
+      a. Divide M(i) into 16 words W(0), W(1), ... , W(15), where W(0)
+         is the left-most word.
+
+      b. For t = 16 to 79 let
+
+         W(t) = S^1(W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16)).
+
+      c. Let A = H0, B = H1, C = H2, D = H3, E = H4.
+
+      d. For t = 0 to 79 do
+
+         TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t);
+
+         E = D;  D = C;  C = S^30(B);  B = A; A = TEMP;
+
+      e. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4
+         + E.
+
+   After processing M(n), the message digest is the 160-bit string
+   represented by the 5 words
+
+         H0 H1 H2 H3 H4.
+
+6.2 Method 2
+
+   The method above assumes that the sequence W(0), ... , W(79) is
+   implemented as an array of eighty 32-bit words.  This is efficient
+   from the standpoint of minimization of execution time, since the
+   addresses of W(t-3), ...  ,W(t-16) in step (b) are easily computed.
+   If space is at a premium, an alternative is to regard { W(t) } as a
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 7]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+   circular queue, which may be implemented using an array of sixteen
+   32-bit words W[0], ... W[15].  In this case, in hex let
+
+   MASK = 0000000F.  Then processing of M(i) is as follows:
+
+      a. Divide M(i) into 16 words W[0], ... , W[15], where W[0] is the
+         left-most word.
+
+      b. Let A = H0, B = H1, C = H2, D = H3, E = H4.
+
+      c. For t = 0 to 79 do
+
+         s = t AND MASK;
+
+         if (t >= 16) W[s] = S^1(W[(s + 13) AND MASK] XOR W[(s + 8) AND
+         MASK] XOR W[(s + 2) AND MASK] XOR W[s]);
+
+         TEMP = S^5(A) + f(t;B,C,D) + E + W[s] + K(t);
+
+         E = D; D = C; C = S^30(B); B = A; A = TEMP;
+
+      d. Let H0 = H0 + A, H1 = H1 + B, H2 = H2 + C, H3 = H3 + D, H4 = H4
+         + E.
+
+7. C Code
+
+   Below is a demonstration implementation of SHA-1 in C.  Section 7.1
+   contains the header file, 7.2 the C code, and 7.3 a test driver.
+
+7.1 .h file
+
+/*
+ *  sha1.h
+ *
+ *  Description:
+ *      This is the header file for code which implements the Secure
+ *      Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
+ *      April 17, 1995.
+ *
+ *      Many of the variable names in this code, especially the
+ *      single character names, were used because those were the names
+ *      used in the publication.
+ *
+ *      Please read the file sha1.c for more information.
+ *
+ */
+
+
+
+
+
+Eastlake & Jones             Informational                      [Page 8]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+#ifndef _SHA1_H_
+#define _SHA1_H_
+
+#include <stdint.h>
+/*
+ * If you do not have the ISO standard stdint.h header file, then you
+ * must typdef the following:
+ *    name              meaning
+ *  uint32_t         unsigned 32 bit integer
+ *  uint8_t          unsigned 8 bit integer (i.e., unsigned char)
+ *  int_least16_t    integer of >= 16 bits
+ *
+ */
+
+#ifndef _SHA_enum_
+#define _SHA_enum_
+enum
+{
+    shaSuccess = 0,
+    shaNull,            /* Null pointer parameter */
+    shaInputTooLong,    /* input data too long */
+    shaStateError       /* called Input after Result */
+};
+#endif
+#define SHA1HashSize 20
+
+/*
+ *  This structure will hold context information for the SHA-1
+ *  hashing operation
+ */
+typedef struct SHA1Context
+{
+    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */
+
+    uint32_t Length_Low;            /* Message length in bits      */
+    uint32_t Length_High;           /* Message length in bits      */
+
+                               /* Index into message block array   */
+    int_least16_t Message_Block_Index;
+    uint8_t Message_Block[64];      /* 512-bit message blocks      */
+
+    int Computed;               /* Is the digest computed?         */
+    int Corrupted;             /* Is the message digest corrupted? */
+} SHA1Context;
+
+/*
+ *  Function Prototypes
+ */
+
+
+
+Eastlake & Jones             Informational                      [Page 9]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+int SHA1Reset(  SHA1Context *);
+int SHA1Input(  SHA1Context *,
+                const uint8_t *,
+                unsigned int);
+int SHA1Result( SHA1Context *,
+                uint8_t Message_Digest[SHA1HashSize]);
+
+#endif
+
+7.2 .c file
+
+/*
+ *  sha1.c
+ *
+ *  Description:
+ *      This file implements the Secure Hashing Algorithm 1 as
+ *      defined in FIPS PUB 180-1 published April 17, 1995.
+ *
+ *      The SHA-1, produces a 160-bit message digest for a given
+ *      data stream.  It should take about 2**n steps to find a
+ *      message with the same digest as a given message and
+ *      2**(n/2) to find any two messages with the same digest,
+ *      when n is the digest size in bits.  Therefore, this
+ *      algorithm can serve as a means of providing a
+ *      "fingerprint" for a message.
+ *
+ *  Portability Issues:
+ *      SHA-1 is defined in terms of 32-bit "words".  This code
+ *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
+ *      bit unsigned integer types.  If your C compiler does not
+ *      support 32 bit unsigned integers, this code is not
+ *      appropriate.
+ *
+ *  Caveats:
+ *      SHA-1 is designed to work with messages less than 2^64 bits
+ *      long.  Although SHA-1 allows a message digest to be generated
+ *      for messages of any number of bits less than 2^64, this
+ *      implementation only works with messages with a length that is
+ *      a multiple of the size of an 8-bit character.
+ *
+ */
+
+
+
+
+
+
+
+
+
+
+Eastlake & Jones             Informational                     [Page 10]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+#include "sha1.h"
+
+/*
+ *  Define the SHA1 circular left shift macro
+ */
+#define SHA1CircularShift(bits,word) \
+                (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/* Local Function Prototyptes */
+void SHA1PadMessage(SHA1Context *);
+void SHA1ProcessMessageBlock(SHA1Context *);
+
+/*
+ *  SHA1Reset
+ *
+ *  Description:
+ *      This function will initialize the SHA1Context in preparation
+ *      for computing a new SHA1 message digest.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to reset.
+ *
+ *  Returns:
+ *      sha Error Code.
+ *
+ */
+int SHA1Reset(SHA1Context *context)
+{
+    if (!context)
+    {
+        return shaNull;
+    }
+
+    context->Length_Low             = 0;
+    context->Length_High            = 0;
+    context->Message_Block_Index    = 0;
+
+    context->Intermediate_Hash[0]   = 0x67452301;
+    context->Intermediate_Hash[1]   = 0xEFCDAB89;
+    context->Intermediate_Hash[2]   = 0x98BADCFE;
+    context->Intermediate_Hash[3]   = 0x10325476;
+    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
+
+    context->Computed   = 0;
+    context->Corrupted  = 0;
+
+
+
+
+
+Eastlake & Jones             Informational                     [Page 11]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+    return shaSuccess;
+}
+
+/*
+ *  SHA1Result
+ *
+ *  Description:
+ *      This function will return the 160-bit message digest into the
+ *      Message_Digest array  provided by the caller.
+ *      NOTE: The first octet of hash is stored in the 0th element,
+ *            the last octet of hash in the 19th element.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to use to calculate the SHA-1 hash.
+ *      Message_Digest: [out]
+ *          Where the digest is returned.
+ *
+ *  Returns:
+ *      sha Error Code.
+ *
+ */
+int SHA1Result( SHA1Context *context,
+                uint8_t Message_Digest[SHA1HashSize])
+{
+    int i;
+
+    if (!context || !Message_Digest)
+    {
+        return shaNull;
+    }
+
+    if (context->Corrupted)
+    {
+        return context->Corrupted;
+    }
+
+    if (!context->Computed)
+    {
+        SHA1PadMessage(context);
+        for(i=0; i<64; ++i)
+        {
+            /* message may be sensitive, clear it out */
+            context->Message_Block[i] = 0;
+        }
+        context->Length_Low = 0;    /* and clear length */
+        context->Length_High = 0;
+        context->Computed = 1;
+
+
+
+Eastlake & Jones             Informational                     [Page 12]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+    }
+
+    for(i = 0; i < SHA1HashSize; ++i)
+    {
+        Message_Digest[i] = context->Intermediate_Hash[i>>2]
+                            >> 8 * ( 3 - ( i & 0x03 ) );
+    }
+
+    return shaSuccess;
+}
+
+/*
+ *  SHA1Input
+ *
+ *  Description:
+ *      This function accepts an array of octets as the next portion
+ *      of the message.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The SHA context to update
+ *      message_array: [in]
+ *          An array of characters representing the next portion of
+ *          the message.
+ *      length: [in]
+ *          The length of the message in message_array
+ *
+ *  Returns:
+ *      sha Error Code.
+ *
+ */
+int SHA1Input(    SHA1Context    *context,
+                  const uint8_t  *message_array,
+                  unsigned       length)
+{
+    if (!length)
+    {
+        return shaSuccess;
+    }
+
+    if (!context || !message_array)
+    {
+        return shaNull;
+    }
+
+    if (context->Computed)
+    {
+        context->Corrupted = shaStateError;
+
+
+
+Eastlake & Jones             Informational                     [Page 13]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+        return shaStateError;
+    }
+
+    if (context->Corrupted)
+    {
+         return context->Corrupted;
+    }
+    while(length-- && !context->Corrupted)
+    {
+    context->Message_Block[context->Message_Block_Index++] =
+                    (*message_array & 0xFF);
+
+    context->Length_Low += 8;
+    if (context->Length_Low == 0)
+    {
+        context->Length_High++;
+        if (context->Length_High == 0)
+        {
+            /* Message is too long */
+            context->Corrupted = 1;
+        }
+    }
+
+    if (context->Message_Block_Index == 64)
+    {
+        SHA1ProcessMessageBlock(context);
+    }
+
+    message_array++;
+    }
+
+    return shaSuccess;
+}
+
+/*
+ *  SHA1ProcessMessageBlock
+ *
+ *  Description:
+ *      This function will process the next 512 bits of the message
+ *      stored in the Message_Block array.
+ *
+ *  Parameters:
+ *      None.
+ *
+ *  Returns:
+ *      Nothing.
+ *
+ *  Comments:
+
+
+
+Eastlake & Jones             Informational                     [Page 14]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+ *      Many of the variable names in this code, especially the
+ *      single character names, were used because those were the
+ *      names used in the publication.
+ *
+ *
+ */
+void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
+                            0x5A827999,
+                            0x6ED9EBA1,
+                            0x8F1BBCDC,
+                            0xCA62C1D6
+                            };
+    int           t;                 /* Loop counter                */
+    uint32_t      temp;              /* Temporary word value        */
+    uint32_t      W[80];             /* Word sequence               */
+    uint32_t      A, B, C, D, E;     /* Word buffers                */
+
+    /*
+     *  Initialize the first 16 words in the array W
+     */
+    for(t = 0; t < 16; t++)
+    {
+        W[t] = context->Message_Block[t * 4] << 24;
+        W[t] |= context->Message_Block[t * 4 + 1] << 16;
+        W[t] |= context->Message_Block[t * 4 + 2] << 8;
+        W[t] |= context->Message_Block[t * 4 + 3];
+    }
+
+    for(t = 16; t < 80; t++)
+    {
+       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+    }
+
+    A = context->Intermediate_Hash[0];
+    B = context->Intermediate_Hash[1];
+    C = context->Intermediate_Hash[2];
+    D = context->Intermediate_Hash[3];
+    E = context->Intermediate_Hash[4];
+
+    for(t = 0; t < 20; t++)
+    {
+        temp =  SHA1CircularShift(5,A) +
+                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+
+
+
+Eastlake & Jones             Informational                     [Page 15]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+        B = A;
+        A = temp;
+    }
+
+    for(t = 20; t < 40; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 40; t < 60; t++)
+    {
+        temp = SHA1CircularShift(5,A) +
+               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    for(t = 60; t < 80; t++)
+    {
+        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
+        E = D;
+        D = C;
+        C = SHA1CircularShift(30,B);
+        B = A;
+        A = temp;
+    }
+
+    context->Intermediate_Hash[0] += A;
+    context->Intermediate_Hash[1] += B;
+    context->Intermediate_Hash[2] += C;
+    context->Intermediate_Hash[3] += D;
+    context->Intermediate_Hash[4] += E;
+
+    context->Message_Block_Index = 0;
+}
+
+
+/*
+ *  SHA1PadMessage
+ *
+
+
+
+Eastlake & Jones             Informational                     [Page 16]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+ *  Description:
+ *      According to the standard, the message must be padded to an even
+ *      512 bits.  The first padding bit must be a '1'.  The last 64
+ *      bits represent the length of the original message.  All bits in
+ *      between should be 0.  This function will pad the message
+ *      according to those rules by filling the Message_Block array
+ *      accordingly.  It will also call the ProcessMessageBlock function
+ *      provided appropriately.  When it returns, it can be assumed that
+ *      the message digest has been computed.
+ *
+ *  Parameters:
+ *      context: [in/out]
+ *          The context to pad
+ *      ProcessMessageBlock: [in]
+ *          The appropriate SHA*ProcessMessageBlock function
+ *  Returns:
+ *      Nothing.
+ *
+ */
+
+void SHA1PadMessage(SHA1Context *context)
+{
+    /*
+     *  Check to see if the current message block is too small to hold
+     *  the initial padding bits and length.  If so, we will pad the
+     *  block, process it, and then continue padding into a second
+     *  block.
+     */
+    if (context->Message_Block_Index > 55)
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 64)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+
+        SHA1ProcessMessageBlock(context);
+
+        while(context->Message_Block_Index < 56)
+        {
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+    else
+    {
+        context->Message_Block[context->Message_Block_Index++] = 0x80;
+        while(context->Message_Block_Index < 56)
+        {
+
+
+
+Eastlake & Jones             Informational                     [Page 17]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+            context->Message_Block[context->Message_Block_Index++] = 0;
+        }
+    }
+
+    /*
+     *  Store the message length as the last 8 octets
+     */
+    context->Message_Block[56] = context->Length_High >> 24;
+    context->Message_Block[57] = context->Length_High >> 16;
+    context->Message_Block[58] = context->Length_High >> 8;
+    context->Message_Block[59] = context->Length_High;
+    context->Message_Block[60] = context->Length_Low >> 24;
+    context->Message_Block[61] = context->Length_Low >> 16;
+    context->Message_Block[62] = context->Length_Low >> 8;
+    context->Message_Block[63] = context->Length_Low;
+
+    SHA1ProcessMessageBlock(context);
+}
+
+7.3 Test Driver
+
+   The following code is a main program test driver to exercise the code
+   in sha1.c.
+
+/*
+ *  sha1test.c
+ *
+ *  Description:
+ *      This file will exercise the SHA-1 code performing the three
+ *      tests documented in FIPS PUB 180-1 plus one which calls
+ *      SHA1Input with an exact multiple of 512 bits, plus a few
+ *      error test checks.
+ *
+ *  Portability Issues:
+ *      None.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "sha1.h"
+
+/*
+ *  Define patterns for testing
+ */
+#define TEST1   "abc"
+#define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
+
+
+
+Eastlake & Jones             Informational                     [Page 18]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+#define TEST2b  "jkijkljklmklmnlmnomnopnopq"
+#define TEST2   TEST2a TEST2b
+#define TEST3   "a"
+#define TEST4a  "01234567012345670123456701234567"
+#define TEST4b  "01234567012345670123456701234567"
+    /* an exact multiple of 512 bits */
+#define TEST4   TEST4a TEST4b
+char *testarray[4] =
+{
+    TEST1,
+    TEST2,
+    TEST3,
+    TEST4
+};
+long int repeatcount[4] = { 1, 1, 1000000, 10 };
+char *resultarray[4] =
+{
+    "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D",
+    "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1",
+    "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F",
+    "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52"
+};
+
+int main()
+{
+    SHA1Context sha;
+    int i, j, err;
+    uint8_t Message_Digest[20];
+
+    /*
+     *  Perform SHA-1 tests
+     */
+    for(j = 0; j < 4; ++j)
+    {
+        printf( "\nTest %d: %d, '%s'\n",
+                j+1,
+                repeatcount[j],
+                testarray[j]);
+
+        err = SHA1Reset(&sha);
+        if (err)
+        {
+            fprintf(stderr, "SHA1Reset Error %d.\n", err );
+            break;    /* out of for j loop */
+        }
+
+        for(i = 0; i < repeatcount[j]; ++i)
+        {
+
+
+
+Eastlake & Jones             Informational                     [Page 19]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+            err = SHA1Input(&sha,
+                  (const unsigned char *) testarray[j],
+                  strlen(testarray[j]));
+            if (err)
+            {
+                fprintf(stderr, "SHA1Input Error %d.\n", err );
+                break;    /* out of for i loop */
+            }
+        }
+
+        err = SHA1Result(&sha, Message_Digest);
+        if (err)
+        {
+            fprintf(stderr,
+            "SHA1Result Error %d, could not compute message digest.\n",
+            err );
+        }
+        else
+        {
+            printf("\t");
+            for(i = 0; i < 20 ; ++i)
+            {
+                printf("%02X ", Message_Digest[i]);
+            }
+            printf("\n");
+        }
+        printf("Should match:\n");
+        printf("\t%s\n", resultarray[j]);
+    }
+
+    /* Test some error returns */
+    err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1);
+    printf ("\nError %d. Should be %d.\n", err, shaStateError );
+    err = SHA1Reset(0);
+    printf ("\nError %d. Should be %d.\n", err, shaNull );
+    return 0;
+}
+
+8. Security Considerations
+
+   This document is intended to provide convenient open source access by
+   the Internet community to the United States of America Federal
+   Information Processing Standard Secure Hash Function SHA-1 [FIPS
+   180-1].  No independent assertion of the security of this hash
+   function by the authors for any particular use is intended.
+
+
+
+
+
+
+Eastlake & Jones             Informational                     [Page 20]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+References
+
+   [FIPS 180-1] "Secure Hash Standard", United States of American,
+                National Institute of Science and Technology, Federal
+                Information Processing Standard (FIPS) 180-1, April
+                1993.
+
+   [MD4]        "The MD4 Message Digest Algorithm," Advances in
+                Cryptology - CRYPTO '90 Proceedings, Springer-Verlag,
+                1991, pp. 303-311.
+
+   [RFC 1320]   Rivest, R., "The MD4 Message-Digest Algorithm", RFC
+                1320, April 1992.
+
+   [RFC 1321]   Rivest, R., "The MD5 Message-Digest Algorithm", RFC
+                1321, April 1992.
+
+   [RFC 1750]   Eastlake, D., Crocker, S. and J. Schiller, "Randomness
+                Requirements for Security", RFC 1750, December 1994.
+
+Authors' Addresses
+
+   Donald E. Eastlake, 3rd
+   Motorola
+   155 Beaver Street
+   Milford, MA 01757 USA
+
+   Phone:   +1 508-634-2066 (h)
+            +1 508-261-5434 (w)
+   Fax:     +1 508-261-4777
+   EMail:   Donald.Eastlake@motorola.com
+
+
+   Paul E. Jones
+   Cisco Systems, Inc.
+   7025 Kit Creek Road
+   Research Triangle Park, NC 27709 USA
+
+   Phone:   +1 919 392 6948
+   EMail:   paulej@packetizer.com
+
+
+
+
+
+
+
+
+
+
+
+Eastlake & Jones             Informational                     [Page 21]
+\f
+RFC 3174           US Secure Hash Algorithm 1 (SHA1)      September 2001
+
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2001).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake & Jones             Informational                     [Page 22]
+\f
diff --git a/doc/server-plugin-flow.fig b/doc/server-plugin-flow.fig
new file mode 100644 (file)
index 0000000..d98d7c7
--- /dev/null
@@ -0,0 +1,115 @@
+#FIG 3.2
+Landscape
+Center
+Inches
+Letter  
+100.00
+Single
+-2
+1200 2
+6 14100 14100 17100 18450
+2 2 0 1 0 0 50 0 4 0.000 0 0 -1 0 0 5
+        14100 14100 17100 14100 17100 18450 14100 18450 14100 14100
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        16950 18150 16950 16500 14325 16500 14325 18150 16950 18150
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        16950 16275 16950 14775 14250 14775 14250 16275 16950 16275
+4 0 0 50 0 18 18 0.0000 4 210 1545 14325 14550 user_canon\001
+4 0 0 50 0 18 18 0.0000 4 210 2520 14400 15150 canon_user_server\001
+4 0 0 50 0 18 18 0.0000 4 270 2415 14475 16875 canon_user_client\001
+-6
+6 14100 11175 17100 13500
+2 2 0 1 0 0 50 0 4 0.000 0 0 -1 0 0 5
+        14100 11175 17100 11175 17100 13500 14100 13500 14100 11175
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        16950 13275 16950 11925 14250 11925 14250 13275 16950 13275
+4 0 0 50 0 18 18 0.0000 4 210 1095 14325 11625 auxprop\001
+4 0 0 50 0 18 18 0.0000 4 270 2175 14475 12375 auxprop_lookup\001
+-6
+2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
+        11700 3000 11700 1200 8100 1200 8100 3000 11700 3000
+2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
+        11700 5400 11700 3600 8100 3600 8100 5400 11700 5400
+2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
+        11700 7800 11700 6000 8100 6000 8100 7800 11700 7800
+2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
+        11700 10200 11700 8400 8100 8400 8100 10200 11700 10200
+2 4 0 1 0 7 50 0 -1 0.000 0 0 7 0 0 5
+        11700 12300 11700 10800 8100 10800 8100 12300 11700 12300
+2 2 0 1 0 0 50 0 4 0.000 0 0 -1 0 0 5
+        4500 8700 7500 8700 7500 17175 4500 17175 4500 8700
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        7275 13050 7275 11475 4725 11475 4725 13050 7275 13050
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        7275 14925 7275 13350 4725 13350 4725 14925 7275 14925
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        7275 16800 7275 15225 4725 15225 4725 16800 7275 16800
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        7275 11025 7275 9450 4725 9450 4725 11025 7275 11025
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        11700 15000 11700 13200 8100 13200 8100 15000 11700 15000
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        7275 12000 8100 13725
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        11700 13800 14250 15000
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14250 15225 11700 14100
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        11700 14400 14250 12375
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14250 12675 11700 14700
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        8100 14100 7275 12375
+2 1 0 3 0 0 50 0 -1 0.000 0 0 7 1 1 2
+       0 0 3.00 180.00 360.00
+       0 0 3.00 180.00 360.00
+        8100 11400 7275 11925
+2 1 0 3 0 0 50 0 -1 0.000 0 0 7 1 1 2
+       0 0 3.00 180.00 360.00
+       0 0 3.00 180.00 360.00
+        8100 9300 7275 10200
+2 2 0 1 0 0 50 0 4 0.000 0 0 -1 0 0 5
+        14100 3600 17100 3600 17100 8700 14100 8700 14100 3600
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 4500 11700 2100
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 5100 11700 4500
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 5700 11700 6900
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 6600 11700 9300
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 7500 11700 11100
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 7800 11700 11400
+2 1 0 3 0 0 50 0 -1 0.000 0 0 -1 1 0 2
+       0 0 3.00 180.00 360.00
+        14100 8550 11700 12150
+2 4 0 1 0 0 50 0 -1 0.000 0 0 7 0 0 5
+        11625 17400 11625 15600 8100 15600 8100 17400 11625 17400
+4 0 0 50 0 18 18 0.0000 4 270 1575 4650 9150 server_plug\001
+4 0 0 50 0 18 18 0.0000 4 270 1590 4875 9825 mech_new()\001
+4 0 0 50 0 18 18 0.0000 4 270 1650 4875 11850 mech_step()\001
+4 0 0 50 0 18 18 0.0000 4 270 2145 4875 13800 mech_dispose()\001
+4 0 0 50 0 18 18 0.0000 4 270 1755 8400 13725 canon_user()\001
+4 0 0 50 0 18 18 0.0000 4 270 3105 8400 14415 [user information hook]\001
+4 0 0 50 0 18 18 0.0000 4 270 1470 14400 4050 application\001
+4 0 0 50 0 18 18 0.0000 4 45 225 12750 10125 ...\001
+4 0 0 50 0 18 18 0.0000 4 270 1965 8400 16125 sasl_dispose()\001
+4 0 0 50 0 18 18 0.0000 4 270 2445 8400 11400 sasl_server_step()\001
+4 0 0 50 0 18 18 0.0000 4 270 2445 8400 9000 sasl_server_start()\001
+4 0 0 50 0 18 18 0.0000 4 270 1980 8400 6600 sasl_listmech()\001
+4 0 0 50 0 18 18 0.0000 4 270 2385 8400 4200 sasl_server_new()\001
+4 0 0 50 0 18 18 0.0000 4 270 2265 8400 1725 sasl_server_init()\001
diff --git a/doc/sysadmin.html b/doc/sysadmin.html
new file mode 100644 (file)
index 0000000..63381ac
--- /dev/null
@@ -0,0 +1,502 @@
+<HTML><HEAD>
+<title>Cyrus SASL for System Administrators</title>
+<!-- $Id: sysadmin.html,v 1.50 2005/02/16 20:52:05 shadow Exp $ -->
+</HEAD>
+<BODY>
+<H1>Cyrus SASL for System Administrators</H1>
+
+This document covers configuring SASL for system administrators,
+specifically those administrators who are installing a server that
+uses the Cyrus SASL library.  You may want to read
+<a href=components.html>this document</a> which presents an
+overview of the major components of the Cyrus SASL distribution
+and describes how they interact, as well as <a href=install.html>
+the installation guide</a>.
+
+<h2><A NAME="saslintro">What SASL is</A></h2>
+
+SASL, the Simple Authentication and Security Layer, is a generic
+mechanism for protocols to accomplish authentication.  Since protocols
+(such as SMTP or IMAP) use SASL, it is a natural place for code
+sharing between applications.  Some notable applications that use the
+Cyrus SASL library include <a
+href="http://www.sendmail.org">Sendmail</a>,
+<a href="http://web.asg.cmu.edu/cyrus">Cyrus imapd</a>,
+and <a href="http://www.openldap.org">OpenLDAP</a>.
+
+<p> Applications use the SASL library to tell them how to accomplish
+the SASL protocol exchange, and what the results were.
+
+<p> SASL is only a framework: specific SASL mechanisms govern the
+exact protocol exchange.  If there are n protocols and m different
+ways of authenticating, SASL attempts to make it so only n plus m
+different specifications need be written instead of n times m
+different specifications.  With the Cyrus SASL library, the mechanisms
+need only be written once, and they'll work with all servers that use
+it.
+
+<h3><a name="authid">Authentication and authorization identifiers</a></h3>
+
+An important concept to become familiar with is the difference between
+an "authorization identifier" and an "authentication identifier".
+
+<DL compact>
+<DT>userid (user id, authorization id)<dd> The userid is the
+identifier an application uses to check allowable options.  On my Unix
+system, the user "<tt>bovik</tt>" (the account of Harry Q. Bovik) is
+allowed to write to "<tt>/home/bovik</tt>" and its subdirectories but
+not to "<tt>/etc</tt>".
+
+<DT>authid (authentication id)<dd> The authentication identifier is
+the identifier that is being checked.  "bovik"'s password might be
+"qqqq", and the system will authenticate anyone who knows "qqqq" as
+"bovik".  However, it's possible to authenticate as one user but
+<b>act as</b> another user.  For instance, Harry might be away on
+vacation and assign one of his graduate students, Jane, to read his
+mail.  He might then allow Jane to act as him merely by supplying her
+password and her id as authentication but requesting authorization as
+"bovik". So Jane might log in with an authentication identifier of
+"jane" and an authorization id of "bovik" and her own (Jane's)
+password.
+</DL>
+
+<p>Applications can set their own proxy policies; by default, the SASL
+library will only allow the same user to act for another (that is,
+userid must equal authid).  See your application's documentation for
+details about changing the default proxy/authorization policies.
+
+<h3><a name="realms">Realms</a></h3>
+
+The Cyrus SASL library supports the concept of "realms".  A realm is
+an abstract set of users and certain mechanisms authenticate users in
+a certain realm.
+
+<p>In the simplest case, a single server on a single machine, the
+realm might be the fully-qualified domain name of the server.  If the
+applications don't specify a realm to SASL, most mechanisms will
+default to this.
+
+<p> If a site wishes to share passwords between multiple machines, it
+might choose it's authentication realm as a domain name, such as
+"CMU.EDU".  On the other hand, in order to prevent the entire site's
+security from being compromised when one machine is compromised, each
+server could have it's own realm. Certain mechanisms force the user
+(client side) to manually configure what realm they're in, making it
+harder for users to authenticate.
+
+<p>A single site might support multiple different realms.  This can
+confuse applications that weren't written in anticipation of this; make
+sure your application can support it before adding users from different
+realms into your databases.
+
+<p>To add users of different realms to sasldb, you can use the
+<tt>-u</tt> option to saslpasswd2.  The SQL plugin has a way of
+integrating the realm name into the query string with the '%r' macro.
+
+<p>The Kerberos mechanisms treat the SASL realm as the Kerberos
+realm.  Thus, the realm for Kerberos mechanisms defaults to the
+default Kerberos realm on the server.  They may support cross-realm
+authentication; check your application on how it deals with this.
+
+<p>Realms will be passed to saslauthd as part of the saslauthd protocol,
+however the way each saslauthd module deals with the situation is
+different (for example, the LDAP plugin allows you to use the realm
+to query the server, while the rimap and PAM plugins ignore it entirely).
+
+<p>Realms are represented in a username string by any text followinhg
+the '@' sign.  So, usernames like rjs3@ANDREW.CMU.EDU, is user 'rjs3'
+in the realm 'ANDREW.CMU.EDU'.  If no realm is provided, the server's
+FQDN is assumed (likewise when specifying a realm for saslpasswd2).
+
+<h2><a name="saslhow">How SASL works</a></h2>
+
+How SASL works is governed by what mechanism the client and server 
+choose to use and the exact implementation of that mechanism.  This
+section describes the way these mechanisms act in the Cyrus SASL
+implementation.
+
+<h3>The PLAIN mechanism, <tt>sasl_checkpass()</tt>, and plaintext
+passwords</h3>
+
+The PLAIN mechanism is not a secure method of authentication by
+itself.  It is intended for connections that are being encrypted by
+another level.  (For example, the IMAP command "STARTTLS" creates an
+encrypted connection over which PLAIN might be used.) The PLAIN
+mechanism works by transmitting a userid, an authentication id, and a
+password to the server, and the server then determines whether that is
+an allowable triple.
+
+<p>The principal concern for system administrators is how the
+authentication identifier and password are verified.  The Cyrus SASL
+library is flexible in this regard:
+
+<DL>
+<dt><i>auxprop</i> 
+<dd> checks passwords agains the <tt>userPassword</tt> attribute
+supplied by an auxiliary property plugin.  For example, SASL ships
+with a sasldb auxiliary property plugin, that can be used to
+authenticate against the passwords stored in <tt>/etc/sasldb2</tt>.
+Since other mechanisms also use this database for passwords, using
+this method will allow SASL to provide a uniform password database to
+a large number of mechanisms.
+
+<dt><i>saslauthd</i>
+
+<dd> contacts the <tt>saslauthd</tt> daemon to to check passwords
+using a variety of mechanisms.  More information about the various invocations
+of saslauthd can be can be found in <tt>saslauthd(8)</tt>.  Generally you
+want something like <tt>saslauthd -a pam</tt>.  If plaintext authentications
+seem to be taking some time under load, increasing the value of the <tt>-n</tt>
+parameter can help.<p>
+
+Saslauthd keeps its named socket in "/var/state/saslauthd" by default.
+This can be overridden by specifying an alternate value to
+--with-saslauthd=/foo/bar at compile time, or by passing the -m
+parameter to saslauthd (along with setting the saslauthd_path SASL
+option).  Whatever directory this is, it must exist in order for
+saslauthd to function.<p>
+
+Once you configure (and start) <tt>saslauthd</tt>, there is a
+<tt>testsaslauthd</tt> program that can be built with <tt>make
+testsaslauthd</tt> in the <tt>saslauthd</tt> subdirectory of the
+source.  This can be used to check that that the <tt>saslauthd</tt>
+daemon is installed and running properly.  An invocation like
+<tt>testsaslauthd -u rjs3 -p 1234</tt> with appropriate values for the
+username and password should do the trick.<p>
+
+If you are using the PAM method to verify passwords with saslauthd, keep in
+mind that your PAM configuration will need to be configured for each service
+name that is using saslauthd for authentication. Common service names
+are &quot;imap&quot;, &quot;sieve&quot;, and &quot;smtp&quot;.
+
+<dt><i>Courier-IMAP authdaemond</i>
+
+<dd> contacts Courier-IMAP's <tt>authdaemond</tt> daemon to check passwords.
+This daemon is simliar in functionality to <tt>saslauthd</tt>, and is shipped
+separately with the <a href="http://www.courier-mta.org">Courier</a> mail server.
+
+<p>Note: this feature is <b>not</b> compiled in the library by default, and its 
+provided for sites with custom/special requirements only (because the
+internal authentication protocol its not documented anywhere so it could
+change at any time).  We have tested against the authdaemond included with
+Courier-IMAP 2.2.1.
+
+<p>To enable <tt>authdaemond</tt> support, pass <tt>--with-authdaemon</tt> to the 
+configuration script, set pwcheck_method to ``authdaemond'' and point 
+authdaemon_path to <tt>authdaemond</tt>'s unix socket. Optionally, you can
+specify --with-authdaemond=PATH to the configure script so that
+authdaemond_path points to a default, static, location.
+
+<dt><i>pwcheck</i>
+
+<dd> checks passwords with the use of a separate,
+  helper daemon.  This feature is for backwards-compatibility
+  only. New installations should use saslauthd.<p>
+
+<dt><i>write your own</i>
+<dd> Last, but not least, the most flexible method of authentication
+for PLAIN is to write your own.  If you do so, any application that
+calls the "<tt>sasl_checkpass()</tt>" routine or uses PLAIN will
+invoke your code.  The easiest place to modify the plaintext
+authentication routines is to modify the routine
+"<tt>_sasl_checkpass()</tt>" in the file <tt>lib/server.c</tt> to
+support a new method, and to add that method to
+<tt>lib/checkpw.c</tt>.  Be sure to add a prototype in
+<tt>lib/saslint.h</tt>!
+
+<p>However, the more flexible and preferred method of
+adding a routine is to create a new saslauthd mechanism.<p> </dl>
+
+<p>The LOGIN mechanism (not to be confused with IMAP4's LOGIN command)
+is an undocumented, unsupported mechanism.  It's included in the Cyrus
+SASL distribution for the sake of SMTP servers that might want to
+interoperate with old clients.  Do not enable this mechanism unless
+you know you're going to need it.  When enabled, it verifies passwords
+the same way the PLAIN mechanism does.
+
+<h3>Shared secrets mechanisms</h3>
+
+The Cyrus SASL library also supports some "shared secret"
+authentication methods: CRAM-MD5 and its successor DIGEST-MD5.  These
+methods rely on the client and the server sharing a "secret", usually
+a password.  The server generates a challenge and the client a
+response proving that it knows the shared secret.  This is much more
+secure than simply sending the secret over the wire proving that the
+client knows it.
+
+<p>There's a downside: in order to verify such responses, the
+server must keep passwords or password equivalents in a database;
+if this database is compromised, it is the same as if all the
+passwords for the realm are compromised.
+
+<p>Put another way, <i>you cannot use saslauthd with these methods</i>.  
+If you do not wish to advertise these methods for that reason (i.e. you
+are only using saslauthd for password verification), then either remove
+the non-plaintext plugins (those other than login and plain) from the
+plugin directory, or use the <tt>mech_list</tt> option to disable them.
+
+<p>For simplicity sake, the Cyrus SASL library stores plaintext
+passwords only in the <tt>/etc/sasldb2</tt> database.  These passwords
+are then shared among all mechanisms which choose to use it.
+Depending on the exact database method
+used (gdbm, ndbm, or db) the file may have different suffixes or may
+even have two different files ("<tt>sasldb.dir</tt>" and
+"<tt>sasldb.pag</tt>").  It is also possible for a server to define
+it's own way of storing authentication secrets.  Currently, no
+application is known to do this.
+
+<p>The principle problem for a system administrator is to make sure that
+sasldb is properly protected. Only the servers that need to read it to
+verify passwords should be able to.  If there are any normal shell
+users on the system, they must not be able to read it.
+
+<p>This point is important, so we will repeat it: <b>sasldb stores the
+plaintext versions of all of its passwords. If it is compromised so
+are all of the passwords that it stores</b>.
+
+<p>Managing password changes is outside the scope of the library.
+However, system administrators should probably make a way of letting
+user's change their passwords available to users.  The
+"<tt>saslpasswd2</tt>" utility is provided to change the secrets in
+sasldb.  It does not affect PAM, <tt>/etc/passwd</tt>, or any other
+standard system library; it only affects secrets stored in sasldb.
+
+<p>Finally, system administrators should think if they want to enable
+"auto_transition".  If set, the library will automatically create
+secrets in sasldb when a user uses PLAIN to successfully authenticate.
+However, this means that the individual servers, such as imapd, need
+read/write access to sasldb, not just read access.  By default,
+"auto_transition" is set to false; set it to true to enable.  (There's
+no point in enabling this option if "pwcheck_method" is "auxprop",
+and the sasldb plugin is installed, since you'll be transitioning from
+a plaintext store to a plaintext store)
+
+<h3>Kerberos mechanisms</h3>
+
+The Cyrus SASL library also comes with two mechanisms that make use of
+Kerberos: KERBEROS_V4, which should be able to use any Kerberos v4
+implementation, and GSSAPI (tested against MIT Kerberos 5, Heimdal
+Kerberos 5 and CyberSafe Kerberos 5).  These mechanisms make use of the kerberos infrastructure
+and thus have no password database.
+
+<p>Applications that wish to use a kerberos mechanism will need access
+to a service key, stored either in a "srvtab" file (Kerberos 4) or a
+"keytab" file (Kerberos 5).  Currently, the keytab file location is
+not configurable and defaults to the system default (probably
+<tt>/etc/krb5.keytab</tt>).
+
+<p>The Kerberos 4 srvtab file location is configurable; by default it is
+<tt>/etc/srvtab</tt>, but this is modifiable by the "srvtab" option.
+Different SASL applications can use different srvtab files.
+
+<p>A SASL application must be able to read its srvtab or keytab file.
+
+<p>You may want to consult the <a href="gssapi.html">GSSAPI Tutorial</a>.</p>
+
+<h3>The OTP mechanism</h3>
+
+The Cyrus SASL library also supports the One-Time-Password (OTP)
+mechanism.  This mechanism is similar to CRAM-MD5 and DIGEST-MD5 in
+that is uses a shared secret and a challenge/response exchange.
+However, OTP is more secure than the other shared secret mechanisms in
+that the secret is used to generate a sequence of one-time (single
+use) passwords which prevents reply attacks, and that secret need
+not be stored on the system.  These one-time passwords are stored in the
+<tt>/etc/sasldb2</tt> database.  See the <i>Shared secrets
+mechanisms</i> section for a discussion of the <tt>/etc/sasldb2</tt>
+database.
+
+<h4>OTP via OPIE</h4>
+For sites with an existing OTP infrastructure using OPIE, Cyrus SASL
+can be configured to use OPIE v2.4 instead of using its own database
+and server-side routines.
+OPIE should be configured with the <tt>--disable-user-locking</tt> 
+option if the SASL server application will not be running as "root". 
+
+<p>OPIE uses its own "opiekeys" database for storing the data necessary
+for generating the server challenges.  The location of the opiekeys
+file is configurable in SASL; by default it is <tt>/etc/opiekeys</tt>,
+but this is modifiable by the "opiekeys" option.
+
+<p>A SASL server application must be able to read and write the
+opiekeys file.
+
+<h2>Auxiliary Properties</h2>
+
+SASLv2 introduces the concept of Auxilliary Properties.  That is, the ability
+for information related to authentication and authorization to all be looked
+up at once from a directory during the authentication process.  SASL Plugins
+internally take advantage of this to do password lookups in directories
+such as the SASLdb, LDAP or a SQL database.  Applications can look up arbitrary properties through them.<p>
+
+Note that this means that if your password database is in a SASLdb, and
+you wish to use it for plaintext password lookups through the sasldb, you
+will need to set the sasl <a href=options.html>option</a>
+<tt>pwcheck_method</tt> to be <tt>auxprop</tt>. 
+
+<h2>How to set configuration options</h2>
+
+The Cyrus SASL library comes with a built-in configuration file
+reader.  However, it is also possible for applications to redefine
+where the library gets it's configuration options from.
+
+<h3><a name="saslconf">The default configuration file</a></h3>
+
+<p>By default, the Cyrus SASL library reads it's options from
+<tt>/usr/lib/sasl2/App.conf</tt> (where "App" is the application
+defined name of the application).  For instance, Sendmail reads it's
+configuration from "<tt>/usr/lib/sasl2/Sendmail.conf</tt>" and the
+sample server application included with the library looks in
+"<tt>/usr/lib/sasl2/sample.conf</tt>".
+
+<p>A standard Cyrus SASL configuration file looks like: 
+<pre>
+srvtab: /var/app/srvtab
+pwcheck_method: saslauthd
+</pre>
+
+<h3>Application configuration</h3>
+
+Applications can redefine how the SASL library looks for configuration
+information.  Check your application's documentation for specifics.
+
+<p>For instance, Cyrus imapd reads its sasl options from it's own
+configuration file, <tt>/etc/imapd.conf</tt>, by prepending all SASL
+options with "<tt>sasl_</tt>": the SASL option "pwcheck_method" is set
+by changing "sasl_pwcheck_method" in <tt>/etc/imapd.conf</tt>.
+
+<h2>Troubleshooting</h2>
+
+<dl compact>
+<dt><b>Q:</b> Why doesn't KERBEROS_V4 doesn't appear as an
+available mechanism?
+<dd>
+<p><b>A:</b> Check that the <tt>srvtab</tt> file is readable by the
+user running as the daemon.  For Cyrus imapd, it must be readable by
+the Cyrus user.  By default, the library looks for the srvtab in
+<tt>/etc/srvtab</tt>, but it's configurable using the <tt>srvtab</tt>
+option.
+
+<p>
+<dt><b>Q:</b> Why doesn't OTP doesn't appear as an available
+mechanism?
+<dd>
+<p><b>A:</b> If using OPIE, check that the <tt>opiekeys</tt> file is
+readable by the user running the daemon.  For Cyrus imapd, it must
+be readable by the Cyrus user.  By default, the library looks for the
+opiekeys in <tt>/etc/opiekeys</tt>, but it's configurable using the
+<tt>opiekeys</tt> option.
+
+<p>
+<dt><b>Q:</b> Why don't CRAM-MD5 and DIGEST-MD5 work with my old sasldb?
+<dd>
+<p><b>A:</b> Because sasldb now stores plaintext passwords only, the old
+sasldb is completely incompatible.
+
+<p>
+<dt><b>Q:</b> I'm having performance problems on each authentication, there is
+a noticeable slowdown when sasl initializes, what can I do?
+<dd>
+<p><b>A:</b>libsasl reads from <tt>/dev/random</tt> as part of its
+initialization. <tt>/dev/random</tt> is a "secure" source of entropy,
+and will block your application until a sufficient amount of
+randomness has been collected to meet libsasl's needs.</p>
+
+<p>To improve performance, you can change DEV_RANDOM in
+<tt>config.h</tt> to be <tt>/dev/urandom</tt> and recompile
+libsasl. <tt>/dev/urandom</tt> offers less secure random numbers but
+should return immediately. The included mechanisms, besides OTP and
+SRP, use random numbers only to generate nonces, so using
+<tt>/dev/urandom</tt> is safe if you aren't using OTP or SRP.
+
+<p>
+<dt><b>Q:</b> I've converted the sasldb database to the new format. 
+Why can't anybody authenticate?
+<dd>
+<p><b>A:</b> sasldb is now a plugin module for the auxprop method.
+Make sure you changed the /usr/lib/sasl2/*.conf files to reflect<br>
+<tt>pwcheck_method: auxprop</tt><br>
+<br>
+...and if you're using cyrus-imapd, /etc/imapd.conf must reflect:
+<tt>sasl_pwcheck_method: auxprop</tt>
+
+<p>
+<dt><b>Q:</b> Is LOGIN supported?
+<dd>
+<p><b>A:</b> The LOGIN mechanism is a non-standard, undocumented
+plaintext mechanism.  It's included in the SASL distribution purely
+for sites that need it to interoperate with old clients; we don't
+support it.  Don't enable it unless you know you need it.
+
+<p>
+<dt><b>Q:</b> Is NTLM supported?
+<dd>
+<p><b>A:</b> The NTLM mechanism is a non-standard, undocumented
+mechanism developed by Microsoft.  It's included in the SASL
+distribution purely for sites that need it to interoperate with
+Microsoft clients (ie, Outlook) and/or servers (ie, Exchange); we
+don't support it.  Don't enable it unless you know you need it.
+
+<p>
+<dt><b>Q:</b> How can I get a non-root application to check plaintext
+passwords?
+<dd>
+<p><b>A:</b> Use the "saslauthd" daemon and setting "pwcheck_method"
+to "saslauthd".
+
+<p>
+<dt><b>Q:</b> I want to use Berkeley DB, but it's installed in
+<tt>/usr/local/BerkeleyDB.3.1</tt> and <tt>configure</tt> can't find
+it.
+<dd>
+<p><b>A:</b> Try setting "CPPFLAGS" and "LDFLAGS" environment
+variables before running <tt>configure</tt>, like so:
+<pre>
+env CPPFLAGS="-I/usr/local/BerkeleyDB.3.1/include" \
+  LDFLAGS="-L/usr/local/BerkeleyDB.3.1/lib -R/usr/local/BerkeleyDB.3.1/lib" \
+  ./configure --with-dblib=berkeley 
+</pre>
+
+<p>
+<dt><b>Q:</b> It's not working and won't tell me why! Help!
+<dd>
+<p><b>A:</b> Check syslog output (usually stored in
+<tt>/var/log</tt>) for more information. You might want to change your
+syslog configuration (usually <tt>/etc/syslogd.conf</tt>) to log
+"debug.*" to a file while debugging a problem.</p>
+
+<p>The developers make heavy use of <tt>strace</tt> or <tt>truss</tt>
+when debugging a problem that isn't outputting any useful
+information.</p>
+
+<p>
+<dt><b>Q:</b> Is there a mailing list to discuss the Cyrus SASL
+library?
+<dd>
+<p><b>A:</b> <tt>cyrus-sasl@lists.andrew.cmu.edu</tt> is available for
+discussion.  To subscribe, send a message to
+<a href=
+"mailto:majordomo@lists.andrew.cmu.edu?subject=subscribe cyrus-sasl">
+<tt>majordomo@lists.andrew.cmu.edu</tt></a>
+with the body of 'subscribe cyrus-sasl'.
+
+<p> An archive is available via
+<ul>
+ <li> anonymous IMAP at <a
+href="imap://cyrus.andrew.cmu.edu/archive.cyrus-sasl">imap://cyrus.andrew.cmu.edu/archive.cyrus-sasl</a>.
+  <li> HTTP at <a
+href="http://asg.web.cmu.edu/archive/mailbox.php3?mailbox=archive.cyrus-sasl">
+http://asg.web.cmu.edu/archive/mailbox.php3?mailbox=archive.cyrus-sasl</a>
+</ul>
+
+<p>Note: If you are not subscribed, your posts go through human
+approval before they go out to the list and so posting may be
+(greatly) delayed.
+</dl>
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
+
diff --git a/doc/testing.txt b/doc/testing.txt
new file mode 100644 (file)
index 0000000..d182dd1
--- /dev/null
@@ -0,0 +1,84 @@
+** This document is mainly useful for people doing libsasl development
+   or users having a lot of difficulty getting libsasl to work.
+
+Testing the CMU SASL Library with the included sample applications
+##################################################################
+
+The CMU SASL library comes with two small sample programs:
+sample-client and sample-server.  Each of these programs dump base-64
+SASL iterations to STDOUT, and read the next iteration from STDIN.
+Lines preceded by "C: " are from the client, and from "S: " are from
+the server.
+
+This makes it fairly straightforward to test mechanisms; simply run
+the sample-client on the "client" machine, and sample-server on the
+"server" machine.
+
+Both programs take a -m MECH command line argument; this can be used
+to force the mechanism used in the exchange.  KERBEROS_V4 requires
+that the IP addresses of both client and server be set, along with the
+service name, and the server's fully-qualified hostname; these are
+done through more command line arguments.
+
+Example:
+
+Here's the client side of an exchange.  The mechanism selection code
+chooses KERBEROS_V4; negotiation takes place, and the client is
+authenticated.  This is being run on the machine SPOOKY.ANDREW.CMU.EDU
+(128.2.121.162), pretending to be talking to an "rcmd" service running
+on port 23 (note the semicolons in the IP address.  There is a strong
+chance these will need to be escaped for proper interpretation by the shell):
+
+> ./sample-client -i local=128.2.121.162;23,remote=128.2.121.162;23 -s rcmd -n SPOOKY.ANDREW.CMU.EDU
+Waiting for mechanism list from server...
+S: UExBSU4gQU5PTllNT1VTIEtFUkJFUk9TX1Y0IERJR0VTVC1NRDUgQ1JBTS1NRDUgAAAAAED5EEA=
+Choosing best mechanism from: PLAIN ANONYMOUS KERBEROS_V4 DIGEST-MD5 CRAM-MD5 
+Using mechanism KERBEROS_V4
+Preparing initial.
+Sending initial response...
+C: S0VSQkVST1NfVjQA
+Waiting for server reply...
+S: hVQFjA==
+Sending response...
+C: BAYCQU5EUkVXLkNNVS5FRFUAOCDnIsZLQRdjLHXvzPNgpURYVj1iMqBIcTRaMpEQ8vWeYnfB+mTCVEa2URpkVgpzS1161MAX7ERzFV/EfGKlrAhGJCdN56mQ3eL2PzJlK7Z9ctKv4gKErcmV
+Waiting for server reply...
+S: BgcvFb63CLs=
+Sending response...
+C: ohBT+Jqab9zmDzclN7GSTw==
+Negotiation complete
+>
+
+
+Here's the server side of the same dialog:
+
+
+> ./sample-server -s rcmd -i local=128.2.121.162;23,remote=128.2.121.162;23
+Generating client mechanism list...
+Sending list of 5 mechanism(s)
+S: UExBSU4gQU5PTllNT1VTIEtFUkJFUk9TX1Y0IERJR0VTVC1NRDUgQ1JBTS1NRDUgAAAAAED5EEA=
+Waiting for client mechanism...
+C: S0VSQkVST1NfVjQA
+Sending response...
+S: hVQFjA==
+Waiting for client reply...
+C: BAYCQU5EUkVXLkNNVS5FRFUAOCDnIsZLQRdjLHXvzPNgpURYVj1iMqBIcTRaMpEQ8vWeYnfB+mTCVEa2URpkVgpzS1161MAX7ERzFV/EfGKlrAhGJCdN56mQ3eL2PzJlK7Z9ctKv4gKErcmV
+Sending response...
+S: BgcvFb63CLs=
+Waiting for client reply...
+C: ohBT+Jqab9zmDzclN7GSTw==
+Negotiation complete
+Username: rob
+Realm: ANDREW.CMU.EDU
+SSF: 56
+> 
+
+
+Running the Testsuite application
+#################################
+
+The Testsuite application in the utils directory trys out all the
+functionality of libsasl against itself. When you run the application
+it displays some requirments for running, such as being able to read
+and write to the sasldb file. If this program is set up correctly and
+still fails we'd like to hear about it at cyrus-bugs@andrew.cmu.edu.
+
diff --git a/doc/upgrading.html b/doc/upgrading.html
new file mode 100644 (file)
index 0000000..41895a0
--- /dev/null
@@ -0,0 +1,96 @@
+<HTML><HEAD>
+<title>Upgrading from Cyrus SASLv1 to Cyrus SASLv2</title>
+<!-- $Id: upgrading.html,v 1.12 2003/08/14 21:04:13 rjs3 Exp $ -->
+</HEAD>
+<BODY>
+<H1>Upgrading from Cyrus SASLv1 to Cyrus SASLv2</H1>
+
+This document covers issues with upgrading from SASLv1 to SASLv2.
+To upgrade:
+
+<ul>
+<li> Install Cyrus SASL v2 as normal according to <a
+href="install.html">the installation guide</a>.  This will overwrite
+some manpages, but will not affect your current applications.  Do NOT
+attempt to make it use the same directories, otherwise old Cyrus SASLv1
+applications will no longer function.</li>
+
+<li> Install your new Cyrus SASL v2 applications. Applications that
+use Cyrus SASLv1 will <em>not</em> use the Cyrus SASL v2
+infrastructure (and vice-versa).
+
+<li> If you used <tt>/etc/sasldb</tt> for authentication, you'll need
+to take the following steps to convert to using <tt>/etc/sasldb2</tt>
+with Cyrus SASL v2:
+      <ol>
+      <li> run <tt>utils/dbconverter-2</tt> after installation.</li>
+      <li> change the <tt>pwcheck_method</tt> in any config files to
+      <tt>auxprop</tt></li> 
+      <li> (optional) add <tt>auxprop_plugin</tt> to the config files,
+      set to <tt>sasldb</tt></li>
+      </ol>
+
+<li> If you used <tt>passwd</tt>, <tt>shadow</tt>, <tt>pam</tt>,
+<tt>kerberos_v4</tt> or <tt>sia</tt> as your <tt>pwcheck_method</tt>
+in libsasl v1, you'll need to convert to using
+<tt>saslauthd</tt>. Arrange to start <tt>saslauthd -a
+<i>method</i></tt> on boot. Change <tt>pwcheck_method</tt> in any
+configuration files to <tt>saslauthd</tt>.</li>
+
+<li> If you used <tt>pwcheck</tt> with libsasl v1, you can either
+continue to use <tt>pwcheck</tt> with libsasl v1 or you can switch to
+<tt>saslauthd</tt>, which offers more flexibility and a potentially
+much more efficient implementation.</li>
+
+<li> If you are continuing to use some libsasl v1 applications, read
+onwards to understand the ramifications.</li>
+
+<li> If you want to learn how to port applications from libsasl v1 to
+libsasl v2, you should read <A HREF=appconvert.html>this document</A>.
+</ul>
+
+<h2><A NAME="overview">Backwards Compatibility</A></h2>
+
+Cyrus SASLv2 is completely incompatible with applications that use
+Cyrus SASLv1.  This means that applications are unable to
+simultaneously link both versions of the library, and developers are
+encouraged to instead develop or upgrade their applications to link
+against the new libsasl.<p>
+
+Likewise, the format for the sasldb database has been completely
+revamped.  See <A HREF="#db">here</A> for a discussion of the relevant
+upgrade issues related to sasldb.  All new passwords stored in the
+sasldb database will be in plaintext, meaning that a compromised
+sasldb will compromise all services with the same passwords.  (This
+situation isn't significantly worse, cryptographicly speaking, than
+the old method and allows the database to be easy to transition to
+another format, when the need arises.)  Mechanisms requiring a more
+secure password database backend (e.g. SRP) should implement their own
+or use alternate property names within sasldb.<P>
+
+<h2><A NAME="coexist">Coexistence with SASLv1</A></h2>
+
+The two library versions and the associated utilities should be able
+to coexist on the same system.  The man pages will be unable to
+coexist (but luckily the new manpages are much better!).  The libsasl
+v2-specific utilities have had a "2" appended to their name for this
+purpose (e.g. <tt>saslpasswd2</tt>, <tt>sasldblistusers2</tt>).  The
+new-style sasldb now defaults to the name <tt>/etc/sasldb2</tt>, but
+this is configurable.
+
+<h2><A NAME="db">Database Upgrades</A></h2>
+
+While there does not seem to be any conflict with the keys stored in
+the database, it is not recommended for both versions of the library
+to use the same database file.  Included in the utils directory is a
+program called <tt>dbconverter-2</tt> which will allow you to convert
+from the old-format database to the new format.  Note that if you continue to
+run older applications that rely on Cyrus SASLv1, the databases for SASLv1
+and SASLv2 will not automatically be kept in sync.<p>
+
+<hr>
+Back to the <A href=index.html>index</a>
+
+</body>
+</html>
+
diff --git a/doc/windows.html b/doc/windows.html
new file mode 100755 (executable)
index 0000000..48788c4
--- /dev/null
@@ -0,0 +1,180 @@
+<html><head>
+<title>Building Cyrus SASL on Windows</title>
+
+</head>
+
+<body>
+<h1>Building Cyrus SASL on Windows</h1>
+
+Note, that Cyrus SASL on Windows is still laregely a "work in progress".
+So far only the main library, plugins (SASLDB using SleepyCat, no MySQL)
+and several applications (see the list below) can be built. In particular,
+saslauthd doesn't compile on Windows.
+
+<h2>Prerequisites</h2>
+
+<ul>
+<li>Visual Studio. We have tested Visual Studio 6 and Visual Studio 7 (.NET).
+By default we are using Visual Studio 7 (both 2002 and 2003 versions were tested). If you want to use Visual Studio 6,
+you need to remove the leading # character from the line containing "<tt>#VCVER=6</tt>" in win32/common.mak.
+
+<li>The latest Platform SDK. We are currently using March 2006. (The earliest tested version was November 2001.)
+
+<li>SleepyCat include files and libraries are required to buil SASLDB plugin,
+saslpasswd2.exe and sasldblistusers2.exe. We have tested SleepyCat 4.1.X-4.4.X.
+
+<li>If you are building directly from CVS, you'll need the <a
+href="http://www.cygwin.com/">Cygwin</a> Unix-compatibility
+environment to create the <tt>_init.c</tt> files needed for dynamic
+loading. Cygwin is <em>not</em> required for building from our tar
+distribution.  
+
+</ul>
+
+<h2>Step by step</h2>
+
+These directions assume that you've untarred the library or used CVS
+and the sources are in <tt>C:\SASL</tt>.
+
+<h3>preparing to build (cvs only!)</h3>
+
+Start a cygwin shell and create the dynamic loading stubs:
+
+<pre>
+% cd /cygdrive/c/sasl/plugins
+% sh makeinit.sh
+</pre>
+
+<h3>building using NMake</h3>
+
+Open a "Windows 2000 build environment" from the SDK's Start Menu and
+use "<tt>nmake /f NTMakefile</tt>" to build.
+
+<p>To build a debug verison, use "<tt>nmake /f NTMakefile
+CFG=Debug</tt>". For a production version, "<tt>nmake /f NTMakefile
+CFG=Release</tt>". If you don't specify CFG parameter, production
+version will be built by default.
+
+<p>As Windows build requires SleepyCat, there are additional options
+that has to be provided to NMake on the command line.
+If SleepyCat sources are located in <tt>c:\packages\db\4.1.24</tt>
+and built library in <tt>c:\packages\db\4.1.24\build_win32\Release_static</tt>,
+you should add something like
+<tt>DB_INCLUDE=c:\packages\db\4.1.24\build_win32</tt>
+and <tt>DB_LIBPATH=c:\packages\db\4.1.24\build_win32\Release_static</tt>.
+<br>Also note, that the <tt>DB_LIB</tt> defines the name of the SleepyCat library
+to link against. It defaults to libdb41s.lib.
+<br>If you don't pass the parameters described above, NMake will pick the
+defaults, which is probably not what you want. 
+
+<p>Another option of interest is <tt>STATIC</tt>.
+It specifies which version of the standard C library
+to use. The default is "no", meaning that the standard C library
+from the MSVCRT.DLL will be used.
+
+<p>Example:
+<pre>
+Targeting Windows 2000 and IE 5.0 RETAIL
+
+C:\Program Files\Microsoft SDK> cd \sasl
+
+C:\sasl> nmake /f NTMakefile DB_INCLUDE=c:\packages\db\4.1.24\build_win32
+DB_LIBPATH=c:\packages\db\4.1.24\build_win32\Release_static
+
+No configuration specified. Defaulting to Release.
+Using MSVCRT.dll as C library by default.
+Defaulting SleepyCat library name to libdb41s.lib.
+Codegeneration defaulting to /MD.
+...
+
+</pre>
+
+<p>SASL NTMakefile also understands "clean" target that you can use to clean all files generated by the compiler.
+
+<pre>
+C:\sasl> nmake /f NTMakefile clean
+
+Microsoft (R) Program Maintenance Utility Version 7.00.9466
+Copyright (C) Microsoft Corporation.  All rights reserved.
+
+        cd lib && nmake /f NTMakefile                    clean
+
+Microsoft (R) Program Maintenance Utility Version 7.00.9466
+Copyright (C) Microsoft Corporation.  All rights reserved.
+
+No configuration specified. Defaulting to Release.
+Using MSVCRT.dll as C library by default.
+Defaulting SleepyCat library name to libdb41s.lib.
+Defaulting SleepyCat include path to c:\work\isode\db\build_win32.
+Defaulting SleepyCat library path to c:\work\isode\db\build_win32\Release_static.
+...
+
+</pre>
+
+<h3>building additional plugins</h3>
+
+<p>Specify "GSSAPI=&lt;type&gt;" parameter if you want to enable GSSAPI plugin.
+Currently only &lt;type&gt;=CyberSafe is supported and this will build the plugin
+that links against CyberSafe Kerberos.
+
+GSSAPI depends on <tt>GSSAPI_INCLUDE</tt> and <tt>GSSAPI_LIBPATH</tt> parameters.
+You can either specify them on the command line or edit the defaults in win32\common.mak
+
+<p>Specify "SQL=&lt;type&gt;" parameter if you want to enable SQL plugin.
+Currently only &lt;type&gt;=SQLITE is supported and this will build the plugin
+that links against SQLITE (www.sqlite.org).
+
+SQL=&lt;SQLITE&gt; depends on <tt>SQLITE_INCLUDES</tt> and <tt>SQLITE_LIBPATH</tt> parameters.
+You can either specify them on the command line or edit the defaults in win32\common.mak
+
+<p>Specify "NTLM=1" parameter if you want to enable NTLM plugin.
+I.e. "<tt>nmake /f NTMakefile NTLM=1</tt>"
+
+<p>Specify "SRP=1" parameter if you want to enable SRP plugin.
+You can also specify "DO_SRP_SETPASS=1" if you want to enable SRP setpass functionality.
+
+<p>Specify "OTP=1" parameter if you want to enable OTP plugin.
+
+<p>NTLM, SRP and OTP plugins depend on OpenSSL. You can either specify
+<tt>OPENSSL_INCLUDE</tt> and <tt>OPENSSL_LIBPATH</tt> parameters on the command
+line or edit the defaults in win32\common.mak
+Note, that unless you are building one of those plugins, OpenSSL is not required!
+
+<p>If you want to build multiple additional plugins at once, you can specify
+multiple parameters described above, for example "<tt>nmake /f NTMakefile NTLM=1 SRP=1 OPT=1</tt>"
+
+<h3>limitations</h3>
+
+Currently all plugins but KerberosV4 (kerberos4.c) and PASSDSS (passdss.c) can be built on Windows.
+However limited testings was done for some plugins as listed below:
+
+<ul>
+<li>GSSAPI - tested using CyberSafe,
+<li>SASLDB - only SleepyCat version can be built,
+<li>SQL - using SQLITE, not tested
+</ul>
+
+The following executables were built and tested (to some extend):
+In sample:
+<ul>
+<li>sample-client
+<li>sample-server
+</ul>
+In utils:
+<ul>
+<li>sasldblistusers2
+<li>saslpasswd2
+<li>testsuite
+<li>pluginviewer
+</ul>
+
+Note that saslauthd is <em>NOT</em> in this list.
+
+<h3>testing</h3>
+
+
+<h3>creating an MSI</h3>
+
+</body>
+
+</html>
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644 (file)
index 0000000..5ea5be2
--- /dev/null
@@ -0,0 +1,65 @@
+# Makefile.am for SASL includes
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+noinst_HEADERS = gai.h exits.h
+
+saslincludedir = $(includedir)/sasl
+saslinclude_HEADERS = hmac-md5.h md5.h md5global.h sasl.h saslplug.h saslutil.h prop.h
+
+noinst_PROGRAMS = makemd5
+
+makemd5_SOURCES = makemd5.c
+
+md5global.h: makemd5
+       -rm -f md5global.h
+       ./makemd5 md5global.h
+
+EXTRA_DIST = NTMakefile
+DISTCLEANFILES = md5global.h
+
+if MACOSX
+framedir = /Library/Frameworks/SASL2.framework
+frameheaderdir = $(framedir)/Versions/A/Headers
+frameheader_DATA = $(saslinclude_HEADERS)
+endif
diff --git a/include/Makefile.in b/include/Makefile.in
new file mode 100644 (file)
index 0000000..dce741e
--- /dev/null
@@ -0,0 +1,577 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for SASL includes
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+noinst_HEADERS = gai.h exits.h
+
+saslincludedir = $(includedir)/sasl
+saslinclude_HEADERS = hmac-md5.h md5.h md5global.h sasl.h saslplug.h saslutil.h prop.h
+
+noinst_PROGRAMS = makemd5
+
+makemd5_SOURCES = makemd5.c
+
+EXTRA_DIST = NTMakefile
+DISTCLEANFILES = md5global.h
+
+@MACOSX_TRUE@framedir = /Library/Frameworks/SASL2.framework
+@MACOSX_TRUE@frameheaderdir = $(framedir)/Versions/A/Headers
+@MACOSX_TRUE@frameheader_DATA = $(saslinclude_HEADERS)
+subdir = include
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+noinst_PROGRAMS = makemd5$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+am_makemd5_OBJECTS = makemd5.$(OBJEXT)
+makemd5_OBJECTS = $(am_makemd5_OBJECTS)
+makemd5_LDADD = $(LDADD)
+makemd5_DEPENDENCIES =
+makemd5_LDFLAGS =
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/makemd5.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(makemd5_SOURCES)
+DATA = $(frameheader_DATA)
+
+HEADERS = $(noinst_HEADERS) $(saslinclude_HEADERS)
+
+DIST_COMMON = $(noinst_HEADERS) $(saslinclude_HEADERS) \
+       $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(makemd5_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  include/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstPROGRAMS:
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+makemd5$(EXEEXT): $(makemd5_OBJECTS) $(makemd5_DEPENDENCIES) 
+       @rm -f makemd5$(EXEEXT)
+       $(LINK) $(makemd5_LDFLAGS) $(makemd5_OBJECTS) $(makemd5_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makemd5.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+frameheaderDATA_INSTALL = $(INSTALL_DATA)
+install-frameheaderDATA: $(frameheader_DATA)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(frameheaderdir)
+       @list='$(frameheader_DATA)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(frameheaderDATA_INSTALL) $$d$$p $(DESTDIR)$(frameheaderdir)/$$f"; \
+         $(frameheaderDATA_INSTALL) $$d$$p $(DESTDIR)$(frameheaderdir)/$$f; \
+       done
+
+uninstall-frameheaderDATA:
+       @$(NORMAL_UNINSTALL)
+       @list='$(frameheader_DATA)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f $(DESTDIR)$(frameheaderdir)/$$f"; \
+         rm -f $(DESTDIR)$(frameheaderdir)/$$f; \
+       done
+saslincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+install-saslincludeHEADERS: $(saslinclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(saslincludedir)
+       @list='$(saslinclude_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(saslincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(saslincludedir)/$$f"; \
+         $(saslincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(saslincludedir)/$$f; \
+       done
+
+uninstall-saslincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(saslinclude_HEADERS)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f $(DESTDIR)$(saslincludedir)/$$f"; \
+         rm -f $(DESTDIR)$(saslincludedir)/$$f; \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA) $(HEADERS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(frameheaderdir) $(DESTDIR)$(saslincludedir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+       -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-frameheaderDATA install-saslincludeHEADERS
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-frameheaderDATA uninstall-info-am \
+       uninstall-saslincludeHEADERS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstPROGRAMS ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-frameheaderDATA install-info \
+       install-info-am install-man install-saslincludeHEADERS \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
+       pdf-am ps ps-am tags uninstall uninstall-am \
+       uninstall-frameheaderDATA uninstall-info-am \
+       uninstall-saslincludeHEADERS
+
+
+md5global.h: makemd5
+       -rm -f md5global.h
+       ./makemd5 md5global.h
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/include/NTMakefile b/include/NTMakefile
new file mode 100644 (file)
index 0000000..0c068ee
--- /dev/null
@@ -0,0 +1,65 @@
+# NTMakefile for SASL, include directory\r
+# Alexey Melnikov\r
+#\r
+################################################################\r
+# Copyright (c) 2003 Carnegie Mellon University.  All rights reserved.\r
+#\r
+# Redistribution and use in source and binary forms, with or without\r
+# modification, are permitted provided that the following conditions\r
+# are met:\r
+#\r
+# 1. Redistributions of source code must retain the above copyright\r
+#    notice, this list of conditions and the following disclaimer. \r
+#\r
+# 2. Redistributions in binary form must reproduce the above copyright\r
+#    notice, this list of conditions and the following disclaimer in\r
+#    the documentation and/or other materials provided with the\r
+#    distribution.\r
+#\r
+# 3. The name "Carnegie Mellon University" must not be used to\r
+#    endorse or promote products derived from this software without\r
+#    prior written permission. For permission or any other legal\r
+#    details, please contact  \r
+#      Office of Technology Transfer\r
+#      Carnegie Mellon University\r
+#      5000 Forbes Avenue\r
+#      Pittsburgh, PA  15213-3890\r
+#      (412) 268-4387, fax: (412) 268-7395\r
+#      tech-transfer@andrew.cmu.edu\r
+#\r
+# 4. Redistributions of any form whatsoever must retain the following\r
+#    acknowledgment:\r
+#    "This product includes software developed by Computing Services\r
+#     at Carnegie Mellon University (http://www.cmu.edu/computing/)."\r
+#\r
+# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO\r
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r
+# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE\r
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN\r
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING\r
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+#\r
+################################################################\r
+\r
+#Suppress verbose output from defaulting values\r
+VERBOSE=0\r
+\r
+!INCLUDE ..\win32\common.mak\r
+\r
+includedir = $(prefix)\include\r
+\r
+saslincludedir = $(includedir)\sasl\\r
+\r
+saslinclude_HEADERS = hmac-md5.h md5.h sasl.h saslplug.h saslutil.h prop.h\r
+\r
+# The first target get executed by default. We don't want this to be "install"\r
+all:\r
+       @echo Nothing to be done for $@\r
+\r
+#\r
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels\r
+#\r
+install: $(saslinclude_HEADERS)\r
+       !xcopy sasl*.h $(saslincludedir) /I /F /Y\r
+       !xcopy $? $(saslincludedir) /I /F /Y\r
diff --git a/include/exits.h b/include/exits.h
new file mode 100644 (file)
index 0000000..464cb11
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1987, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)sysexits.h  8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef        _SYSEXITS_H_
+#define        _SYSEXITS_H_
+
+/*
+ *  SYSEXITS.H -- Exit status codes for system programs.
+ *
+ *     This include file attempts to categorize possible error
+ *     exit statuses for system programs, notably delivermail
+ *     and the Berkeley network.
+ *
+ *     Error numbers begin at EX__BASE to reduce the possibility of
+ *     clashing with other exit statuses that random programs may
+ *     already return.  The meaning of the codes is approximately
+ *     as follows:
+ *
+ *     EX_USAGE -- The command was used incorrectly, e.g., with
+ *             the wrong number of arguments, a bad flag, a bad
+ *             syntax in a parameter, or whatever.
+ *     EX_DATAERR -- The input data was incorrect in some way.
+ *             This should only be used for user's data & not
+ *             system files.
+ *     EX_NOINPUT -- An input file (not a system file) did not
+ *             exist or was not readable.  This could also include
+ *             errors like "No message" to a mailer (if it cared
+ *             to catch it).
+ *     EX_NOUSER -- The user specified did not exist.  This might
+ *             be used for mail addresses or remote logins.
+ *     EX_NOHOST -- The host specified did not exist.  This is used
+ *             in mail addresses or network requests.
+ *     EX_UNAVAILABLE -- A service is unavailable.  This can occur
+ *             if a support program or file does not exist.  This
+ *             can also be used as a catchall message when something
+ *             you wanted to do doesn't work, but you don't know
+ *             why.
+ *     EX_SOFTWARE -- An internal software error has been detected.
+ *             This should be limited to non-operating system related
+ *             errors as possible.
+ *     EX_OSERR -- An operating system error has been detected.
+ *             This is intended to be used for such things as "cannot
+ *             fork", "cannot create pipe", or the like.  It includes
+ *             things like getuid returning a user that does not
+ *             exist in the passwd file.
+ *     EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp,
+ *             etc.) does not exist, cannot be opened, or has some
+ *             sort of error (e.g., syntax error).
+ *     EX_CANTCREAT -- A (user specified) output file cannot be
+ *             created.
+ *     EX_IOERR -- An error occurred while doing I/O on some file.
+ *     EX_TEMPFAIL -- temporary failure, indicating something that
+ *             is not really an error.  In sendmail, this means
+ *             that a mailer (e.g.) could not create a connection,
+ *             and the request should be reattempted later.
+ *     EX_PROTOCOL -- the remote system returned something that
+ *             was "not possible" during a protocol exchange.
+ *     EX_NOPERM -- You did not have sufficient permission to
+ *             perform the operation.  This is not intended for
+ *             file system problems, which should use NOINPUT or
+ *             CANTCREAT, but rather for higher level permissions.
+ */
+
+#define EX_OK          0       /* successful termination */
+
+#define EX__BASE       64      /* base value for error messages */
+
+#define EX_USAGE       64      /* command line usage error */
+#define EX_DATAERR     65      /* data format error */
+#define EX_NOINPUT     66      /* cannot open input */
+#define EX_NOUSER      67      /* addressee unknown */
+#define EX_NOHOST      68      /* host name unknown */
+#define EX_UNAVAILABLE 69      /* service unavailable */
+#define EX_SOFTWARE    70      /* internal software error */
+#define EX_OSERR       71      /* system error (e.g., can't fork) */
+#define EX_OSFILE      72      /* critical OS file missing */
+#define EX_CANTCREAT   73      /* can't create (user) output file */
+#define EX_IOERR       74      /* input/output error */
+#define EX_TEMPFAIL    75      /* temp failure; user is invited to retry */
+#define EX_PROTOCOL    76      /* remote error in protocol */
+#define EX_NOPERM      77      /* permission denied */
+#define EX_CONFIG      78      /* configuration error */
+
+#define EX__MAX        78      /* maximum listed value */
+
+#endif /* !_SYSEXITS_H_ */
diff --git a/include/gai.h b/include/gai.h
new file mode 100644 (file)
index 0000000..d77ad11
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: gai.h,v 1.8 2006/04/10 13:36:20 mel Exp $
+ *
+ * This module is besed on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file is included in getaddrinfo.c and getnameinfo.c.
+ * See getaddrinfo.c and getnameinfo.c.
+ */
+
+#ifndef _GAI_H_
+#define _GAI_H_
+
+#ifndef NI_MAXHOST
+#define        NI_MAXHOST      1025
+#endif
+#ifndef NI_MAXSERV
+#define        NI_MAXSERV      32
+#endif
+
+/* for old netdb.h */
+#ifndef EAI_NODATA
+#define EAI_NODATA     1
+#define EAI_MEMORY     2
+#define EAI_FAMILY     5       /* ai_family not supported */
+#define EAI_SERVICE    9       /* servname not supported for ai_socktype */
+#endif
+
+/* dummy value for old netdb.h */
+#ifndef AI_PASSIVE
+#define AI_PASSIVE     1
+#define AI_CANONNAME   2
+struct addrinfo {
+       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
+       int     ai_family;      /* PF_xxx */
+       int     ai_socktype;    /* SOCK_xxx */
+       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+       size_t  ai_addrlen;     /* length of ai_addr */
+       char    *ai_canonname;  /* canonical name for hostname */
+       struct sockaddr *ai_addr;       /* binary address */
+       struct addrinfo *ai_next;       /* next structure in linked list */
+};
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+int    getnameinfo(const struct sockaddr *, socklen_t, char *,
+                   size_t, char *, size_t, int);
+#endif
+
+#ifndef HAVE_GETADDRINFO
+int    getaddrinfo(const char *, const char *,
+                   const struct addrinfo *, struct addrinfo **);
+void   freeaddrinfo(struct addrinfo *);
+char   *gai_strerror(int);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/hmac-md5.h b/include/hmac-md5.h
new file mode 100755 (executable)
index 0000000..babe003
--- /dev/null
@@ -0,0 +1,59 @@
+/* hmac-md5.h -- HMAC_MD5 functions
+ */
+
+#ifndef HMAC_MD5_H
+#define HMAC_MD5_H 1
+
+#define HMAC_MD5_SIZE 16
+
+/* intermediate MD5 context */
+typedef struct HMAC_MD5_CTX_s {
+    MD5_CTX ictx, octx;
+} HMAC_MD5_CTX;
+
+/* intermediate HMAC state
+ *  values stored in network byte order (Big Endian)
+ */
+typedef struct HMAC_MD5_STATE_s {
+    UINT4 istate[4];
+    UINT4 ostate[4];
+} HMAC_MD5_STATE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* One step hmac computation
+ *
+ * digest may be same as text or key
+ */
+void _sasl_hmac_md5(const unsigned char *text, int text_len,
+                   const unsigned char *key, int key_len,
+                   unsigned char digest[HMAC_MD5_SIZE]);
+
+/* create context from key
+ */
+void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac,
+                        const unsigned char *key, int key_len);
+
+/* precalculate intermediate state from key
+ */
+void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *hmac,
+                           const unsigned char *key, int key_len);
+
+/* initialize context from intermediate state
+ */
+void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state);
+
+#define _sasl_hmac_md5_update(hmac, text, text_len) _sasl_MD5Update(&(hmac)->ictx, (text), (text_len))
+
+/* finish hmac from intermediate result.  Intermediate result is zeroed.
+ */
+void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
+                         HMAC_MD5_CTX *hmac);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HMAC_MD5_H */
diff --git a/include/makemd5.c b/include/makemd5.c
new file mode 100644 (file)
index 0000000..eaf78aa
--- /dev/null
@@ -0,0 +1,246 @@
+/* creates the md5global.h file. 
+ *  Derived from KTH kerberos library bits.c program
+ * Tim Martin 
+ * $Id: makemd5.c,v 1.4 2003/02/13 19:55:52 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.
+ */
+
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. All advertising materials mentioning features or use of this software 
+ *    must display the following acknowledgement: 
+ *      This product includes software developed by Kungliga Tekniska 
+ *      Högskolan and its contributors. 
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+
+static void
+my_strupr(char *s)
+{
+    char *p = s;
+    while(*p){
+       if(islower((int) *p))
+           *p = toupper((int) *p);
+       p++;
+    }  
+}
+
+
+#define BITSIZE(TYPE)                                          \
+{                                                              \
+    int b = 0; TYPE x = 1, zero = 0; char *pre = "U";          \
+    char tmp[128], tmp2[128];                                  \
+    while(x){ x <<= 1; b++; if(x < zero) pre=""; }             \
+    if(b >= len){                                              \
+        int tabs;                                              \
+       sprintf(tmp, "%sINT%d" , pre, len/8);                   \
+       sprintf(tmp2, "typedef %s %s;", #TYPE, tmp);            \
+       my_strupr(tmp);                                         \
+       tabs = 5 - strlen(tmp2) / 8;                            \
+        fprintf(f, "%s", tmp2);                                        \
+       while(tabs-- > 0) fprintf(f, "\t");                     \
+       fprintf(f, "/* %2d bits */\n", b);                      \
+        return;                                                 \
+    }                                                          \
+}
+
+static void
+try_signed(FILE *f, int len)
+{
+    BITSIZE(signed char);
+    BITSIZE(short);
+    BITSIZE(int);
+    BITSIZE(long);
+#ifdef HAVE_LONG_LONG
+    BITSIZE(long long);
+#endif
+    fprintf(f, "/* There is no %d bit type */\n", len);
+}
+
+static void
+try_unsigned(FILE *f, int len)
+{
+    BITSIZE(unsigned char);
+    BITSIZE(unsigned short);
+    BITSIZE(unsigned int);
+    BITSIZE(unsigned long);
+#ifdef HAVE_LONG_LONG
+    BITSIZE(unsigned long long);
+#endif
+    fprintf(f, "/* There is no %d bit type */\n", len);
+}
+
+static int print_pre(FILE *f)
+{
+  fprintf(f,
+         "/* GLOBAL.H - RSAREF types and constants\n"
+         " */\n"
+          "#ifndef MD5GLOBAL_H\n"
+          "#define MD5GLOBAL_H\n"
+         "\n"
+         "/* PROTOTYPES should be set to one if and only if the compiler supports\n"
+         "  function argument prototyping.\n"
+         "The following makes PROTOTYPES default to 0 if it has not already\n"
+         "  been defined with C compiler flags.\n"
+         " */\n"
+         "#ifndef PROTOTYPES\n"
+         "#define PROTOTYPES 0\n"
+         "#endif\n"
+         "\n"
+         "/* POINTER defines a generic pointer type */\n"
+         "typedef unsigned char *POINTER;\n"
+         "\n"
+         );
+  return 1;
+}
+
+static int print_post(FILE *f)
+{
+  fprintf(f, "\n"
+         "/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.\n"
+         "If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it\n"
+         "returns an empty list.\n"
+         "*/\n"
+         "#if PROTOTYPES\n"
+         "#define PROTO_LIST(list) list\n"
+         "#else\n"
+         "#define PROTO_LIST(list) ()\n"
+         "#endif\n"
+         "\n"
+         "#endif /* MD5GLOBAL_H */\n\n"
+         );
+
+  return 1;
+}
+
+
+int main(int argc, char **argv)
+{
+  FILE *f;
+  char *fn, *hb;
+    
+  if(argc < 2){
+    fn = "bits.h";
+    hb = "__BITS_H__";
+    f = stdout;
+  } else {
+    char *p;
+    fn = argv[1];
+    hb = malloc(strlen(fn) + 5);
+    sprintf(hb, "__%s__", fn);
+    for(p = hb; *p; p++){
+      if(!isalnum((int) *p))
+       *p = '_';
+    }
+    f = fopen(argv[1], "w");
+  }
+
+  print_pre(f);
+
+#ifndef HAVE_INT8_T
+    try_signed (f, 8);
+#endif /* HAVE_INT8_T */
+#ifndef HAVE_INT16_T
+    try_signed (f, 16);
+#endif /* HAVE_INT16_T */
+#ifndef HAVE_INT32_T
+    try_signed (f, 32);
+#endif /* HAVE_INT32_T */
+#ifndef HAVE_INT64_T
+    try_signed (f, 64);
+#endif /* HAVE_INT64_T */
+
+#ifndef HAVE_U_INT8_T
+    try_unsigned (f, 8);
+#endif /* HAVE_INT8_T */
+#ifndef HAVE_U_INT16_T
+    try_unsigned (f, 16);
+#endif /* HAVE_U_INT16_T */
+#ifndef HAVE_U_INT32_T
+    try_unsigned (f, 32);
+#endif /* HAVE_U_INT32_T */
+#ifndef HAVE_U_INT64_T
+    try_unsigned (f, 64);
+#endif /* HAVE_U_INT64_T */
+
+    print_post(f);
+  
+    fclose(f);
+
+    return 0;  
+}
diff --git a/include/md5.h b/include/md5.h
new file mode 100644 (file)
index 0000000..15b46ea
--- /dev/null
@@ -0,0 +1,43 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+  UINT4 state[4];                                   /* state (ABCD) */
+  UINT4 count[2];        /* number of bits, modulo 2^64 (lsb first) */
+  unsigned char buffer[64];                         /* input buffer */
+} MD5_CTX;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _sasl_MD5Init PROTO_LIST ((MD5_CTX *));
+void _sasl_MD5Update PROTO_LIST
+  ((MD5_CTX *, const unsigned char *, unsigned int));
+void _sasl_MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/include/md5global.h b/include/md5global.h
new file mode 100644 (file)
index 0000000..fbd7455
--- /dev/null
@@ -0,0 +1,38 @@
+/* GLOBAL.H - RSAREF types and constants
+ */
+#ifndef MD5GLOBAL_H
+#define MD5GLOBAL_H
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+  function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+  been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+typedef signed char 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/include/prop.h b/include/prop.h
new file mode 100644 (file)
index 0000000..7a65c85
--- /dev/null
@@ -0,0 +1,187 @@
+/* prop.h -- property request/response management routines
+ *
+ * Author: Chris Newman
+ * Removal of implementation-specific details by: Rob Siemborski
+ *
+ * This is intended to be used to create a list of properties to request,
+ * and _then_ request values for all properties.  Any change to the request
+ * list will discard any existing values.  This assumption allows a very
+ * efficient and simple memory model.  This was designed for SASL API auxiliary
+ * property support, but would be fine for other contexts where this property
+ * model is appropriate.
+ *
+ * The "struct propctx" is allocated by prop_new and is a fixed size structure.
+ * If a prop_init() call were added, it would be reasonable to embed a "struct
+ * propctx" in another structure.  prop_new also allocates a pool of memory
+ * (in the vbase field) which will be used for an array of "struct propval"
+ * to list all the requested properties.
+ *
+ * Properties may be multi-valued.
+ */
+
+#ifndef PROP_H
+#define PROP_H 1
+
+/* The following ifdef block is the standard way of creating macros
+ * which make exporting from a DLL simpler. All files within this DLL
+ * are compiled with the LIBSASL_EXPORTS symbol defined on the command
+ * line. this symbol should not be defined on any project that uses
+ * this DLL. This way any other project whose source files include
+ * this file see LIBSASL_API functions as being imported from a DLL,
+ * wheras this DLL sees symbols defined with this macro as being
+ * exported.  */
+/* Under Unix, life is simpler: we just need to mark library functions
+ * as extern.  (Technically, we don't even have to do that.) */
+#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 */
+
+/* the resulting structure for property values
+ */
+struct propval {
+    const char *name;   /* name of property; NULL = end of list */
+                         /* same pointer used in request will be used here */
+    const char **values; /* list of strings, values == NULL if property not
+                         * found, *values == NULL if property found with
+                         * no values */
+    unsigned nvalues;    /* total number of value strings */
+    unsigned valsize;   /* total size in characters of all value strings */
+};
+
+/*
+ * private internal structure
+ */
+#define PROP_DEFAULT 4         /* default number of propvals to assume */
+struct propctx;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* create a property context
+ *  estimate -- an estimate of the storage needed for requests & responses
+ *              0 will use module default
+ * returns a new property context on success and NULL on any error
+ */
+LIBSASL_API struct propctx *prop_new(unsigned estimate);
+
+/* create new propctx which duplicates the contents of an existing propctx
+ * returns SASL_OK on success
+ * possible other return values include: SASL_NOMEM, SASL_BADPARAM
+ */
+LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx);
+
+/* Add property names to request
+ *  ctx       -- context from prop_new()
+ *  names     -- list of property names; must persist until context freed
+ *               or requests cleared (This extends to other contexts that
+ *               are dup'ed from this one, and their children, etc)
+ *
+ * NOTE: may clear values from context as side-effect
+ * returns SASL_OK on success
+ * possible other return values include: SASL_NOMEM, SASL_BADPARAM
+ */
+LIBSASL_API int prop_request(struct propctx *ctx, const char **names);
+
+/* return array of struct propval from the context
+ *  return value persists until next call to
+ *   prop_request, prop_clear or prop_dispose on context
+ *
+ *  returns NULL on error
+ */
+LIBSASL_API const struct propval *prop_get(struct propctx *ctx);
+
+/* Fill in an array of struct propval based on a list of property names
+ *  return value persists until next call to
+ *   prop_request, prop_clear or prop_dispose on context
+ *  returns number of matching properties which were found (values != NULL)
+ *  if a name requested here was never requested by a prop_request, then
+ *  the name field of the associated vals entry will be set to NULL
+ *
+ * The vals array MUST be atleast as long as the names array.
+ *
+ * returns # of matching properties on success
+ * possible other return values include: SASL_BADPARAM
+ */
+LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names,
+                 struct propval *vals);
+
+/* clear values and optionally requests from property context
+ *  ctx      -- property context
+ *  requests -- 0 = don't clear requests, 1 = clear requests
+ */
+LIBSASL_API void prop_clear(struct propctx *ctx, int requests);
+
+/* erase the value of a property
+ */
+LIBSASL_API void prop_erase(struct propctx *ctx, const char *name);
+
+/* dispose of property context
+ *  ctx      -- is disposed and set to NULL; noop if ctx or *ctx is NULL
+ */
+LIBSASL_API void prop_dispose(struct propctx **ctx);
+
+
+/****fetcher interfaces****/
+
+/* format the requested property names into a string
+ *  ctx    -- context from prop_new()/prop_request()
+ *  sep    -- separator between property names (unused if none requested)
+ *  seplen -- length of separator, if < 0 then strlen(sep) will be used
+ *  outbuf -- output buffer
+ *  outmax -- maximum length of output buffer including NUL terminator
+ *  outlen -- set to length of output string excluding NUL terminator
+ * returns SASL_OK on success
+ * returns SASL_BADPARAM or amount of additional space needed on failure
+ */
+LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen,
+               char *outbuf, unsigned outmax, unsigned *outlen);
+
+/* add a property value to the context
+ *  ctx    -- context from prop_new()/prop_request()
+ *  name   -- name of property to which value will be added
+ *            if NULL, add to the same name as previous prop_set/setvals call
+ *  value  -- a value for the property; will be copied into context
+ *            if NULL, remove existing values
+ *  vallen -- length of value, if <= 0 then strlen(value) will be used
+ * returns SASL_OK on success
+ * possible error return values include: SASL_BADPARAM, SASL_NOMEM
+ */
+LIBSASL_API int prop_set(struct propctx *ctx, const char *name,
+            const char *value, int vallen);
+
+/* set the values for a property
+ *  ctx    -- context from prop_new()/prop_request()
+ *  name   -- name of property to which value will be added
+ *            if NULL, add to the same name as previous prop_set/setvals call
+ *  values -- array of values, ending in NULL.  Each value is a NUL terminated
+ *            string
+ * returns SASL_OK on success
+ * possible error return values include: SASL_BADPARAM, SASL_NOMEM
+ */
+LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name,
+                const char **values);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PROP_H */
diff --git a/include/sasl.h b/include/sasl.h
new file mode 100755 (executable)
index 0000000..7ae1185
--- /dev/null
@@ -0,0 +1,1261 @@
+/* This is a proposed C API for support of SASL
+ *
+ *********************************IMPORTANT*******************************
+ * send email to chris.newman@innosoft.com and cyrus-bugs@andrew.cmu.edu *
+ * if you need to add new error codes, callback types, property values,  *
+ * etc.   It is important to keep the multiple implementations of this   *
+ * API from diverging.                                                   *
+ *********************************IMPORTANT*******************************
+ *
+ * Basic Type Summary:
+ *  sasl_conn_t       Context for a SASL connection negotiation
+ *  sasl_ssf_t        Security layer Strength Factor
+ *  sasl_callback_t   A typed client/server callback function and context
+ *  sasl_interact_t   A client interaction descriptor
+ *  sasl_secret_t     A client password
+ *  sasl_rand_t       Random data context structure
+ *  sasl_security_properties_t  An application's required security level
+ *
+ * Callbacks:
+ *  sasl_getopt_t     client/server: Get an option value
+ *  sasl_logmsg_t     client/server: Log message handler
+ *  sasl_getsimple_t  client: Get user/language list
+ *  sasl_getsecret_t  client: Get authentication secret
+ *  sasl_chalprompt_t client: Display challenge and prompt for response
+ *
+ * Server only Callbacks:
+ *  sasl_authorize_t             user authorization policy callback
+ *  sasl_getconfpath_t           get path to search for config file
+ *  sasl_server_userdb_checkpass check password and auxprops in userdb
+ *  sasl_server_userdb_setpass   set password in userdb
+ *  sasl_server_canon_user       canonicalize username routine
+ *
+ * Client/Server Function Summary:
+ *  sasl_done         Release all SASL global state
+ *  sasl_dispose      Connection done: Dispose of sasl_conn_t
+ *  sasl_getprop      Get property (e.g., user name, security layer info)
+ *  sasl_setprop      Set property (e.g., external ssf)
+ *  sasl_errdetail    Generate string from last error on connection
+ *  sasl_errstring    Translate sasl error code to a string
+ *  sasl_encode       Encode data to send using security layer
+ *  sasl_decode       Decode data received using security layer
+ *  
+ * Utility functions:
+ *  sasl_encode64     Encode data to send using MIME base64 encoding
+ *  sasl_decode64     Decode data received using MIME base64 encoding
+ *  sasl_erasebuffer  Erase a buffer
+ *
+ * Client Function Summary:
+ *  sasl_client_init  Load and initialize client plug-ins (call once)
+ *  sasl_client_new   Initialize client connection context: sasl_conn_t
+ *  sasl_client_start Select mechanism for connection
+ *  sasl_client_step  Perform one authentication step
+ *
+ * Server Function Summary
+ *  sasl_server_init  Load and initialize server plug-ins (call once)
+ *  sasl_server_new   Initialize server connection context: sasl_conn_t
+ *  sasl_listmech     Create list of available mechanisms
+ *  sasl_server_start Begin an authentication exchange
+ *  sasl_server_step  Perform one authentication exchange step
+ *  sasl_checkpass    Check a plaintext passphrase
+ *  sasl_checkapop    Check an APOP challenge/response (uses pseudo "APOP"
+ *                    mechanism similar to CRAM-MD5 mechanism; optional)
+ *  sasl_user_exists  Check if user exists
+ *  sasl_setpass      Change a password or add a user entry
+ *  sasl_auxprop_request  Request auxiliary properties
+ *  sasl_auxprop_getctx   Get auxiliary property context for connection
+ *  sasl_auxprop_store    Store a set of auxiliary properties
+ *
+ * Basic client model:
+ *  1. client calls sasl_client_init() at startup to load plug-ins
+ *  2. when connection formed, call sasl_client_new()
+ *  3. once list of supported mechanisms received from server, client
+ *     calls sasl_client_start().  goto 4a
+ *  4. client calls sasl_client_step()
+ * [4a. If SASL_INTERACT, fill in prompts and goto 4
+ *      -- doesn't happen if callbacks provided]
+ *  4b. If SASL error, goto 7 or 3
+ *  4c. If SASL_OK, continue or goto 6 if last server response was success
+ *  5. send message to server, wait for response
+ *  5a. On data or success with server response, goto 4
+ *  5b. On failure goto 7 or 3
+ *  5c. On success with no server response continue
+ *  6. continue with application protocol until connection closes
+ *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
+ *  7. call sasl_dispose(), may return to step 2
+ *  8. call sasl_done() when program terminates
+ *
+ * Basic Server model:
+ *  1. call sasl_server_init() at startup to load plug-ins
+ *  2. On connection, call sasl_server_new()
+ *  3. call sasl_listmech() and send list to client]
+ *  4. after client AUTH command, call sasl_server_start(), goto 5a
+ *  5. call sasl_server_step()
+ *  5a. If SASL_CONTINUE, output to client, wait response, repeat 5
+ *  5b. If SASL error, then goto 7
+ *  5c. If SASL_OK, move on
+ *  6. continue with application protocol until connection closes
+ *     call sasl_getprop to get username
+ *     call sasl_getprop/sasl_encode/sasl_decode() if using security layer
+ *  7. call sasl_dispose(), may return to step 2
+ *  8. call sasl_done() when program terminates
+ *
+ *************************************************
+ * IMPORTANT NOTE: server realms / username syntax
+ *
+ * If a user name contains a "@", then the rightmost "@" in the user name
+ * separates the account name from the realm in which this account is
+ * located.  A single server may support multiple realms.  If the
+ * server knows the realm at connection creation time (e.g., a server
+ * with multiple IP addresses tightly binds one address to a specific
+ * realm) then that realm must be passed in the user_realm field of
+ * the sasl_server_new call.  If user_realm is non-empty and an
+ * unqualified user name is supplied, then the canon_user facility is
+ * expected to append "@" and user_realm to the user name.  The canon_user
+ * facility may treat other characters such as "%" as equivalent to "@".
+ *
+ * If the server forbids the use of "@" in user names for other
+ * purposes, this simplifies security validation.
+ */
+
+#ifndef SASL_H
+#define SASL_H 1
+
+/* Keep in sync with win32/common.mak */
+#define SASL_VERSION_MAJOR 2
+#define SASL_VERSION_MINOR 1
+#define SASL_VERSION_STEP 23
+
+/* A convenience macro: same as was defined in the OpenLDAP LDAPDB */
+#define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\
+      (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP)
+
+#include "prop.h"
+
+/*************
+ * Basic API *
+ *************/
+
+/* SASL result codes: */
+#define SASL_CONTINUE    1   /* another step is needed in authentication */
+#define SASL_OK          0   /* successful result */
+#define SASL_FAIL       -1   /* generic failure */
+#define SASL_NOMEM      -2   /* memory shortage failure */
+#define SASL_BUFOVER    -3   /* overflowed buffer */
+#define SASL_NOMECH     -4   /* mechanism not supported */
+#define SASL_BADPROT    -5   /* bad protocol / cancel */
+#define SASL_NOTDONE    -6   /* can't request info until later in exchange */
+#define SASL_BADPARAM   -7   /* invalid parameter supplied */
+#define SASL_TRYAGAIN   -8   /* transient failure (e.g., weak key) */
+#define SASL_BADMAC    -9   /* integrity check failed */
+#define SASL_NOTINIT    -12  /* SASL library not initialized */
+                             /* -- client only codes -- */
+#define SASL_INTERACT    2   /* needs user interaction */
+#define SASL_BADSERV    -10  /* server failed mutual authentication step */
+#define SASL_WRONGMECH  -11  /* mechanism doesn't support requested feature */
+                             /* -- server only codes -- */
+#define SASL_BADAUTH    -13  /* authentication failure */
+#define SASL_NOAUTHZ    -14  /* authorization failure */
+#define SASL_TOOWEAK    -15  /* mechanism too weak for this user */
+#define SASL_ENCRYPT    -16  /* encryption needed to use mechanism */
+#define SASL_TRANS      -17  /* One time use of a plaintext password will
+                               enable requested mechanism for user */
+#define SASL_EXPIRED    -18  /* passphrase expired, has to be reset */
+#define SASL_DISABLED   -19  /* account disabled */
+#define SASL_NOUSER     -20  /* user not found */
+#define SASL_BADVERS    -23  /* version mismatch with plug-in */
+#define SASL_UNAVAIL    -24  /* remote authentication server unavailable */
+#define SASL_NOVERIFY   -26  /* user exists, but no verifier for user */
+                            /* -- codes for password setting -- */
+#define SASL_PWLOCK     -21  /* passphrase locked */
+#define SASL_NOCHANGE   -22  /* requested change was not needed */
+#define SASL_WEAKPASS   -27  /* passphrase is too weak for security policy */
+#define SASL_NOUSERPASS -28  /* user supplied passwords not permitted */
+
+/* max size of a sasl mechanism name */
+#define SASL_MECHNAMEMAX 20
+
+#ifdef _WIN32
+/* Define to have the same layout as a WSABUF */
+#ifndef STRUCT_IOVEC_DEFINED
+#define STRUCT_IOVEC_DEFINED 1
+struct iovec {
+    long iov_len;
+    char *iov_base;
+};
+#endif
+#else
+struct iovec;                               /* Defined in OS headers */
+#endif
+
+
+/* per-connection SASL negotiation state for client or server
+ */
+typedef struct sasl_conn sasl_conn_t;
+
+/* Plain text password structure.
+ *  len is the length of the password, data is the text.
+ */
+typedef struct sasl_secret {
+    unsigned long len;
+    unsigned char data[1];             /* variable sized */
+} sasl_secret_t;
+
+/* random data context structure
+ */
+typedef struct sasl_rand_s sasl_rand_t;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****************************
+ * Configure Basic Services *
+ ****************************/
+
+/* the following functions are used to adjust how allocation and mutexes work
+ * they must be called before all other SASL functions:
+ */
+
+/* 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 *);
+
+/* 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
+
+/* verify file callback -- this allows applications to check if they
+ * want SASL to use files, file by file.  This is intended to allow
+ * applications to sanity check the environment to make sure plugins
+ * or the configuration file can't be written to, etc.
+ * inputs: 
+ *  context     -- verifypath context from the callback record
+ *  file        -- full path to file to verify
+ *  type        -- type of file to verify (see below)
+
+ * returns:
+ *  SASL_OK        -- no error (file can safely be used)
+ *  SASL_CONTINUE  -- continue WITHOUT using this file
+ *  SASL_FAIL      -- error 
+ */
+
+/* these are the types of files libsasl will ask about */
+typedef enum {
+    SASL_VRFY_PLUGIN=0,                /* a DLL/shared library plug-in */
+    SASL_VRFY_CONF=1,          /* a configuration file */
+    SASL_VRFY_PASSWD=2,                /* a password storage file/db */
+    SASL_VRFY_OTHER=3          /* some other file */
+} sasl_verify_type_t;
+
+typedef int sasl_verifyfile_t(void *context,
+                              const char *file, sasl_verify_type_t type);
+#define SASL_CB_VERIFYFILE  4
+
+/* getconfpath callback -- this allows applications to specify the
+ * colon-separated path to search for config files (by default,
+ * taken from the SASL_CONF_PATH environment variable).
+ * inputs:
+ *  context     -- getconfpath context from the callback record
+ * outputs:
+ *  path        -- colon seperated path (allocated on the heap; the
+ *                 library will free it using the sasl_free_t *
+ *                 passed to sasl_set_callback, or the standard free()
+ *                 library call).
+ * returns:
+ *  SASL_OK     -- no error
+ *  SASL_FAIL   -- error
+ */
+typedef int sasl_getconfpath_t(void *context,
+                               char **path);
+
+#define SASL_CB_GETCONFPATH  5
+
+/* client/user interaction callbacks:
+ */
+/* Simple prompt -- result must persist until next call to getsimple on
+ *  same connection or until connection context is disposed
+ * inputs:
+ *  context       -- context from callback structure
+ *  id            -- callback id
+ * outputs:
+ *  result        -- set to NUL terminated string
+ *                   NULL = user cancel
+ *  len           -- length of result
+ * returns SASL_OK
+ */
+typedef int sasl_getsimple_t(void *context, int id,
+                            const char **result, unsigned *len);
+#define SASL_CB_USER         0x4001  /* client user identity to login as */
+#define SASL_CB_AUTHNAME     0x4002  /* client authentication name */
+#define SASL_CB_LANGUAGE     0x4003  /* comma separated list of RFC 1766
+                                     * language codes in order of preference
+                                     * to be used to localize client prompts
+                                     * or server error codes */
+#define SASL_CB_CNONCE       0x4007  /* caller supplies client-nonce
+                                     * primarily for testing purposes */
+
+/* get a sasl_secret_t (plaintext password with length)
+ * inputs:
+ *  conn          -- connection context
+ *  context       -- context from callback structure
+ *  id            -- callback id
+ * outputs:
+ *  psecret       -- set to NULL to cancel
+ *                   set to password structure which must persist until
+ *                   next call to getsecret in same connection, but middleware
+ *                   will erase password data when it's done with it.
+ * returns SASL_OK
+ */
+typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id,
+                            sasl_secret_t **psecret);
+#define SASL_CB_PASS         0x4004  /* client passphrase-based secret */
+
+
+/* prompt for input in response to a challenge.
+ * input:
+ *  context   -- context from callback structure
+ *  id        -- callback id
+ *  challenge -- server challenge
+ * output:
+ *  result    -- NUL terminated result, NULL = user cancel
+ *  len       -- length of result
+ * returns SASL_OK
+ */
+typedef int sasl_chalprompt_t(void *context, int id,
+                             const char *challenge,
+                             const char *prompt, const char *defresult,
+                             const char **result, unsigned *len);
+#define SASL_CB_ECHOPROMPT   0x4005 /* challenge and client enterred result */
+#define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */
+
+/* prompt (or autoselect) the realm to do authentication in.
+ *  may get a list of valid realms.
+ * input:
+ *  context     -- context from callback structure
+ *  id          -- callback id
+ *  availrealms -- available realms; string list; NULL terminated
+ *                 list may be empty.
+ * output:
+ *  result      -- NUL terminated realm; NULL is equivalent to ""
+ * returns SASL_OK
+ * result must persist until the next callback
+ */
+typedef int sasl_getrealm_t(void *context, int id,
+                           const char **availrealms,
+                           const char **result);
+#define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */
+
+/* server callbacks:
+ */
+
+/* improved callback to verify authorization;
+ *     canonicalization now handled elsewhere
+ *  conn           -- connection context
+ *  requested_user -- the identity/username to authorize (NUL terminated)
+ *  rlen           -- length of requested_user
+ *  auth_identity  -- the identity associated with the secret (NUL terminated)
+ *  alen           -- length of auth_identity
+ *  default_realm  -- default user realm, as passed to sasl_server_new if
+ *  urlen          -- length of default realm
+ *  propctx        -- auxiliary properties
+ * returns SASL_OK on success,
+ *         SASL_NOAUTHZ or other SASL response on failure
+ */
+typedef int sasl_authorize_t(sasl_conn_t *conn,
+                            void *context,
+                            const char *requested_user, unsigned rlen,
+                            const char *auth_identity, unsigned alen,
+                            const char *def_realm, unsigned urlen,
+                            struct propctx *propctx);
+#define SASL_CB_PROXY_POLICY 0x8001
+
+/* functions for "userdb" based plugins to call to get/set passwords.
+ * the location for the passwords is determined by the caller or middleware.
+ * plug-ins may get passwords from other locations.
+ */
+
+/* callback to verify a plaintext password against the caller-supplied
+ * user database.  This is necessary to allow additional <method>s for
+ * encoding of the userPassword property.
+ *  user          -- NUL terminated user name with user@realm syntax
+ *  pass          -- password to check (may not be NUL terminated)
+ *  passlen       -- length of password to check
+ *  propctx       -- auxiliary properties for user
+ */
+typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn,
+                                          void *context,
+                                          const char *user,
+                                          const char *pass,
+                                          unsigned passlen,
+                                          struct propctx *propctx);
+#define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005)
+
+/* callback to store/change a plaintext password in the user database
+ *  user          -- NUL terminated user name with user@realm syntax
+ *  pass          -- password to store (may not be NUL terminated)
+ *  passlen       -- length of password to store
+ *  propctx       -- auxiliary properties (not stored)
+ *  flags         -- see SASL_SET_* flags below (SASL_SET_CREATE optional)
+ */
+typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn,
+                                        void *context,
+                                        const char *user,
+                                        const char *pass,
+                                        unsigned passlen,
+                                        struct propctx *propctx,
+                                        unsigned flags);
+#define SASL_CB_SERVER_USERDB_SETPASS (0x8006)
+
+/* callback for a server-supplied user canonicalization function.
+ *
+ * This function is called directly after the mechanism has the
+ * authentication and authorization IDs.  It is called before any
+ * User Canonicalization plugin is called.  It has the responsibility
+ * of copying its output into the provided output buffers.
+ * 
+ *  in, inlen     -- user name to canonicalize, may not be NUL terminated
+ *                   may be same buffer as out
+ *  flags         -- not currently used, supplied by auth mechanism
+ *  user_realm    -- the user realm (may be NULL in case of client)
+ *  out           -- buffer to copy user name
+ *  out_max       -- max length of user name
+ *  out_len       -- set to length of user name
+ *
+ * returns
+ *  SASL_OK         on success
+ *  SASL_BADPROT    username contains invalid character
+ */
+
+/* User Canonicalization Function Flags */
+
+#define SASL_CU_NONE    0x00 /* Not a valid flag to pass */
+/* One of the following two is required */
+#define SASL_CU_AUTHID  0x01
+#define SASL_CU_AUTHZID 0x02
+
+typedef int sasl_canon_user_t(sasl_conn_t *conn,
+                             void *context,
+                             const char *in, unsigned inlen,
+                             unsigned flags,
+                             const char *user_realm,
+                             char *out,
+                             unsigned out_max, unsigned *out_len);
+
+#define SASL_CB_CANON_USER (0x8007)
+
+/**********************************
+ * Common Client/server functions *
+ **********************************/
+
+/* Types of paths to set (see sasl_set_path below). */
+#define SASL_PATH_TYPE_PLUGIN  0
+#define SASL_PATH_TYPE_CONFIG  1
+
+/* a simpler way to set plugin path or configuration file path
+ * without the need to set sasl_getpath_t callback.
+ *
+ * This function can be called before sasl_server_init/sasl_client_init.
+ */  
+LIBSASL_API int sasl_set_path (int path_type, char * path);
+
+/* get sasl library version information
+ * implementation is a vendor-defined string
+ * version is a vender-defined representation of the version #.
+ *
+ * This function is being deprecated in favor of sasl_version_info. */
+LIBSASL_API void sasl_version(const char **implementation,
+                             int *version);
+
+/* Extended version of sasl_version().
+ *
+ * This function is to be used
+ *  for library version display and logging
+ *  for bug workarounds in old library versions
+ *
+ * The sasl_version_info is not to be used for API feature detection.
+ *
+ * All parameters are optional. If NULL is specified, the value is not returned.
+ */
+LIBSASL_API void sasl_version_info (const char **implementation,
+                               const char **version_string,
+                               int *version_major,
+                               int *version_minor,
+                               int *version_step,
+                               int *version_patch);
+
+/* dispose of all SASL plugins.  Connection
+ * states have to be disposed of before calling this.
+ */
+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 */
+
+/* This returns a string which is either empty or has an error message
+ * from sasl_seterror (e.g., from a plug-in or callback).  It differs
+ * from the result of sasl_errdetail() which also takes into account the
+ * last return status code.
+ */
+#define SASL_PLUGERR     10
+
+/* a handle to any delegated credentials or NULL if none is present 
+ * is returned by the mechanism. The user will probably need to know
+ * which mechanism was used to actually known how to make use of them
+ * currently only implemented for the gssapi mechanism */
+#define SASL_DELEGATEDCREDS 11  
+
+#define SASL_SERVICE      12   /* service passed to sasl_*_new */
+#define SASL_SERVERFQDN   13   /* serverFQDN passed to sasl_*_new */
+#define SASL_AUTHSOURCE   14   /* name of auth source last used, useful
+                                * for failed authentication tracking */
+#define SASL_MECHNAME     15    /* active mechanism name, if any */
+#define SASL_AUTHUSER     16    /* authentication/admin user */
+#define SASL_APPNAME     17    /* application name (used for logging/
+                                  configuration), same as appname parameter
+                                  to sasl_server_init */
+
+/* GSS-API credential handle for sasl_client_step() or sasl_server_step().
+ * The application is responsible for releasing this credential handle. */
+#define        SASL_GSS_CREDS    18
+
+/* GSS name (gss_name_t) of the peer, as output by gss_inquire_context()
+ * or gss_accept_sec_context().
+ * On server end this is similar to SASL_USERNAME, but the gss_name_t
+ * structure can contain additional attributes associated with the peer.
+ */
+#define        SASL_GSS_PEER_NAME      19
+
+/* Local GSS name (gss_name_t) as output by gss_inquire_context(). This
+ * is particularly useful for servers that respond to multiple names. */
+#define        SASL_GSS_LOCAL_NAME     20
+
+
+/* set property in SASL connection state
+ * returns:
+ *  SASL_OK       -- value set
+ *  SASL_BADPARAM -- invalid property or value
+ */
+LIBSASL_API int sasl_setprop(sasl_conn_t *conn,
+                            int propnum,
+                            const void *value);
+#define SASL_SSF_EXTERNAL  100 /* external SSF active (sasl_ssf_t *) */
+#define SASL_SEC_PROPS     101 /* sasl_security_properties_t */
+#define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) */
+
+/* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the
+ * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms).
+ * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in
+ * including EXTERNAL is present.
+ */
+
+/* do precalculations during an idle period or network round trip
+ *  may pass NULL to precompute for some mechanisms prior to connect
+ *  returns 1 if action taken, 0 if no action taken
+ */
+LIBSASL_API int sasl_idle(sasl_conn_t *conn);
+
+/**************
+ * Client API *
+ **************/
+
+/* list of client interactions with user for caller to fill in
+ */
+typedef struct sasl_interact {
+    unsigned long id;          /* same as client/user callback ID */
+    const char *challenge;     /* presented to user (e.g. OTP challenge) */
+    const char *prompt;                /* presented to user (e.g. "Username: ") */
+    const char *defresult;     /* default result string */
+    const void *result;                /* set to point to result */
+    unsigned len;              /* set to length of result */
+} sasl_interact_t;
+
+/* initialize the SASL client drivers
+ *  callbacks      -- base callbacks for all client connections;
+ *                    must include getopt callback
+ * returns:
+ *  SASL_OK        -- Success
+ *  SASL_NOMEM     -- Not enough memory
+ *  SASL_BADVERS   -- Mechanism version mismatch
+ *  SASL_BADPARAM  -- missing getopt callback or error in config file
+ *  SASL_NOMECH    -- No mechanisms available
+ *  ...
+ */
+LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks);
+
+/* initialize a client exchange based on the specified mechanism
+ *  service       -- registered name of the service using SASL (e.g. "imap")
+ *  serverFQDN    -- the fully qualified domain name of the server
+ *  iplocalport   -- client IPv4/IPv6 domain literal string with port
+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
+ *  ipremoteport  -- server IPv4/IPv6 domain literal string with port
+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
+ *  prompt_supp   -- list of client interactions supported
+ *                   may also include sasl_getopt_t context & call
+ *                   NULL prompt_supp = user/pass via SASL_INTERACT only
+ *                   NULL proc = interaction supported via SASL_INTERACT
+ *  flags         -- server usage flags (see above)
+ * in/out:
+ *  pconn         -- connection negotiation structure
+ *                   pointer to NULL => allocate new
+ *
+ * Returns:
+ *  SASL_OK       -- success
+ *  SASL_NOMECH   -- no mechanism meets requested properties
+ *  SASL_NOMEM    -- not enough memory
+ */
+LIBSASL_API int sasl_client_new(const char *service,
+                               const char *serverFQDN,
+                               const char *iplocalport,
+                               const char *ipremoteport,
+                               const sasl_callback_t *prompt_supp,
+                               unsigned flags,
+                               sasl_conn_t **pconn);
+
+/* select a mechanism for a connection
+ *  mechlist      -- mechanisms server has available (punctuation ignored)
+ *                   if NULL, then discard cached info and retry last mech
+ * output:
+ *  prompt_need   -- on SASL_INTERACT, list of prompts needed to continue
+ *                   may be NULL if callbacks provided
+ *  clientout     -- the initial client response to send to the server
+ *                   will be valid until next call to client_start/client_step
+ *                   NULL if mech doesn't include initial client challenge
+ *  mech          -- set to mechansm name of selected mechanism (may be NULL)
+ *
+ * Returns:
+ *  SASL_OK       -- success
+ *  SASL_NOMEM    -- not enough memory
+ *  SASL_NOMECH   -- no mechanism meets requested properties
+ *  SASL_INTERACT -- user interaction needed to fill in prompt_need list
+ */
+LIBSASL_API int sasl_client_start(sasl_conn_t *conn,
+                                 const char *mechlist,
+                                 sasl_interact_t **prompt_need,
+                                 const char **clientout,
+                                 unsigned *clientoutlen,
+                                 const char **mech);
+
+/* do a single authentication step.
+ *  serverin    -- the server message received by the client, MUST have a NUL
+ *                 sentinel, not counted by serverinlen
+ * output:
+ *  prompt_need -- on SASL_INTERACT, list of prompts needed to continue
+ *  clientout   -- the client response to send to the server
+ *                 will be valid until next call to client_start/client_step
+ *
+ * returns:
+ *  SASL_OK        -- success
+ *  SASL_INTERACT  -- user interaction needed to fill in prompt_need list
+ *  SASL_BADPROT   -- server protocol incorrect/cancelled
+ *  SASL_BADSERV   -- server failed mutual auth
+ */
+LIBSASL_API int sasl_client_step(sasl_conn_t *conn,
+                                const char *serverin,
+                                unsigned serverinlen,
+                                sasl_interact_t **prompt_need,
+                                const char **clientout,
+                                unsigned *clientoutlen);
+
+/**************
+ * Server API *
+ **************/
+
+/* initialize server drivers, done once per process
+ *  callbacks      -- callbacks for all server connections; must include
+ *                    getopt callback
+ *  appname        -- name of calling application (for lower level logging)
+ * results:
+ *  state          -- server state
+ * returns:
+ *  SASL_OK        -- success
+ *  SASL_BADPARAM  -- error in config file
+ *  SASL_NOMEM     -- memory failure
+ *  SASL_BADVERS   -- Mechanism version mismatch
+ */
+LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks,
+                                const char *appname);
+
+/* IP/port syntax:
+ *  a.b.c.d;p              where a-d are 0-255 and p is 0-65535 port number.
+ *  e:f:g:h:i:j:k:l;p      where e-l are 0000-ffff lower-case hexidecimal
+ *  e:f:g:h:i:j:a.b.c.d;p  alternate syntax for previous
+ *
+ *  Note that one or more "0" fields in f-k can be replaced with "::"
+ *  Thus:                 e:f:0000:0000:0000:j:k:l;p
+ *  can be abbreviated:   e:f::j:k:l;p
+ *
+ * A buffer of size 52 is adequate for the longest format with NUL terminator.
+ */
+
+/* create context for a single SASL connection
+ *  service        -- registered name of the service using SASL (e.g. "imap")
+ *  serverFQDN     -- Fully qualified domain name of server.  NULL means use
+ *                    gethostname() or equivalent.
+ *                    Useful for multi-homed servers.
+ *  user_realm     -- permits multiple user realms on server, NULL = default
+ *  iplocalport    -- server IPv4/IPv6 domain literal string with port
+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
+ *  ipremoteport   -- client IPv4/IPv6 domain literal string with port
+ *                    (if NULL, then mechanisms requiring IPaddr are disabled)
+ *  callbacks      -- callbacks (e.g., authorization, lang, new getopt context)
+ *  flags          -- usage flags (see above)
+ * returns:
+ *  pconn          -- new connection context
+ *
+ * returns:
+ *  SASL_OK        -- success
+ *  SASL_NOMEM     -- not enough memory
+ */
+LIBSASL_API int sasl_server_new(const char *service,
+                               const char *serverFQDN,
+                               const char *user_realm,
+                               const char *iplocalport,
+                               const char *ipremoteport,
+                               const sasl_callback_t *callbacks,
+                               unsigned flags,
+                               sasl_conn_t **pconn);
+
+/* Return an array of NUL-terminated strings, terminated by a NULL pointer,
+ * which lists all possible mechanisms that the library can supply
+ *
+ * Returns NULL on failure. */
+LIBSASL_API const char ** sasl_global_listmech(void);
+
+/* This returns a list of mechanisms in a NUL-terminated string
+ *  conn          -- the connection to list mechanisms for (either client
+ *                   or server)
+ *  user          -- restricts mechanisms to those available to that user
+ *                   (may be NULL, not used for client case)
+ *  prefix        -- appended to beginning of result
+ *  sep           -- appended between mechanisms
+ *  suffix        -- appended to end of result
+ * results:
+ *  result        -- NUL terminated result which persists until next
+ *                   call to sasl_listmech for this sasl_conn_t
+ *  plen          -- gets length of result (excluding NUL), may be NULL
+ *  pcount        -- gets number of mechanisms, may be NULL
+ *
+ * returns:
+ *  SASL_OK        -- success
+ *  SASL_NOMEM     -- not enough memory
+ *  SASL_NOMECH    -- no enabled mechanisms
+ */
+LIBSASL_API int sasl_listmech(sasl_conn_t *conn,
+                             const char *user,
+                             const char *prefix,
+                             const char *sep,
+                             const char *suffix,
+                             const char **result,
+                             unsigned *plen,
+                             int *pcount);
+
+/* start a mechanism exchange within a connection context
+ *  mech           -- the mechanism name client requested
+ *  clientin       -- client initial response (NUL terminated), NULL if empty
+ *  clientinlen    -- length of initial response
+ *  serverout      -- initial server challenge, NULL if done 
+ *                    (library handles freeing this string)
+ *  serveroutlen   -- length of initial server challenge
+ * output:
+ *  pconn          -- the connection negotiation state on success
+ *
+ * Same returns as sasl_server_step() or
+ * SASL_NOMECH if mechanism not available.
+ */
+LIBSASL_API int sasl_server_start(sasl_conn_t *conn,
+                                 const char *mech,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen);
+
+/* perform one step of the SASL exchange
+ *  inputlen & input -- client data
+ *                      NULL on first step if no optional client step
+ *  outputlen & output -- set to the server data to transmit
+ *                        to the client in the next step
+ *                        (library handles freeing this)
+ *
+ * returns:
+ *  SASL_OK        -- exchange is complete.
+ *  SASL_CONTINUE  -- indicates another step is necessary.
+ *  SASL_TRANS     -- entry for user exists, but not for mechanism
+ *                    and transition is possible
+ *  SASL_BADPARAM  -- service name needed
+ *  SASL_BADPROT   -- invalid input from client
+ *  ...
+ */
+LIBSASL_API int sasl_server_step(sasl_conn_t *conn,
+                                const char *clientin,
+                                unsigned clientinlen,
+                                const char **serverout,
+                                unsigned *serveroutlen);
+
+/* check if an apop exchange is valid
+ *  (note this is an optional part of the SASL API)
+ *  if challenge is NULL, just check if APOP is enabled
+ * inputs:
+ *  challenge     -- challenge which was sent to client
+ *  challen       -- length of challenge, 0 = strlen(challenge)
+ *  response      -- client response, "<user> <digest>" (RFC 1939)
+ *  resplen       -- length of response, 0 = strlen(response)
+ * returns 
+ *  SASL_OK       -- success
+ *  SASL_BADAUTH  -- authentication failed
+ *  SASL_BADPARAM -- missing challenge
+ *  SASL_BADPROT  -- protocol error (e.g., response in wrong format)
+ *  SASL_NOVERIFY -- user found, but no verifier
+ *  SASL_NOMECH   -- mechanism not supported
+ *  SASL_NOUSER   -- user not found
+ */
+LIBSASL_API int sasl_checkapop(sasl_conn_t *conn,
+                              const char *challenge, unsigned challen,
+                              const char *response, unsigned resplen);
+
+/* check if a plaintext password is valid
+ *   if user is NULL, check if plaintext passwords are enabled
+ * inputs:
+ *  user          -- user to query in current user_domain
+ *  userlen       -- length of username, 0 = strlen(user)
+ *  pass          -- plaintext password to check
+ *  passlen       -- length of password, 0 = strlen(pass)
+ * returns 
+ *  SASL_OK       -- success
+ *  SASL_NOMECH   -- mechanism not supported
+ *  SASL_NOVERIFY -- user found, but no verifier
+ *  SASL_NOUSER   -- user not found
+ */
+LIBSASL_API int sasl_checkpass(sasl_conn_t *conn,
+                              const char *user, unsigned userlen,
+                              const char *pass, unsigned passlen);
+
+/* check if a user exists on server
+ *  conn          -- connection context
+ *  service       -- registered name of the service using SASL (e.g. "imap")
+ *  user_realm    -- permits multiple user realms on server, NULL = default
+ *  user          -- NUL terminated user name
+ *
+ * returns:
+ *  SASL_OK       -- success
+ *  SASL_DISABLED -- account disabled
+ *  SASL_NOUSER   -- user not found
+ *  SASL_NOVERIFY -- user found, but no usable mechanism
+ *  SASL_NOMECH   -- no mechanisms enabled
+ */
+LIBSASL_API int sasl_user_exists(sasl_conn_t *conn,
+                                const char *service,
+                                const char *user_realm,
+                                const char *user);
+
+/* set the password for a user
+ *  conn        -- SASL connection
+ *  user        -- user name
+ *  pass        -- plaintext password, may be NULL to remove user
+ *  passlen     -- length of password, 0 = strlen(pass)
+ *  oldpass     -- NULL will sometimes work
+ *  oldpasslen  -- length of password, 0 = strlen(oldpass)
+ *  flags       -- see flags below
+ * 
+ * returns:
+ *  SASL_NOCHANGE  -- proper entry already exists
+ *  SASL_NOMECH    -- no authdb supports password setting as configured
+ *  SASL_NOVERIFY  -- user exists, but no settable password present
+ *  SASL_DISABLED  -- account disabled
+ *  SASL_PWLOCK    -- password locked
+ *  SASL_WEAKPASS  -- password too weak for security policy
+ *  SASL_NOUSERPASS -- user-supplied passwords not permitted
+ *  SASL_FAIL      -- OS error
+ *  SASL_BADPARAM  -- password too long
+ *  SASL_OK        -- successful
+ */
+LIBSASL_API int sasl_setpass(sasl_conn_t *conn,
+                            const char *user,
+                            const char *pass, unsigned passlen,
+                            const char *oldpass, unsigned oldpasslen,
+                            unsigned flags);
+#define SASL_SET_CREATE  0x01   /* create a new entry for user */
+#define SASL_SET_DISABLE 0x02  /* disable user account */
+#define SASL_SET_NOPLAIN 0x04  /* do not store secret in plain text */
+#define SASL_SET_CURMECH_ONLY 0x08     /* set the mechanism specific password only.
+                                          fail if no current mechanism */
+
+/*********************************************************
+ * Auxiliary Property Support -- added by cjn 1999-09-29 *
+ *********************************************************/
+
+#define SASL_AUX_END      NULL /* last auxiliary property */
+
+/* traditional Posix items (should be implemented on Posix systems) */
+#define SASL_AUX_PASSWORD_PROP "userPassword" /* User Password */
+#define SASL_AUX_PASSWORD "*" SASL_AUX_PASSWORD_PROP /* User Password (of authid) */
+#define SASL_AUX_UIDNUM   "uidNumber"  /* UID number for the user */
+#define SASL_AUX_GIDNUM   "gidNumber"  /* GID for the user */
+#define SASL_AUX_FULLNAME "gecos"      /* full name of the user, unix-style */
+#define SASL_AUX_HOMEDIR  "homeDirectory" /* home directory for user */
+#define SASL_AUX_SHELL    "loginShell" /* login shell for the user */
+
+/* optional additional items (not necessarily implemented) */
+/* single preferred mail address for user canonically-quoted
+ * RFC821/822 syntax */
+#define SASL_AUX_MAILADDR "mail"
+/* path to unix-style mailbox for user */
+#define SASL_AUX_UNIXMBX  "mailMessageStore"
+/* SMTP mail channel name to use if user authenticates successfully */
+#define SASL_AUX_MAILCHAN "mailSMTPSubmitChannel"
+
+/* Request a set of auxiliary properties
+ *  conn         connection context
+ *  propnames    list of auxiliary property names to request ending with
+ *               NULL.  
+ *
+ * Subsequent calls will add items to the request list.  Call with NULL
+ * to clear the request list.
+ *
+ * errors
+ *  SASL_OK       -- success
+ *  SASL_BADPARAM -- bad count/conn parameter
+ *  SASL_NOMEM    -- out of memory
+ */
+LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn,
+                                    const char **propnames);
+
+/* Returns current auxiliary property context.
+ * Use functions in prop.h to access content
+ *
+ *  if authentication hasn't completed, property values may be empty/NULL
+ *
+ *  properties not recognized by active plug-ins will be left empty/NULL
+ *
+ *  returns NULL if conn is invalid.
+ */
+LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn);
+
+/* Store the set of auxiliary properties for the given user.
+ * Use functions in prop.h to set the content.
+ *
+ *  conn         connection context
+ *  ctx          property context from prop_new()/prop_request()/prop_set()
+ *  user         NUL terminated user
+ *
+ * Call with NULL 'ctx' to see if the backend allows storing properties.
+ *
+ * errors
+ *  SASL_OK       -- success
+ *  SASL_NOMECH   -- can not store some/all properties
+ *  SASL_BADPARAM -- bad conn/ctx/user parameter
+ *  SASL_NOMEM    -- out of memory
+ *  SASL_FAIL     -- failed to store
+ */
+LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn,
+                                  struct propctx *ctx, const char *user);
+
+/**********************
+ * security layer API *
+ **********************/
+
+/* encode a block of data for transmission using security layer,
+ *  returning the input buffer if there is no security layer.
+ *  output is only valid until next call to sasl_encode or sasl_encodev
+ * returns:
+ *  SASL_OK      -- success (returns input if no layer negotiated)
+ *  SASL_NOTDONE -- security layer negotiation not finished
+ *  SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF
+ */
+LIBSASL_API int sasl_encode(sasl_conn_t *conn,
+                           const char *input, unsigned inputlen,
+                           const char **output, unsigned *outputlen);
+
+/* encode a block of data for transmission using security layer
+ *  output is only valid until next call to sasl_encode or sasl_encodev
+ * returns:
+ *  SASL_OK      -- success (returns input if no layer negotiated)
+ *  SASL_NOTDONE -- security layer negotiation not finished
+ *  SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF
+ *                  or no security layer
+ */
+LIBSASL_API int sasl_encodev(sasl_conn_t *conn,
+                            const struct iovec *invec, unsigned numiov,
+                            const char **output, unsigned *outputlen);
+
+/* decode a block of data received using security layer
+ *  returning the input buffer if there is no security layer.
+ *  output is only valid until next call to sasl_decode
+ *
+ *  if outputlen is 0 on return, than the value of output is undefined.
+ *  
+ * returns:
+ *  SASL_OK      -- success (returns input if no layer negotiated)
+ *  SASL_NOTDONE -- security layer negotiation not finished
+ *  SASL_BADMAC  -- bad message integrity check
+ */
+LIBSASL_API int sasl_decode(sasl_conn_t *conn,
+                           const char *input, unsigned inputlen,
+                           const char **output, unsigned *outputlen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SASL_H */
diff --git a/include/saslplug.h b/include/saslplug.h
new file mode 100755 (executable)
index 0000000..61d0a33
--- /dev/null
@@ -0,0 +1,953 @@
+/* saslplug.h --  API for SASL plug-ins
+ */
+
+#ifndef SASLPLUG_H
+#define SASLPLUG_H 1
+
+#ifndef MD5GLOBAL_H
+#include "md5global.h"
+#endif
+#ifndef MD5_H
+#include "md5.h"
+#endif
+#ifndef HMAC_MD5_H
+#include "hmac-md5.h"
+#endif
+#ifndef PROP_H
+#include "prop.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* callback to lookup a sasl_callback_t for a connection
+ * input:
+ *  conn        -- the connection to lookup a callback for
+ *  callbacknum -- the number of the callback
+ * output:
+ *  pproc       -- pointer to the callback function (set to NULL on failure)
+ *  pcontext    -- pointer to the callback context (set to NULL on failure)
+ * returns:
+ *  SASL_OK -- no error
+ *  SASL_FAIL -- unable to find a callback of the requested type
+ *  SASL_INTERACT -- caller must use interaction to get data
+ */
+typedef int sasl_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 a human readable text
+     * (strerror()) for the error specified as the parameter).
+     * The implementation may use a fixed size buffer not smaller
+     * than 512 octets if it securely truncates the message.
+     *
+     * level is a SASL_LOG_* level (see sasl.h)
+     */
+    void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...);
+
+    /* 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);
+    int (*auxprop_store)(sasl_conn_t *conn,
+                        struct propctx *ctx, const char *user);
+
+    /* for additions which don't require a version upgrade; set to 0 */
+    int (*spare_fptr1)();
+    int (*spare_fptr2)();
+} sasl_utils_t;
+
+/*
+ * output parameters from SASL API
+ *
+ * created / destroyed by the glue code, though probably filled in
+ * by a combination of the plugin, the glue code, and the canon_user callback.
+ *
+ */
+typedef struct sasl_out_params {
+    unsigned doneflag;         /* exchange complete */
+
+    const char *user;          /* canonicalized user name */
+    const char *authid;                /* canonicalized authentication id */
+
+    unsigned ulen;             /* length of canonicalized user name */
+    unsigned alen;             /* length of canonicalized authid */
+
+    /* security layer information */
+    unsigned maxoutbuf;         /* Maximum buffer size, which will
+                                   produce buffer no bigger than the
+                                   negotiated SASL maximum buffer size */
+    sasl_ssf_t mech_ssf;   /* Should be set non-zero if negotiation of a
+                           * security layer was *attempted*, even if
+                           * the negotiation failed */
+    void *encode_context;
+    int (*encode)(void *context, const struct iovec *invec, unsigned numiov,
+                 const char **output, unsigned *outputlen);
+    void *decode_context;
+    int (*decode)(void *context, const char *input, unsigned inputlen,
+                 const char **output, unsigned *outputlen);
+    
+    /* Pointer to delegated (client's) credentials, if supported by
+       the SASL mechanism */
+    void *client_creds;
+
+    /* for additions which don't require a version upgrade; set to 0 */
+    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;
+
+
+
+/* Used by both client and server side plugins */
+typedef enum  {
+    SASL_INFO_LIST_START = 0,
+    SASL_INFO_LIST_MECH,
+    SASL_INFO_LIST_END
+} sasl_info_callback_stage_t;
+
+
+
+/******************************
+ * 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);
+
+typedef struct client_sasl_mechanism
+{
+    int version;
+
+    char *plugname;
+    const sasl_client_plug_t *plug;
+} client_sasl_mechanism_t;
+
+typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m,
+                                         sasl_info_callback_stage_t stage,
+                                         void *rock);
+
+/* Dump information about available client plugins */
+LIBSASL_API int sasl_client_plugin_info (const char *mech_list,
+       sasl_client_info_callback_t *info_cb,
+       void *info_cb_rock);
+
+
+/********************
+ * Server Functions *
+ ********************/
+
+/* log message formatting routine */
+typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...);
+
+/*
+ * input parameters to server SASL plugin
+ *
+ * created / destroyed by the glue code
+ *
+ */
+typedef struct sasl_server_params {
+    const char *service;       /* NULL = default service for user_exists
+                                  and setpass */
+    const char *appname;       /* name of calling application */
+    const char *serverFQDN;    /* server default fully qualified domain name
+                                * (e.g., gethostname) */
+    const char *user_realm;    /* realm for user (NULL = client supplied) */
+    const char *iplocalport;   /* server IP domain literal & port */
+    const char *ipremoteport;  /* client IP domain literal & port */
+
+    unsigned servicelen;       /* length of service */
+    unsigned applen;           /* length of appname */
+    unsigned slen;             /* length of serverFQDN */
+    unsigned urlen;            /* length of user_realm */
+    unsigned iploclen;         /* length of iplocalport */
+    unsigned ipremlen;         /* length of ipremoteport */
+
+    /* This indicates the level of logging desired.  See SASL_LOG_*
+     * in sasl.h
+     *
+     * Plug-ins can ignore this and just pass their desired level to
+     * the log callback.  This is primarily used to eliminate logging which
+     * might be a performance problem (e.g., full protocol trace) and
+     * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives
+     */
+    int log_level;
+
+    const sasl_utils_t *utils; /* SASL API utility routines --
+                                * for a particular sasl_conn_t,
+                                * MUST remain valid until mech_free is
+                                * called */
+    const sasl_callback_t *callbacks;  /* Callbacks from application */
+
+    /* application's security requirements */
+    sasl_security_properties_t props;
+    sasl_ssf_t external_ssf;   /* external SSF active */
+
+    /* Pointer to the function which takes the plaintext passphrase and
+     *  transitions a user to non-plaintext mechanisms via setpass calls.
+     *  (NULL = auto transition not enabled/supported)
+     *
+     *  If passlen is 0, it defaults to strlen(pass).
+     *  returns 0 if no entry added, 1 if entry added
+     */
+    int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen);
+
+    /* Canonicalize a user name from on-wire to internal format
+     *  added cjn 1999-09-21
+     *  Must be called once user name acquired if canon_user is non-NULL.
+     *  conn        connection context
+     *  user        user name from wire protocol (need not be NUL terminated)
+     *  ulen        length of user name from wire protocol (0 = strlen(user))
+     *  flags       for SASL_CU_* flags
+     *  oparams     the user, authid, ulen, alen, fields are
+     *              set appropriately after canonicalization/copying and
+     *              authorization of arguments
+     *
+     *  responsible for setting user, ulen, authid, and alen in the oparams
+     *  structure
+     *
+     *  default behavior is to strip leading and trailing whitespace, as
+     *  well as allocating space for and copying the parameters.
+     *
+     * results:
+     *  SASL_OK       -- success
+     *  SASL_NOMEM    -- out of memory
+     *  SASL_BADPARAM -- invalid conn
+     *  SASL_BADPROT  -- invalid user/authid
+     */
+    int (*canon_user)(sasl_conn_t *conn,
+                     const char *user, unsigned ulen,
+                     unsigned flags,
+                     sasl_out_params_t *oparams);
+    
+    /* auxiliary property context (see definitions in prop.h)
+     *  added cjn 2000-01-30
+     *
+     * NOTE: these properties are the ones associated with the
+     * canonicalized "user" (user to login as / authorization id), not
+     * the "authid" (user whose credentials are used / authentication id)
+     * Prefix the property name with a "*" if a property associated with
+     * the "authid" is interesting.
+     */
+    struct propctx *propctx;
+
+    /* for additions which don't require a version upgrade; set to 0 */
+    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;
+
+/* logging levels (more levels may be added later, if necessary):
+ */
+#define SASL_LOG_NONE  0       /* don't log anything */
+#define SASL_LOG_ERR   1       /* log unusual errors (default) */
+#define SASL_LOG_FAIL  2       /* log all authentication failures */
+#define SASL_LOG_WARN  3       /* log non-fatal warnings */
+#define SASL_LOG_NOTE  4       /* more verbose than LOG_WARN */
+#define SASL_LOG_DEBUG 5       /* more verbose than LOG_NOTE */
+#define SASL_LOG_TRACE 6       /* traces of internal protocols */
+#define SASL_LOG_PASS  7       /* traces of internal protocols, including
+                                * passwords */
+
+/* additional flags for setpass() function below:
+ */
+/*      SASL_SET_CREATE                     create user if pass non-NULL */
+/*      SASL_SET_DISABLE                    disable user */
+#define SASL_SET_REMOVE  SASL_SET_CREATE /* remove user if pass is NULL */
+
+/* features for server plug-in
+ */
+#define SASL_FEAT_SERVICE    0x0200 /* service-specific passwords supported */
+#define SASL_FEAT_GETSECRET  0x0400 /* sasl_server_{get,put}secret_t callbacks
+                                    * required by plug-in */
+
+/* a C object for a server mechanism
+ */
+typedef struct sasl_server_plug {
+    /* mechanism name */
+    const char *mech_name;
+
+    /* best mech additional security layer strength factor */
+    sasl_ssf_t max_ssf;
+
+    /* best security flags, as defined in sasl_security_properties_t */
+    unsigned security_flags;
+
+    /* features of plugin */
+    unsigned features;
+    
+    /* global state for mechanism */
+    void *glob_context;
+
+    /* create a new mechanism handler
+     *  glob_context  -- global context
+     *  sparams       -- server config params
+     *  challenge     -- server challenge from previous instance or NULL
+     *  challen       -- length of challenge from previous instance or 0
+     * out:
+     *  conn_context  -- connection context
+     *  errinfo       -- error information
+     *
+     * returns:
+     *  SASL_OK       -- successfully created mech instance
+     *  SASL_*        -- any other server error code
+     */
+    int (*mech_new)(void *glob_context,
+                   sasl_server_params_t *sparams,
+                   const char *challenge,
+                   unsigned challen,
+                   void **conn_context);
+    
+    /* perform one step in exchange
+     *
+     * returns:
+     *  SASL_OK       -- success, all done
+     *  SASL_CONTINUE -- success, one more round trip
+     *  SASL_*        -- any other server error code
+     */
+    int (*mech_step)(void *conn_context,
+                    sasl_server_params_t *sparams,
+                    const char *clientin,
+                    unsigned clientinlen,
+                    const char **serverout,
+                    unsigned *serveroutlen,
+                    sasl_out_params_t *oparams);
+    
+    /* dispose of a connection state
+     */
+    void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils);
+    
+    /* free global state for mechanism
+     *  mech_dispose must be called on all mechanisms first
+     */
+    void (*mech_free)(void *glob_context, const sasl_utils_t *utils);
+    
+    /* set a password (optional)
+     *  glob_context  -- global context
+     *  sparams       -- service, middleware utilities, etc. props ignored
+     *  user          -- user name
+     *  pass          -- password/passphrase (NULL = disable/remove/delete)
+     *  passlen       -- length of password/passphrase
+     *  oldpass       -- old password/passphrase (NULL = transition)
+     *  oldpasslen    -- length of password/passphrase
+     *  flags         -- see above
+     *
+     * returns:
+     *  SASL_NOCHANGE -- no change was needed
+     *  SASL_NOUSER   -- no entry for user
+     *  SASL_NOVERIFY -- no mechanism compatible entry for user
+     *  SASL_PWLOCK   -- password locked
+     *  SASL_DIABLED  -- account disabled
+     *  etc.
+     */
+    int (*setpass)(void *glob_context,
+                  sasl_server_params_t *sparams,
+                  const char *user,
+                  const char *pass, unsigned passlen,
+                  const char *oldpass, unsigned oldpasslen,
+                  unsigned flags);
+
+    /* query which mechanisms are available for user
+     *  glob_context  -- context
+     *  sparams       -- service, middleware utilities, etc. props ignored
+     *  user          -- NUL terminated user name
+     *  maxmech       -- max number of strings in mechlist (0 = no output)
+     * output:
+     *  mechlist      -- an array of C string pointers, filled in with
+     *                   mechanism names available to the user
+     *
+     * returns:
+     *  SASL_OK       -- success
+     *  SASL_NOMEM    -- not enough memory
+     *  SASL_FAIL     -- lower level failure
+     *  SASL_DISABLED -- account disabled
+     *  SASL_NOUSER   -- user not found
+     *  SASL_BUFOVER  -- maxmech is too small
+     *  SASL_NOVERIFY -- user found, but no mechanisms available
+     */
+    int (*user_query)(void *glob_context,
+                     sasl_server_params_t *sparams,
+                     const char *user,
+                     int maxmech,
+                     const char **mechlist);
+     
+    /* perform precalculations during a network round-trip
+     *  or idle period.  conn_context may be NULL (optional)
+     *  returns 1 if action taken, 0 if no action taken
+     */
+    int (*idle)(void *glob_context,
+               void *conn_context,
+               sasl_server_params_t *sparams);
+
+    /* check if mechanism is available
+     *  optional--if NULL, mechanism is available based on ENABLE= in config
+     *
+     *  If this routine sets conn_context to a non-NULL value, then the call
+     *  to mech_new will be skipped.  This should not be done unless
+     *  there's a significant performance benefit, since it can cause
+     *  additional memory allocation in SASL core code to keep track of
+     *  contexts potentially for multiple mechanisms.
+     *
+     *  This is called by the first call to sasl_listmech() for a
+     *  given connection context, thus for a given protocol it may
+     *  never be called.  Note that if mech_avail returns SASL_NOMECH,
+     *  then that mechanism is considered disabled for the remainder
+     *  of the session.  If mech_avail returns SASL_NOTDONE, then a
+     *  future call to mech_avail may still return either SASL_OK
+     *  or SASL_NOMECH.
+     *
+     *  returns SASL_OK on success,
+     *          SASL_NOTDONE if mech is not available now, but may be later
+     *                       (e.g. EXTERNAL w/o auth_id)
+     *          SASL_NOMECH if mech disabled
+     */
+    int (*mech_avail)(void *glob_context,
+                     sasl_server_params_t *sparams,
+                     void **conn_context);
+
+    /* for additions which don't require a version upgrade; set to 0 */
+    int (*spare_fptr2)();
+} sasl_server_plug_t;
+
+#define SASL_SERVER_PLUG_VERSION 4
+
+/* plug-in entry point:
+ *  utils         -- utility callback functions
+ *  plugname      -- name of plug-in (may be NULL)
+ *  max_version   -- highest server plug version supported
+ * returns:
+ *  out_version   -- server plug-in version of result
+ *  pluglist      -- list of mechanism plug-ins
+ *  plugcount     -- number of mechanism plug-ins
+ * results:
+ *  SASL_OK       -- success
+ *  SASL_NOMEM    -- failure
+ *  SASL_BADVERS  -- max_version too small
+ *  SASL_BADPARAM -- bad config string
+ *  ...
+ */
+typedef int sasl_server_plug_init_t(const sasl_utils_t *utils,
+                                   int max_version,
+                                   int *out_version,
+                                   sasl_server_plug_t **pluglist,
+                                   int *plugcount);
+
+/* 
+ * add a server plug-in
+ */
+LIBSASL_API int sasl_server_add_plugin(const char *plugname,
+                                      sasl_server_plug_init_t *splugfunc);
+
+
+typedef struct server_sasl_mechanism
+{
+    int version;
+    int condition; /* set to SASL_NOUSER if no available users;
+                     set to SASL_CONTINUE if delayed plugin loading */
+    char *plugname; /* for AUTHSOURCE tracking */
+    const sasl_server_plug_t *plug;
+    char *f;       /* where should i load the mechanism from? */
+} server_sasl_mechanism_t;
+
+typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m,
+                                         sasl_info_callback_stage_t stage,
+                                         void *rock);
+
+
+/* Dump information about available server plugins (separate functions are
+   used for canon and auxprop plugins) */
+LIBSASL_API int sasl_server_plugin_info (const char *mech_list,
+       sasl_server_info_callback_t *info_cb,
+       void *info_cb_rock);
+
+
+/*********************************************************
+ * user canonicalization plug-in -- added cjn 1999-09-29 *
+ *********************************************************/
+
+typedef struct sasl_canonuser {
+    /* optional features of plugin (set to 0) */
+    int features;
+
+    /* spare integer (set to 0) */
+    int spare_int1;
+
+    /* global state for plugin */
+    void *glob_context;
+
+    /* name of plugin */
+    char *name;
+
+    /* free global state for plugin */
+    void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils);
+
+    /* canonicalize a username
+     *  glob_context     -- global context from this structure
+     *  sparams          -- server params, note user_realm&propctx elements
+     *  user             -- user to login as (may not be NUL terminated)
+     *  len              -- length of user name (0 = strlen(user))
+     *  flags            -- for SASL_CU_* flags
+     *  out              -- buffer to copy user name
+     *  out_max          -- max length of user name
+     *  out_len          -- set to length of user name
+     *
+     *  note that the output buffers MAY be the same as the input buffers.
+     *
+     * returns
+     *  SASL_OK         on success
+     *  SASL_BADPROT    username contains invalid character
+     */
+    int (*canon_user_server)(void *glob_context,
+                            sasl_server_params_t *sparams,
+                            const char *user, unsigned len,
+                            unsigned flags,
+                            char *out,
+                            unsigned out_umax, unsigned *out_ulen);
+
+    int (*canon_user_client)(void *glob_context,
+                            sasl_client_params_t *cparams,
+                            const char *user, unsigned len,
+                            unsigned flags,
+                            char *out,
+                            unsigned out_max, unsigned *out_len);
+
+    /* for additions which don't require a version upgrade; set to 0 */
+    int (*spare_fptr1)();
+    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;
+
+    /* store the fields/values of an auxiliary property context (OPTIONAL)
+     *
+     * if ctx is NULL, just check if storing properties is enabled
+     *
+     * returns
+     *  SASL_OK         on success
+     *  SASL_FAIL       on failure
+     */
+    int (*auxprop_store)(void *glob_context,
+                        sasl_server_params_t *sparams,
+                        struct propctx *ctx,
+                        const char *user, unsigned ulen);
+} sasl_auxprop_plug_t;
+
+/* auxprop lookup flags */
+#define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties
+                                   * with non-zero len field.  If set,
+                                   * override value of those properties */
+#define SASL_AUXPROP_AUTHZID  0x02 /* if clear, we are looking up the
+                                   * authid flags (prefixed with *), otherwise
+                                   * we are looking up the authzid flags
+                                   * (no prefix) */
+
+#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);
+
+typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m,
+                                     sasl_info_callback_stage_t stage,
+                                     void *rock);
+
+/* Dump information about available auxprop plugins (separate functions are
+   used for canon and server authentication plugins) */
+LIBSASL_API int auxprop_plugin_info (const char *mech_list,
+       auxprop_info_callback_t *info_cb,
+       void *info_cb_rock);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SASLPLUG_H */
diff --git a/include/saslutil.h b/include/saslutil.h
new file mode 100755 (executable)
index 0000000..4755bf5
--- /dev/null
@@ -0,0 +1,92 @@
+/* saslutil.h -- various utility functions in SASL library
+ */
+
+#ifndef SASLUTIL_H
+#define SASLUTIL_H 1
+
+#ifndef SASL_H
+#include "sasl.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* base64 decode
+ *  in     -- input data
+ *  inlen  -- length of input data
+ *  out    -- output data (may be same as in, must have enough space)
+ *  outmax  -- max size of output buffer
+ * result:
+ *  outlen -- actual output length
+ *
+ * returns SASL_BADPROT on bad base64,
+ *  SASL_BUFOVER if result won't fit
+ *  SASL_OK on success
+ */
+LIBSASL_API int sasl_decode64(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen);
+
+/* base64 encode
+ *  in      -- input data
+ *  inlen   -- input data length
+ *  out     -- output buffer (will be NUL terminated)
+ *  outmax  -- max size of output buffer
+ * result:
+ *  outlen  -- gets actual length of output buffer (optional)
+ * 
+ * Returns SASL_OK on success, SASL_BUFOVER if result won't fit
+ */
+LIBSASL_API int sasl_encode64(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen);
+
+/* make a challenge string (NUL terminated)
+ *  buf      -- buffer for result
+ *  maxlen   -- max length of result
+ *  hostflag -- 0 = don't include hostname, 1 = include hostname
+ * returns final length or 0 if not enough space
+ */
+LIBSASL_API int sasl_mkchal(sasl_conn_t *conn, char *buf, 
+                           unsigned maxlen, unsigned hostflag);
+
+/* verify a string is valid UTF-8
+ * if len == 0, strlen(str) will be used.
+ * returns SASL_BADPROT on error, SASL_OK on success
+ */
+LIBSASL_API int sasl_utf8verify(const char *str, unsigned len);
+
+/* create random pool seeded with OS-based params */
+LIBSASL_API int sasl_randcreate(sasl_rand_t **rpool);
+
+/* free random pool from randcreate */
+LIBSASL_API void sasl_randfree(sasl_rand_t **rpool);
+
+/* seed random number generator */
+LIBSASL_API void sasl_randseed(sasl_rand_t *rpool, const char *seed,
+                              unsigned len);
+
+/* generate random octets */
+LIBSASL_API void sasl_rand(sasl_rand_t *rpool, char *buf, unsigned len);
+
+/* churn data into random number generator */
+LIBSASL_API void sasl_churn(sasl_rand_t *rpool, const char *data,
+                           unsigned len);
+
+/* erase a security sensitive buffer or password.
+ *   Implementation may use recovery-resistant erase logic.  
+ */
+LIBSASL_API void sasl_erasebuffer(char *pass, unsigned len);
+
+#ifdef WIN32
+/* Just in case a different DLL defines this as well */
+#if defined(NEED_GETOPT)
+LIBSASL_API int getopt(int argc, char **argv, char *optstring);
+#endif
+LIBSASL_API char * getpass(const char *prompt);
+#endif /* WIN32 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SASLUTIL_H */
diff --git a/java/CyrusSasl/ClientFactory.java b/java/CyrusSasl/ClientFactory.java
new file mode 100644 (file)
index 0000000..7e4f40e
--- /dev/null
@@ -0,0 +1,79 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+import javax.security.auth.callback.*;
+
+class ClientFactory implements SaslClientFactory
+{
+
+    public ClientFactory()
+    {
+
+    }
+
+    /* JNI functions  */
+    private native int jni_sasl_client_init(String appname);
+    private native int jni_sasl_client_new(String service,
+                                          String serverFQDN,
+                                          int secflags, boolean successdata);
+
+
+    private boolean init_client(String appname)
+    {
+       /* load library */
+       try {
+           System.loadLibrary("javasasl");
+       } catch (UnsatisfiedLinkError e) {
+           /* xxx */
+           System.out.println("Unable to load javasasl library");
+       }
+
+       jni_sasl_client_init(appname);    
+       
+       return true;
+    }
+
+    /* initialize the client when the class is loaded */
+    {
+       init_client("javasasl application");
+    }
+
+    public SaslClient createSaslClient(String[] mechanisms,
+                                      String authorizationId,
+                                      String protocol,
+                                      String serverName,
+                                      Hashtable props,
+                                      javax.security.auth.callback.CallbackHandler cbh)
+       throws SaslException
+    {
+       int cptr;
+       boolean successdata = true;
+
+       // here's a list of protocols we know don't have success data
+       if (protocol.equals("imap") ||
+           protocol.equals("pop3") ||
+           protocol.equals("smtp")) {
+           successdata = false;
+       }
+
+       cptr = jni_sasl_client_new(protocol, serverName, 0, successdata);
+
+       if (cptr == 0) {
+           throw new SaslException("Unable to create new Client connection object", new Throwable());
+       }
+
+       /* create the mechlist the way our library likes to see it */
+       String mechlist="";
+
+       for (int lup=0;lup<mechanisms.length;lup++) {
+           mechlist+=mechanisms[lup];
+           mechlist+=" ";
+       }
+
+       
+       return new GenericClient(cptr, mechlist,props,cbh);
+    }
+
+
+
+}
diff --git a/java/CyrusSasl/GenericClient.java b/java/CyrusSasl/GenericClient.java
new file mode 100644 (file)
index 0000000..71d87bd
--- /dev/null
@@ -0,0 +1,197 @@
+package CyrusSasl;
+
+import javax.security.auth.callback.*;
+import java.io.*;
+
+public class GenericClient extends GenericCommon implements SaslClient 
+{
+
+    private byte[]initial_response;
+    private String mechanism;
+    private boolean hasinitresp;
+    private javax.security.auth.callback.CallbackHandler cbh;
+
+    GenericClient(int cptr, String mechlist,
+                 java.util.Hashtable props,
+                 javax.security.auth.callback.CallbackHandler cbh)
+    {
+       ptr=cptr;
+       this.cbh = cbh;
+
+       /* set properties */
+       super.setcommonproperties(props);
+       
+       initial_response = jni_sasl_client_start(cptr, mechlist);
+    }
+
+    private native byte[] jni_sasl_client_start(int ptr,
+                                               String mechlist);
+
+    /**
+     * Perform a step. start() must have been preformed succesfully
+     * before this step() can be called. A client should call this
+     * method until it receives notification from the server that
+     * authentication is complete. Any protocol specific decoding (such
+     * as base64 decoding) must be done before calling step(). The
+     * return byte array should be encoded by the protocol specific
+     * method then sent to the server
+     *
+     * @param challenge byte[] from server (must be protocol specific decode before)
+     * @exception saslException sasl exception
+     * @return the byte[] you should send to the server */
+    
+    public byte[] evaluateChallenge(byte[] challenge) throws SaslException
+    {
+       /* xxx this should check for empty challenge & existing initial
+          sasl challenge */
+       byte[] out=null;
+
+       if (complete && challenge == null) {
+           /* we're already done and there's no challenge */
+           return null;
+       }
+
+       if (challenge==null) {
+           out=jni_sasl_client_step(ptr, null, 0);
+       } else {
+           out=jni_sasl_client_step(ptr, challenge, challenge.length);
+       }
+       
+       return out;
+    }
+
+    private native byte[] jni_sasl_client_step(int ptr,
+                                              byte[] in,
+                                              int inlen);
+
+
+    public boolean hasInitialResponse()
+    {
+       return hasinitresp;
+    }
+       
+    /**
+     * Use this method to obtain the name of the mechanism being
+     * negotiated with the server. After giving start() a list of
+     * mechanisms one will be chosen. Use this method to determine which
+     * one if being used if any.
+     *
+     * @return the mechanism currently negotiated or already negotiated */
+
+    public String getMechanismName()
+    {
+       return mechanism;
+    }
+
+    /* called from C layer */
+    private void callback_setmechanism(String mech, int initresp)
+    {
+       mechanism = mech;
+       hasinitresp = initresp != 0;
+    }
+
+    private String userid;
+    private String authid;
+    private String password;
+    private String realm;
+
+    private void do_callbacks(int wantuid, int wantaid, int wantpass, int wantrealm) throws SaslException
+    {
+       int numcb = wantuid+wantaid+wantpass+wantrealm;
+
+       Callback[] cbs = new Callback[numcb];
+       int pos = 0;
+
+       NameCallback nc = null;
+       NameCallback nc2 = null;
+       PasswordCallback pc = null;
+       RealmCallback rc = null;
+
+       if (wantuid==1) {
+           nc = new NameCallback("Please enter your authorization id");
+           cbs[pos] = nc;
+           pos++;
+       }
+
+       if (wantaid==1) {
+           nc2 = new NameCallback("Please enter your authentication id");
+           cbs[pos] = nc2;
+           pos++;
+       }
+
+       if (wantpass==1) {
+           pc = new PasswordCallback("Please enter your password", false);
+           cbs[pos] = pc;
+           pos++;
+       }
+
+       if (wantrealm==1) {
+           rc = new RealmCallback("Please enter your realm");
+           cbs[pos] = rc;
+           pos++;
+       }
+       
+       try {
+           cbh.handle(cbs);
+       } catch (UnsupportedCallbackException e) {
+           throw new SaslException("Unsupported callback",null);
+       } catch (IOException e) {
+           throw new SaslException("IO exception",null);
+       }
+
+       if (nc!=null) {
+           this.userid = nc.getName();
+       }
+       if (nc2!=null) {
+           this.authid = nc2.getName();
+       }
+       if (pc!=null) {
+           this.password = new String(pc.getPassword());
+       }
+       if (rc!=null) {
+           this.realm = rc.getRealm();
+       }
+    }
+
+    private String get_userid(int a)
+    {
+       return userid;
+    }
+    private String get_authid(int a)
+    {
+       return authid;
+    }
+    private String get_password(int a)
+    {
+       return password;
+    }
+    private String get_realm(int a)
+    {
+       return realm;
+    }
+
+    public InputStream getInputStream(InputStream source) throws IOException
+    {
+       if (getSecurity() > 0) {
+           return new SaslInputStream(source,this);
+       } else {
+           // no security layer, no indirection needed
+           return source;
+       }
+    }
+
+    public OutputStream getOutputStream(OutputStream dest) throws IOException
+    {
+       if (getSecurity() > 0) {
+           return new SaslOutputStream(dest,this);
+       } else {
+           // no security layer, no indirection needed
+           return dest;
+       }
+    }
+
+    public byte[] createInitialResponse(){
+       /* xxx this is deprecated */
+       return initial_response;
+    }
+}
diff --git a/java/CyrusSasl/GenericCommon.java b/java/CyrusSasl/GenericCommon.java
new file mode 100644 (file)
index 0000000..39ef0d2
--- /dev/null
@@ -0,0 +1,294 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+import java.net.*;
+
+/**
+ * @version 1.0
+ * @author Tim Martin
+ */
+
+public abstract class GenericCommon
+{
+
+  /* These are the jni functions called by the routines in common
+   * see javasasl.c for their implementations
+   */
+
+    private native void jni_sasl_set_prop_string(int ptr, int propnum, String value);
+    private native void jni_sasl_set_prop_int(int ptr, int propnum, int value);
+    private native void jni_sasl_set_prop_bytes(int ptr, int propnum, byte[] value);
+    private native void jni_sasl_set_server(int ptr, byte []ipnum, int port);
+    private native void jni_sasl_set_client(int ptr, byte []ipnum, int port);
+    private native void jni_sasl_setSecurity(int ptr, int minssf, int maxssf);
+    private native int jni_sasl_getSecurity(int ptr);
+    private native byte[] jni_sasl_encode(int ptr, byte[] in,int len);
+    private native byte[] jni_sasl_decode(int ptr, byte[] in,int len);
+    private native void jni_sasl_dispose(int ptr);
+
+  /**
+   * security layer security strength factor
+   */
+  public static int SASL_SSF      =1;    
+
+  public static int SASL_MAXOUTBUF=2;     /* security layer max output buf unsigned */  
+  public static int SASL_REALM    =3;     /* server authentication realm used */
+  public static int SASL_GETOPTCTX=4;     /* context for getopt callback */
+
+
+    /**
+     * Local sockaddr_in (use setServer and setClient to set this)
+     */
+  public static int SASL_IP_LOCAL =5;   
+
+    /**
+     * Remote sockaddr_in (use setClient and setServer to set this)
+     */
+
+  public static int SASL_IP_REMOTE =6;  
+
+    /**
+     * External security factor (use setSecurity to set this)
+     */
+  public static int SASL_SSF_EXTERNAL=100;  
+  public static int SASL_SEC_PROPS   =101;  /* sasl_security_properties_t */
+
+
+    int ptr;                   // this is the actual pointer to sasl_conn_t
+    int ssfactive;             // active ssf on this connection
+
+  boolean finished;
+
+  public boolean done() { return finished; }
+
+  /**
+   * Set a SASL property that takes a string value
+   *
+   * @param PROPERTY one of the property constants
+   * @param value string value
+   */
+
+  public void setproperty(int PROPERTY, String value)
+  {
+    jni_sasl_set_prop_string(ptr,PROPERTY,value);
+  }
+
+  /**
+   * Set a SASL property that takes a integer value
+   *
+   * @param PROPERTY one of the property constants
+   * @param value integer value
+   */
+
+  public void setproperty(int PROPERTY, int value)
+  {
+    jni_sasl_set_prop_int(ptr,PROPERTY,value);
+  }
+
+  /**
+   * Set a SASL property that takes a byte[] value
+   *
+   * @param PROPERTY one of the property constants
+   * @param value byte[] value
+   */
+
+  public void setproperty(int PROPERTY, byte[] value)
+  {
+    jni_sasl_set_prop_bytes(ptr,PROPERTY,value);
+  }
+
+  /**
+   * Set the SASL properties for the server
+   * This sets the IP address and port
+   *
+   * @param name String of name of server (e.g. cyrus.andrew.cmu.edu)
+   * @param port port connected to on that server
+   */
+
+  private boolean setRemoteIP(String name,int port)
+  {
+    byte[]ip=null;
+    try {
+      InetAddress server=InetAddress.getByName(name);
+      ip=server.getAddress();    
+    } catch (UnknownHostException e) { 
+      return false;
+    }
+
+    jni_sasl_set_server(ptr, ip, port);
+    return true;
+  }
+
+  /**
+   * Set the SASL properties for the client
+   * This sets the IP address and port
+   *
+   * @param name String of local cannonical name (e.g. myhostname.andrew.cmu.edu)
+   * @param port port connecting
+   */
+
+  private boolean setLocalIP(String name, int port)
+  {
+    byte[]ip=null;
+    try {
+      InetAddress server=InetAddress.getByName(name);
+      ip=server.getAddress();    
+    } catch (UnknownHostException e) { 
+      return false;
+    }
+
+    jni_sasl_set_client(ptr, ip, port);
+    return true;
+  }
+
+  /**
+   * Set the SASL properties for the client
+   * This sets the IP address and port
+   *
+   * @param local local InetAdress
+   * @param port port connecting
+   */
+
+  public boolean setClient(InetAddress local,int port)
+  {
+    byte[]ip=local.getAddress();
+
+    jni_sasl_set_client(ptr, ip, port);
+
+    return true;
+  }
+
+  /**
+   * Set the SASL properties for the client
+   * This sets the IP address and port
+   * The local IP address is determined with InetAddress.getLocalHost()
+   *
+   * @param port port connecting
+   */
+
+  public boolean setClient(int port)
+  {
+    try {
+      return setClient(InetAddress.getLocalHost(),port);
+    } catch (UnknownHostException e) {
+      return false;
+    }
+  }
+
+  /**
+   * Sets the security properties for the session
+   *
+   * @param external external security strength
+   * @param minssf minimum security needed
+   * @param maxssf maximum security to negotiate
+   *
+   * @return if the propery was set sucessfully or not
+   */
+
+
+    public boolean setSecurity(int external, int minssf, int maxssf)
+    {
+       /* setproperty(SASL_SSF_EXTERNAL, external); */
+       
+       jni_sasl_setSecurity(ptr,minssf,maxssf);
+       
+       return true;
+    }
+
+    public int getSecurity() {
+       return jni_sasl_getSecurity(ptr);
+    }
+
+  /**
+   * Encode a String with the negotiated layer
+   *
+   * @param in String to be encoded
+   * @return the encoded string represented at a byte[] 
+   */
+  public byte[] encode(byte[] in)
+  {
+    
+    byte[] out=jni_sasl_encode(ptr,in,in.length);
+
+    return out;
+  }
+                                           
+  /**
+   * Decode a byte[] with the negotiated layer
+   *
+   * @param in byte[] to be decoded
+   * @param len number of bytes to be decoded
+   * @return the decoded string represented at a byte[]
+   */
+  public byte[] decode(byte[] in, int len)
+  {
+    
+    byte[] out=jni_sasl_decode(ptr,in,len);
+
+    return out;
+  }
+
+  /**
+   * Decode a String with the negotiated layer. NOTE: Be careful with
+   * this function. International or high ascii characters may do strange
+   * things. The byte[] method is preferred
+   *
+   * @param in String to be decoded
+   * @return the decoded string represented at a byte[]
+   */
+  public byte[] decode(String in)
+  {
+    return decode(in.getBytes(),in.length());
+  }
+
+  protected void setcommonproperties(Hashtable props)
+  {
+      int i_ssfmin = 0;
+      String s_ssfmin=(String) props.get("javax.security.sasl.encryption.minimum");
+      if (s_ssfmin!=null) i_ssfmin = Integer.parseInt(s_ssfmin);
+
+      int i_ssfmax = 256;
+      String s_ssfmax=(String) props.get("javax.security.sasl.encryption.maximum");
+      if (s_ssfmax!=null) i_ssfmax = Integer.parseInt(s_ssfmax);
+
+      
+      int i_external = 0;
+      /*      String external=(String) props.getProperty("security.policy.encryption.external",
+       */
+
+      setSecurity(i_external,
+                 i_ssfmin,
+                 i_ssfmax);
+      
+      String iplocal  = (String) props.get("javax.security.sasl.ip.local");     
+      if (iplocal!=null) setLocalIP(iplocal,0);
+
+      String ipremote = (String) props.get("javax.security.sasl.ip.remote");
+      if (ipremote!=null) setRemoteIP(ipremote,0);
+   
+      /*    String maxbuf=props.getProperty("security.maxbuf","65000"); */
+    /* xxx this raises an exception for some reason
+       setproperty(SASL_MAXOUTBUF,Integer.parseInt(maxbuf)); */
+  }
+
+
+    final protected void finalize () throws Throwable 
+    {
+       jni_sasl_dispose(ptr);
+    }
+
+    protected boolean complete = false;
+
+    public boolean isComplete()
+    {
+       return complete;
+    }
+
+    /* called by JNI layer */
+    public void setcomplete(int a)
+    {
+       complete = true;
+    }
+
+
+}
diff --git a/java/CyrusSasl/GenericServer.java b/java/CyrusSasl/GenericServer.java
new file mode 100644 (file)
index 0000000..7baa207
--- /dev/null
@@ -0,0 +1,86 @@
+package CyrusSasl;
+
+import javax.security.auth.callback.*;
+import java.io.*;
+
+public class GenericServer extends GenericCommon implements SaslServer 
+{
+
+    private byte[]initial_response;
+    private String mechanism;
+    private javax.security.auth.callback.CallbackHandler cbh;
+    private boolean started = false;
+
+    /* JNI functions */
+    private native byte[] jni_sasl_server_start(int ptr,
+                                               String mech, byte[]in, int inlen);
+
+    private native byte[] jni_sasl_server_step(int ptr,
+                                              byte[] in,
+                                              int inlen);
+
+    GenericServer(int cptr, String mechanism,
+                 java.util.Hashtable props,
+                 javax.security.auth.callback.CallbackHandler cbh)
+    {
+       ptr=cptr;
+       this.cbh = cbh;
+       this.mechanism = mechanism;
+       started = false;
+
+
+       /* set properties */
+       super.setcommonproperties(props);       
+    }
+
+
+    public byte[] evaluateResponse(byte[] response) throws SaslException
+    {
+       byte[] out;
+       byte[] in;
+       int inlen;
+
+       if (response == null)
+       {
+           in=null;
+           inlen = 0;
+       } else {
+           in = response;
+           inlen = response.length;
+       }
+
+       if (started == false) {
+           out=jni_sasl_server_start(ptr, mechanism,in,inlen);
+           started = true;
+       } else {
+           out=jni_sasl_server_step(ptr,in,inlen);
+       }
+
+       return out;
+    }
+    
+    public String getMechanismName()
+    {
+       return mechanism;
+    }
+
+    public InputStream getInputStream(InputStream source) throws IOException
+    {
+       if (getSecurity() > 0) {
+           return new SaslInputStream(source,this);
+       } else {
+           // no security layer, no indirection needed
+           return source;
+       }
+    }
+
+    public OutputStream getOutputStream(OutputStream dest) throws IOException
+    {
+       if (getSecurity() > 0) {
+           return new SaslOutputStream(dest,this);
+       } else {
+           // no security layer, no indirection needed
+           return dest;
+       }
+    }
+}
diff --git a/java/CyrusSasl/Makefile.am b/java/CyrusSasl/Makefile.am
new file mode 100644 (file)
index 0000000..be1ffc1
--- /dev/null
@@ -0,0 +1,64 @@
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+javasasl_version = 1:0:0
+
+javasasldir = $(prefix)/lib/java/classes/sasl/CyrusSasl
+javahtmldir = $(prefix)/html/sasl
+
+INCLUDES=-I$(top_srcdir)/include $(JAVA_INCLUDES)
+
+javasasl_JAVA = Sasl.java GenericClient.java \
+               ClientFactory.java \
+               GenericCommon.java SaslClient.java \
+               SaslClientFactory.java SaslException.java \
+               SaslInputStream.java SaslOutputStream.java\
+               SaslUtils.java ServerFactory.java \
+                SaslServerFactory.java SaslServer.java \
+                GenericServer.java
+EXTRA_DIST = $(javasasl_JAVA)
+CLASSES = $(javasasl_JAVA:.java=.class)
+
+lib_LTLIBRARIES = libjavasasl.la
+libjavasasl_la_SOURCES = javasasl.h javasasl.c
+libjavasasl_la_LDFLAGS = -export_dynamic -L../../lib/.libs -lsasl2 -version-info $(javasasl_version) $(wildcard ../lib/*.lo)
+BUILT_SOURCES = javasasl.h $(CLASSES)
+
+$(srcdir)/javasasl.c: javasasl.h
+
+javasasl.h: $(CLASSES)
+       $(CLASSPATH_ENV) $(JAVAH) -o $@ -jni $(patsubst %.class,CyrusSasl.%,$^)
+
+# force build of class files
+$(CLASSES): classjavasasl.stamp
+
+#install-data-local:
+# xxx broken
+#      $(mkinstalldirs) $(javahtmldir)
+#      $(CLASSPATH_ENV) $(JAVADOC) -d $(javahtmldir) sasl
+#      -if test ! -h $(javahtmldir)/images; \
+#      then \
+#        $(LN_S) $(JAVA_BASE)/docs/api/images $(javahtmldir)/images; \
+#      fi
diff --git a/java/CyrusSasl/Makefile.in b/java/CyrusSasl/Makefile.in
new file mode 100644 (file)
index 0000000..bdd9058
--- /dev/null
@@ -0,0 +1,584 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+javasasl_version = 1:0:0
+
+javasasldir = $(prefix)/lib/java/classes/sasl/CyrusSasl
+javahtmldir = $(prefix)/html/sasl
+
+INCLUDES = -I$(top_srcdir)/include $(JAVA_INCLUDES)
+
+javasasl_JAVA = Sasl.java GenericClient.java \
+               ClientFactory.java \
+               GenericCommon.java SaslClient.java \
+               SaslClientFactory.java SaslException.java \
+               SaslInputStream.java SaslOutputStream.java\
+               SaslUtils.java ServerFactory.java \
+                SaslServerFactory.java SaslServer.java \
+                GenericServer.java
+
+EXTRA_DIST = $(javasasl_JAVA)
+CLASSES = $(javasasl_JAVA:.java=.class)
+
+lib_LTLIBRARIES = libjavasasl.la
+libjavasasl_la_SOURCES = javasasl.h javasasl.c
+libjavasasl_la_LDFLAGS = -export_dynamic -L../../lib/.libs -lsasl2 -version-info $(javasasl_version) $(wildcard ../lib/*.lo)
+BUILT_SOURCES = javasasl.h $(CLASSES)
+subdir = java/CyrusSasl
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libjavasasl_la_LIBADD =
+am_libjavasasl_la_OBJECTS = javasasl.lo
+libjavasasl_la_OBJECTS = $(am_libjavasasl_la_OBJECTS)
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/javasasl.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libjavasasl_la_SOURCES)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(libjavasasl_la_SOURCES)
+
+all: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/CyrusSasl/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f="`echo $$p | sed -e 's|^.*/||'`"; \
+           echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+           $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+         else :; fi; \
+       done
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+         $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libjavasasl.la: $(libjavasasl_la_OBJECTS) $(libjavasasl_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libjavasasl_la_LDFLAGS) $(libjavasasl_la_OBJECTS) $(libjavasasl_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/javasasl.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+JAVACFLAGS =
+CLASSPATH_ENV = CLASSPATH=$(JAVAROOT):$(srcdir)/$(JAVAROOT):$$CLASSPATH
+
+classjavasasl.stamp: $(javasasl_JAVA)
+       @if test -n "$?"; then \
+         echo '$(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) $?' ; \
+         $(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) \
+           $(AM_JAVACFLAGS) $(JAVACFLAGS) $?; \
+       else :; fi
+       echo timestamp > classjavasasl.stamp
+install-javasaslJAVA: classjavasasl.stamp
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(javasasldir)
+       for p in *.class; do \
+         echo " $(INSTALL_DATA) $$p $(DESTDIR)$(javasasldir)/$$p"; \
+         $(INSTALL_DATA) $$p $(DESTDIR)$(javasasldir)/$$p; \
+       done
+
+uninstall-javasaslJAVA:
+       @$(NORMAL_UNINSTALL)
+       @for p in *.class; do \
+         echo " rm -f $(DESTDIR)$(javasasldir)/$$p"; \
+         rm -f $(DESTDIR)$(javasasldir)/$$p; \
+       done
+
+clean-javasaslJAVA:
+       -rm -f *.class classjavasasl.stamp
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LTLIBRARIES) classjavasasl.stamp
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(javasasldir)
+install: $(BUILT_SOURCES)
+       $(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+       -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-javasaslJAVA clean-libLTLIBRARIES \
+       clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-javasaslJAVA
+
+install-exec-am: install-libLTLIBRARIES
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-javasaslJAVA \
+       uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-javasaslJAVA clean-libLTLIBRARIES clean-libtool ctags \
+       distclean distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am \
+       install-javasaslJAVA install-libLTLIBRARIES install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
+       pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am \
+       uninstall-javasaslJAVA uninstall-libLTLIBRARIES
+
+
+$(srcdir)/javasasl.c: javasasl.h
+
+javasasl.h: $(CLASSES)
+       $(CLASSPATH_ENV) $(JAVAH) -o $@ -jni $(patsubst %.class,CyrusSasl.%,$^)
+
+# force build of class files
+$(CLASSES): classjavasasl.stamp
+
+#install-data-local:
+# xxx broken
+#      $(mkinstalldirs) $(javahtmldir)
+#      $(CLASSPATH_ENV) $(JAVADOC) -d $(javahtmldir) sasl
+#      -if test ! -h $(javahtmldir)/images; \
+#      then \
+#        $(LN_S) $(JAVA_BASE)/docs/api/images $(javahtmldir)/images; \
+#      fi
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/CyrusSasl/Sasl.java b/java/CyrusSasl/Sasl.java
new file mode 100644 (file)
index 0000000..5368757
--- /dev/null
@@ -0,0 +1,122 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+import javax.security.auth.callback.*;
+
+public class Sasl
+{
+
+    private static SaslClientFactory client_factory = null;
+    private static SaslServerFactory server_factory = null;
+
+    /*
+   Creates a SaslClient using the parameters supplied. It returns null
+   if no SaslClient can be created using the parameters supplied. Throws
+   SaslException if it cannot create a SaslClient because of an error.
+
+   The algorithm for selection is as follows:
+
+   1. If a factory has been installed via setSaslClientFactory(), try it
+      first. If non-null answer produced, return it.
+   2. Use the packages listed in the javax.security.sasl.client.pkgs
+      property from props to load in a factory and try to create a
+      SaslClient, by looking for a class named ClientFactory. Repeat
+      this for each package on the list until a non-null answer is
+      produced. If non-null answer produced, return it.
+   3. Repeat previous step using the javax.security.sasl.client.pkgs
+      System property.
+   4. If no non-null answer produced, return null.
+
+   Parameters are:
+
+      mechanisms     The non-null list of mechanism names to try. Each
+                     is the IANA-registered name of a SASL mechanism.
+                     (e.g. "GSSAPI", "CRAM-MD5").
+
+
+
+      authorizationID The possibly null protocol-dependent
+                     identification to be used for authorization, e.g.
+                     user name or distinguished name. When the SASL
+                     authentication completes successfully, the entity
+                     named by authorizationId is granted access. If
+                     null, access is granted to a protocol-dependent
+                     default (for example, in LDAP this is the DN in
+                     the bind request).
+
+      protocol       The non-null string name of the protocol for
+                     which the authentication is being performed, e.g
+                     "pop", "ldap".
+
+      serverName     The non-null fully qualified host name of the
+                     server to authenticate to.
+
+      props          The possibly null additional configuration
+                     properties for the session, e.g.
+
+    */
+
+    public static SaslClient
+       createSaslClient(String[] mechanisms,
+                        String authorizationID,
+                        String protocol,
+                        String serverName,
+                        Hashtable props,
+                        javax.security.auth.callback.CallbackHandler cbh)    throws SaslException
+    {
+       if (client_factory == null)
+       {
+           client_factory = new ClientFactory();
+       }
+
+       return client_factory.createSaslClient(mechanisms,
+                                              authorizationID,
+                                              protocol,
+                                              serverName,
+                                              props,
+                                              cbh);
+    }
+
+    public static void setSaslClientFactory(SaslClientFactory fac) {
+       client_factory = fac;
+    }
+
+    public static void setSaslServerFactory(SaslServerFactory fac) {
+       server_factory = fac;
+    }
+
+
+    public static SaslServer CreateSaslServer(String mechanism,
+                                             String protocol,
+                                             String serverName,
+                                             Hashtable props,
+                                             javax.security.auth.callback.CallbackHandler cbh)
+                                             throws SaslException
+    {
+       if (server_factory == null)
+       {
+           server_factory = new ServerFactory();
+       }
+
+       return server_factory.createSaslServer(mechanism,
+                                              protocol,
+                                              serverName,
+                                              props,
+                                              cbh);
+    }
+
+    public static String[] getMechanismNames()
+    {
+       if (server_factory == null)
+       {
+           server_factory = new ServerFactory();
+       }
+
+       return server_factory.getMechanismNames();      
+    }
+
+
+
+
+
+}
diff --git a/java/CyrusSasl/SaslClient.java b/java/CyrusSasl/SaslClient.java
new file mode 100644 (file)
index 0000000..1115564
--- /dev/null
@@ -0,0 +1,23 @@
+package CyrusSasl;
+
+import java.io.*;
+
+public interface SaslClient
+{
+    public byte[]
+       evaluateChallenge(byte[] challenge)
+       throws SaslException;
+
+
+    public boolean hasInitialResponse();
+       
+    public boolean isComplete();
+
+    public String getMechanismName();
+
+    public InputStream getInputStream(InputStream source) throws IOException;
+
+    public OutputStream getOutputStream(OutputStream dest) throws IOException;
+
+
+}
diff --git a/java/CyrusSasl/SaslClientFactory.java b/java/CyrusSasl/SaslClientFactory.java
new file mode 100644 (file)
index 0000000..7f8146e
--- /dev/null
@@ -0,0 +1,16 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+
+public interface SaslClientFactory
+{
+
+    public SaslClient createSaslClient(String[] mechanisms,
+                                      String authorizationId,
+                                      String protocol,
+                                      String serverName,
+                                      Hashtable props,
+                                      javax.security.auth.callback.CallbackHandler cbh)
+       throws SaslException;
+
+}
diff --git a/java/CyrusSasl/SaslException.java b/java/CyrusSasl/SaslException.java
new file mode 100644 (file)
index 0000000..008334d
--- /dev/null
@@ -0,0 +1,41 @@
+package CyrusSasl;
+
+import java.io.IOException;
+
+public class SaslException extends IOException
+{
+    private int foo;
+
+    public SaslException()
+    {
+       super();
+       foo = 3;
+
+    }
+
+    public SaslException(String message)
+    {
+       super(message);
+    }
+    
+    public SaslException(String message,
+                        Throwable ex)
+    {
+
+    }
+
+    public Throwable getException()
+    {
+       return null;
+    }
+
+    public void printStackTrace()
+    {
+
+    }
+
+
+
+
+
+}
diff --git a/java/CyrusSasl/SaslInputStream.java b/java/CyrusSasl/SaslInputStream.java
new file mode 100644 (file)
index 0000000..9ddaf3d
--- /dev/null
@@ -0,0 +1,208 @@
+package CyrusSasl;
+
+import java.io.*;
+
+public class SaslInputStream extends InputStream
+{
+    static final boolean DoEncrypt = true;
+    static final boolean DoDebug = false;
+    private static int BUFFERSIZE = 16384;
+
+    // if bufferend < bufferstart, we've wrapped around
+    private byte[] buffer=new byte[BUFFERSIZE];
+    private int bufferstart = 0;
+    private int bufferend = 0;
+    private int size = 0;
+
+    private GenericCommon conn;
+
+    public InputStream in;
+    
+    public SaslInputStream(InputStream in, GenericCommon conn)
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG constructing SaslInputStream");
+       }
+       this.in = in;
+       this.conn = conn;
+    }
+
+    public synchronized int available() throws IOException
+    {
+       int ina = in.available();
+       if (ina > 1) ina = 1;
+       
+       return size + ina;
+    }
+    
+    private void buffer_add(byte[] str,int len) throws IOException
+    {
+       if (str == null) {
+           // nothing to add
+           return;
+       }
+       
+       byte[] b = str;
+       
+       /* xxx this can be optimized */
+       for (int lup=0;lup<len;lup++) {
+           buffer[bufferend]=b[lup];
+           bufferend = (bufferend + 1) % BUFFERSIZE;
+
+           size++;
+           if (size >= BUFFERSIZE) {
+               throw new IOException();
+           }
+       }
+    }
+    
+    private void buffer_add(byte[] str) throws IOException
+    {
+       buffer_add(str,str.length);
+    }
+
+    private void readsome() throws IOException
+    {
+       int len=in.available();
+
+       if (DoDebug) {
+           System.err.println("DEBUG in readsome(), avail " + len);
+       }
+
+       if (len > BUFFERSIZE || len == 0)
+           len = BUFFERSIZE;
+       
+       byte[]tmp=new byte[len];
+       len = in.read(tmp);
+       
+       if (len>0) {
+           if (DoEncrypt) {
+               buffer_add( conn.decode(tmp,len) );
+           } else {
+               buffer_add(tmp, len);
+           }
+       }
+    }
+
+    public synchronized void close() throws IOException
+    {
+       super.close();
+    }
+
+    public synchronized void reset() throws IOException
+    {
+       throw new IOException();
+    }
+
+    public synchronized void mark(int readlimit)
+    {
+       return;
+    }
+    
+    public boolean markSupported()
+    {
+       return false;
+    }
+
+    /* read a single byte */
+    public synchronized int read() throws IOException
+    {
+       int ret;
+       
+       if (DoDebug) {
+           System.err.println("DEBUG in read(), size " + size);
+       }
+       if (size == 0) {
+           readsome();
+       }
+       
+       if (size == 0) {
+           if (DoDebug) {
+               System.err.println("DEBUG read() returning -1");
+           }
+           return -1;
+       }
+       
+       ret = buffer[bufferstart];
+       bufferstart = (bufferstart + 1) % BUFFERSIZE;
+       size--;
+
+       if (DoDebug) {
+           System.err.println("DEBUG read() returning " + ret);
+       }
+       return ret;
+    }
+
+    public synchronized int read(byte b[]) throws IOException
+    {
+       return read(b,0,b.length);
+    }
+
+    public synchronized int read(byte b[],
+                                int off,
+                                int len) throws IOException 
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG in read(b, off, len), size " + size);
+       }
+       if (off < 0 || len < 0) {
+           throw new IndexOutOfBoundsException();
+       }
+       if (len == 0) {
+           return 0;
+       }
+
+       // block only if we need to
+       if (size == 0) {
+           readsome();
+           if (size == 0) {
+               if (DoDebug) {
+                   System.err.println("DEBUG read(b, off, len) returning -1");
+               }
+               return -1;
+           }
+       }
+
+       int l;
+       for (l = off; l < len + off; l++) {
+           if (bufferstart == bufferend) break;
+
+           b[l] = buffer[bufferstart];
+           bufferstart = (bufferstart + 1) % BUFFERSIZE;
+           size--;
+       }
+
+       if (DoDebug) {
+           System.err.println("DEBUG read() returning " + (l - off));
+       }
+       return l - off;
+    }
+    
+    public synchronized long skip(long n) throws IOException
+    {
+       if (n<=0) return 0;
+
+       long toskip = n;
+       while (toskip > 0) {
+           if (size == 0) {
+               readsome();
+               if (size == 0) {
+                   return n - toskip;
+               }
+           }
+           
+           if (toskip > size) {
+               toskip -= size;
+               bufferstart = bufferend = size = 0;
+           } else {
+               // we've got all the data we need to skip
+               size -= toskip;
+               bufferstart = (int) ((bufferstart + toskip) % BUFFERSIZE);
+           }
+       }
+       
+       // skipped the full amount
+       return n;
+    }
+}
+
diff --git a/java/CyrusSasl/SaslOutputStream.java b/java/CyrusSasl/SaslOutputStream.java
new file mode 100644 (file)
index 0000000..558ab57
--- /dev/null
@@ -0,0 +1,109 @@
+package CyrusSasl;
+
+import java.io.*;
+
+public class SaslOutputStream extends OutputStream
+{
+    static final boolean DoEncrypt = true;
+    static final boolean DoDebug = false;
+
+    private static int MAXBUFFERSIZE=1000;
+    private GenericCommon conn;
+    OutputStream out;
+    
+    private byte[] buffer=new byte[MAXBUFFERSIZE];
+    private int buffersize=0;
+
+    public SaslOutputStream(OutputStream out, GenericCommon conn)
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG constructing SaslOutputStream");
+       }
+       this.conn=conn;
+       this.out=out;
+    }
+
+    private void write_if_size() throws IOException
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG write_if_size(): buffersize " + 
+                              buffersize);
+       }
+       if ( buffersize >=MAXBUFFERSIZE)
+           flush();
+    }
+
+    public synchronized void write(int b) throws IOException
+    {
+       buffer[buffersize]=(byte) b;
+       buffersize++;
+       write_if_size();
+    }
+
+    public synchronized void write(byte b[]) throws IOException
+    {
+       write(b,0,b.length);
+    }
+
+    public synchronized void write(byte b[],
+                                  int off,
+                                  int len) throws IOException
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG writing() len " + len);
+       }
+       if (len+buffersize < MAXBUFFERSIZE) {
+           for (int lup=0;lup<len;lup++) {   
+               buffer[buffersize+lup]=b[lup+off];
+           }
+           buffersize+=len;
+           
+           write_if_size();
+           
+       } else {
+           flush();
+           
+           if (DoEncrypt && conn != null) {
+               // ok, this is a messy way of doing byte[] sub-arraying
+               String str=new String(b,off,len);
+               out.write( conn.encode(str.getBytes()) );
+           } else {
+               out.write(b);
+           }
+           out.flush();
+       }
+
+       if (DoDebug) {
+           System.err.println("DEBUG writing(): done");
+       }
+    }
+
+    public synchronized void flush() throws IOException
+    {
+       if (DoDebug) {
+           System.err.println("DEBUG flushing(): buffersize " + buffersize);
+       }
+       if (buffersize==0) return;
+
+       if (DoEncrypt && conn != null) {
+           // ok, this is a messy way of doing byte[] sub-arraying
+           String str = new String(buffer, 0, buffersize);
+           out.write( conn.encode(str.getBytes()) );
+       } else {
+           out.write(buffer, 0, buffersize);
+       }
+       out.flush();
+       buffersize=0;
+       if (DoDebug) {
+           System.err.println("DEBUG flushing(): done");
+       }
+    }
+
+    public synchronized void close() throws IOException
+    {
+       flush();
+       out.close();
+    }
+
+
+}
diff --git a/java/CyrusSasl/SaslServer.java b/java/CyrusSasl/SaslServer.java
new file mode 100644 (file)
index 0000000..d224028
--- /dev/null
@@ -0,0 +1,20 @@
+package CyrusSasl;
+
+import java.io.*;
+
+public interface SaslServer
+{
+    public byte[]
+       evaluateResponse(byte[] challenge)
+       throws SaslException;
+
+
+    public boolean isComplete();
+
+    public String getMechanismName();
+
+    public InputStream getInputStream(InputStream source) throws IOException;
+
+    public OutputStream getOutputStream(OutputStream dest) throws IOException;
+
+}
diff --git a/java/CyrusSasl/SaslServerFactory.java b/java/CyrusSasl/SaslServerFactory.java
new file mode 100644 (file)
index 0000000..08ae84f
--- /dev/null
@@ -0,0 +1,17 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+
+public interface SaslServerFactory
+{
+
+    public SaslServer createSaslServer(String mechanism,
+                                      String protocol,
+                                      String serverName,
+                                      Hashtable props,
+                                      javax.security.auth.callback.CallbackHandler cbh)
+       throws SaslException;
+
+    public String[] getMechanismNames();
+
+}
diff --git a/java/CyrusSasl/SaslUtils.java b/java/CyrusSasl/SaslUtils.java
new file mode 100644 (file)
index 0000000..b81279c
--- /dev/null
@@ -0,0 +1,202 @@
+package CyrusSasl;
+
+public abstract class SaslUtils
+{
+
+       /**
+        * a static array that maps 6 bit integers to a specific char
+        */
+       private final static char enc_table[] = 
+       { 
+       //   0   1   2   3   4   5   6   7 
+               'A','B','C','D','E','F','G','H', // 0 
+               'I','J','K','L','M','N','O','P', // 1 
+               'Q','R','S','T','U','V','W','X', // 2 
+               'Y','Z','a','b','c','d','e','f', // 3 
+               'g','h','i','j','k','l','m','n', // 4 
+               'o','p','q','r','s','t','u','v', // 5 
+               'w','x','y','z','0','1','2','3', // 6 
+               '4','5','6','7','8','9','+','/'  // 7 
+       }; 
+       private final static byte dec_table[] = 
+       { 
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
+               52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
+               -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+               15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
+               -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+               41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+               -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       }; 
+
+    /**
+     * Base 64 Encodes a String in byte[] form
+     *
+     * @param buf String to be encoded
+     *
+     * @return the encoded value in string form
+     */
+
+       public static String 
+       encode64( byte buf[] ) 
+       {
+               int i = 0; 
+               StringBuffer buffer = new StringBuffer(); 
+               int len = buf.length; 
+               int delta =     len % 3; 
+               byte a, b, c;
+               for (int count = len / 3; count > 0; count--) 
+               {
+                       a = buf[i++];
+                       b = buf[i++];
+                       c = buf[i++];
+                       buffer.append(enc_table[(a >>> 2) & 0x3F]); 
+                       buffer.append(enc_table[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); 
+                       buffer.append(enc_table[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); 
+                       buffer.append(enc_table[c & 0x3F]); 
+
+                       /*                      if (i != 0 && i%57 == 0)
+                                               buffer.append("\r\n");*/
+               }
+
+               if (delta == 1) 
+               {
+                       a = buf[i++];
+                       buffer.append(enc_table[(a >>> 2) & 0x3F]); 
+                       buffer.append(enc_table[((a << 4) & 0x30)]); 
+                       buffer.append('='); 
+                       buffer.append('='); 
+               }
+               if (delta == 2) 
+               {
+                       a = buf[i++];
+                       b = buf[i++];
+                       buffer.append(enc_table[(a >>> 2) & 0x3F]); 
+                       buffer.append(enc_table[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); 
+                       buffer.append(enc_table[((b << 2) & 0x3c)]); 
+                       buffer.append('='); 
+               }
+
+               /*buffer.append("\r\n");*/
+               return buffer.toString(); 
+       }
+
+    /**
+     * Base 64 Encodes a String in String form
+     *
+     * @param s String to be encoded
+     *
+     * @return the encoded value in string form
+     */
+
+    public static String encode64( String s ) 
+    {
+      return encode64( s.getBytes() ); 
+    }
+
+
+    /**
+     * Base 64 Decodes a byte[] string
+     * Ignores trailing whitespace and newlines
+     *
+     * @param buf buffer to be decoded
+     *
+     * @return the decoded value in byte[] form
+     */
+
+
+       public static byte[]
+       decode64( byte buf[] ) 
+       {
+                int padCount = 0;
+                int i, len = buf.length;
+               int real_len = 0;
+
+               for (i=len-1; i >= 0; --i)
+                {
+                       if (buf[i] > ' ')
+                               real_len++;
+
+                        if (buf[i] == 0x3D)
+                                padCount++;
+                }
+
+               // Hmm - should this be a "bad format MIME" exception instead?
+               if (real_len%4 != 0)
+                       throw new IllegalArgumentException("Length not a multiple of 4");
+
+                int ret_len = (real_len/4)*3 - padCount;
+               byte ret[] = new byte[ret_len];
+
+               i = 0;
+               byte[] t = new byte[4];
+               int output_index = 0;
+               int j = 0;
+               t[0] = t[1] = t[2] = t[3] = 61; // Ascii =
+               while (i < len)
+               {
+                       byte c =  buf[i++];
+                       if (c > ' ')
+                               t[j++] = c;
+
+                       if (j == 4)
+                       {
+                               output_index += decode64(ret, output_index, t[0], t[1], t[2], t[3]);
+                               j = 0;
+                               t[0] = t[1] = t[2] = t[3] = 61; // Ascii =
+                       }
+               }
+               if (j > 0)
+                       decode64(ret, output_index, t[0], t[1], t[2], t[3]);
+
+               return ret;
+       }
+
+    /**
+     * Base 64 Decodes a String
+     * Ignores trailing whitespace and newlines
+     *
+     * @param msg String to be decoded
+     *
+     * @return the decoded value in byte[] form
+     */
+
+    public static byte[] decode64( String msg ) 
+    {
+      return decode64( msg.getBytes());
+    }
+
+       // Returns the number of bytes converted
+        private static int
+       decode64( byte ret[], int ret_off, byte a, byte b, byte c, byte d )
+       {
+               byte da = dec_table[a];
+               byte db = dec_table[b];
+               byte dc = dec_table[c];
+               byte dd = dec_table[d];
+
+               if (da == -1 || db == -1 || (dc == -1 && c != 0x3d) || (dd == -1 && d != 0x3d))
+                       throw new IllegalArgumentException("Invalid character ["+a+", "+b+", "+c+", "+d+"]");
+
+               ret[ret_off++] = (byte)(da << 2 | db >>> 4);
+               if (c == 0x3d)  // Ascii =
+                       return 1;
+               ret[ret_off++] = (byte)(db << 4 | dc >>> 2);
+               if (d == 0x3d)  // Ascii =
+                       return 2;
+               ret[ret_off++] = (byte)(dc << 6 | dd);
+                        return 3;
+       }
+
+
+}
diff --git a/java/CyrusSasl/ServerFactory.java b/java/CyrusSasl/ServerFactory.java
new file mode 100644 (file)
index 0000000..1ce7236
--- /dev/null
@@ -0,0 +1,105 @@
+package CyrusSasl;
+
+import java.util.Hashtable;
+import javax.security.auth.callback.*;
+
+class ServerFactory implements SaslServerFactory
+{
+    private int localptr = 0;
+
+    /* JNI functions  */
+    private native int jni_sasl_server_init(String appname);
+    private native int jni_sasl_server_new(String service,
+                                          String local_domain,
+                                          int secflags);
+
+
+    public ServerFactory()
+    {
+       /* these parameters aren't needed for getting mech list */
+       localptr = jni_sasl_server_new("foo", "bar", 0);
+    }
+
+    private boolean init(String appname)
+    {
+       /* load library */
+       try {
+           System.loadLibrary("javasasl");
+       } catch (UnsatisfiedLinkError e) {
+           /* xxx */
+           System.out.println("Unable to load javasasl library");
+       }
+
+       jni_sasl_server_init(appname);
+
+       return true;
+    }
+
+    {
+       init("javasasl application");
+    }
+
+    public SaslServer createSaslServer(String mechanism,
+                                      String protocol,
+                                      String serverName,
+                                      Hashtable props,
+                                      javax.security.auth.callback.CallbackHandler cbh)
+       throws SaslException
+    {
+       int cptr;
+
+       cptr = jni_sasl_server_new(protocol,
+                                  serverName,
+                                  0);
+
+       if (cptr == 0) {
+           throw new SaslException("Unable to create new Client connection object", 
+                                   new Throwable());
+       }
+
+       return new GenericServer(cptr,mechanism,props,cbh);
+    }
+
+    private native String jni_sasl_server_getlist(int ptr, String prefix,
+                                                 String sep, String suffix);
+
+    public String[] getMechanismNames()
+    {
+       if (localptr == 0)
+           localptr = jni_sasl_server_new("foo", 
+                                          "bar",
+                                          0);
+
+       String list = jni_sasl_server_getlist(localptr, "",
+                                             "\n","\n");
+
+       /* count newlines */
+       int newlines = 0;
+       int pos =0;
+
+       while (pos < list.length()) {
+           if (list.charAt(pos)=='\n') 
+               newlines++;
+           pos++;
+       }
+
+       String[]ret = new String[newlines];
+
+       int num =0;
+       pos =0;
+       String temp="";
+
+       while (pos < list.length()) {       
+           if (list.charAt(pos)=='\n') {
+               ret[num++]=temp;
+               temp=new String("");
+           } else {
+               temp+=list.charAt(pos);
+           }
+           pos++;
+       }
+       
+       return ret;
+    }
+
+}
diff --git a/java/CyrusSasl/javasasl.c b/java/CyrusSasl/javasasl.c
new file mode 100644 (file)
index 0000000..fcdac2d
--- /dev/null
@@ -0,0 +1,930 @@
+/* javasasl.c--Java SASL JNI implementation
+ * Tim Martin
+ */
+/***********************************************************
+        Copyright 1998 by Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon
+University not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+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.
+******************************************************************/
+
+#include <config.h>
+#include <stdio.h>
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <assert.h>
+
+#include "javasasl.h"
+
+#define VL(x) /* printf x */
+
+static JNIEnv *globalenv;
+static jobject globalobj;
+
+static int setcomplete(JNIEnv *env, jobject obj);
+
+static void throwexception(JNIEnv *env, int error)
+{
+  jclass newExcCls;
+
+  VL (("Throwing exception!\n"));
+
+  newExcCls = (*env)->FindClass(env, "CyrusSasl/SaslException");
+
+  if (newExcCls == 0) { 
+    return;
+  }
+
+  (*env)->ThrowNew(env, newExcCls, sasl_errstring(error,NULL,NULL));
+}
+
+/* server init */
+
+JNIEXPORT jint JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1init
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jstring jstr)
+{
+  /* Obtain a C-copy of the Java string */
+  const char *str = (*env)->GetStringUTFChars(env, jstr, 0);
+  int result;
+
+  result=sasl_server_init(NULL,str);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+  /* Now we are done with str */
+  (*env)->ReleaseStringUTFChars(env, jstr, str);
+
+  return result;
+}
+
+static int
+log(void *context __attribute__((unused)),
+    int priority,
+    const char *message) 
+{
+  const char *label;
+  jstring jlabel, jmessage;
+  jclass cls;
+  jmethodID mid;
+
+  if (! message)
+    return SASL_BADPARAM;
+
+  switch (priority) {
+  case SASL_LOG_ERR:
+    label = "Error";
+    break;
+  case SASL_LOG_WARN:
+    label = "Warning";
+    break;
+  case SASL_LOG_NOTE:
+    label = "Note";
+    break;
+  case SASL_LOG_FAIL:
+    label = "Fail";
+    break;
+  case SASL_LOG_PASS:
+    label = "Pass";
+    break;
+  case SASL_LOG_TRACE:
+    label = "Trace";
+    break;
+  case SASL_LOG_DEBUG:
+    label = "Debug";
+    break;
+  default:
+    return SASL_BADPARAM;
+  }
+
+  VL(("I have message %s\n",message));
+  VL(("Trying to call log callback\n"));
+  cls = (*globalenv)->GetObjectClass(globalenv, globalobj);
+  mid = (*globalenv)->GetMethodID(globalenv, cls, "callback_log",
+                                 "(Ljava/lang/String;Ljava/lang/String;)V");
+  if (mid == 0) {
+    return SASL_FAIL;
+  }
+
+  /* make label into a java string */
+  jlabel= (*globalenv)->NewStringUTF(globalenv,label);
+
+  /* make message into a java string */
+  jmessage= (*globalenv)->NewStringUTF(globalenv,message);
+
+  /* call java */
+  (*globalenv)->CallVoidMethod(globalenv, globalobj, mid, 
+                              jlabel, jmessage);
+
+  /* Now we are done with jlabel */
+  (*globalenv)->ReleaseStringUTFChars(globalenv, jlabel, label);
+
+  /* Now we are done with jmessage */
+  (*globalenv)->ReleaseStringUTFChars(globalenv, jmessage, message);
+
+  VL(("done with log callback"));
+
+  return SASL_OK;
+}
+
+static sasl_callback_t callbacks[] = {
+  {
+    SASL_CB_LOG,      &log, NULL
+  }, {
+    SASL_CB_PASS,     NULL, NULL
+  }, {
+    SASL_CB_USER,     NULL, NULL /* we'll handle these ourselves */
+  }, {
+    SASL_CB_AUTHNAME, NULL, NULL /* we'll handle these ourselves */
+  }, {
+      /* TODO
+        SASL_CB_ECHOPROMPT, &prompt, NULL
+  }, {
+    SASL_CB_NOECHOPROMPT, &prompt, NULL
+    }, { */
+    SASL_CB_LIST_END, NULL, NULL
+  }
+};
+
+/* client init */
+JNIEXPORT jint JNICALL Java_CyrusSasl_ClientFactory_jni_1sasl_1client_1init
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jstring jstr)
+{
+  /* Obtain a C-copy of the Java string */
+  const char *str = (*env)->GetStringUTFChars(env, jstr, 0);
+  int result;
+
+  VL(("client initing\n"));
+
+  result=sasl_client_init(callbacks);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+  /* Now we are done with str */
+  (*env)->ReleaseStringUTFChars(env, jstr, str);
+
+  return result;
+}
+
+/* server new */
+
+JNIEXPORT jint JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1new
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jstring jservice, 
+   jstring jlocal, 
+   jint jsecflags)
+{
+  sasl_conn_t *conn;
+
+  const char *service = (*env)->GetStringUTFChars(env, jservice, 0);
+  const char *local_domain = (*env)->GetStringUTFChars(env, jlocal, 0);
+  const char *user_domain = NULL;  
+  int result;
+
+  if (local_domain) {
+      VL(("local domain = %s\n",local_domain));
+  }
+  if (user_domain) {
+      VL(("user domain = %s\n",user_domain));
+  }
+
+  result=sasl_server_new(service, local_domain, user_domain, 
+                        NULL, NULL, NULL, jsecflags, &conn);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+  /* Now we are done with str */
+  (*env)->ReleaseStringUTFChars(env, jservice, service);  
+  (*env)->ReleaseStringUTFChars(env, jlocal, local_domain);  
+
+  return (jint) conn;
+}
+
+
+JNIEXPORT jint JNICALL JNICALL Java_CyrusSasl_ClientFactory_jni_1sasl_1client_1new
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jstring jservice, jstring jserver, jint jsecflags, jboolean successdata)
+{
+  sasl_conn_t *conn;
+
+  const char *service = (*env)->GetStringUTFChars(env, jservice, 0);
+  const char *serverFQDN = (*env)->GetStringUTFChars(env, jserver, 0);
+  int result;
+
+  result=sasl_client_new(service, serverFQDN, NULL, NULL, NULL,
+                        jsecflags | (successdata ? SASL_SUCCESS_DATA : 0), 
+                         &conn);
+
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+  /* Now we are done with str */
+  (*env)->ReleaseStringUTFChars(env, jservice, service);  
+  (*env)->ReleaseStringUTFChars(env, jserver, serverFQDN);  
+
+  return (jint) conn;
+}
+
+/* server start */
+
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericServer_jni_1sasl_1server_1start
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jstring jstr, jbyteArray jarr, jint jlen)
+{
+  sasl_conn_t *conn;
+  const char *mech = (*env)->GetStringUTFChars(env, jstr, 0);
+  const char *out;
+  unsigned int outlen;
+   int result;
+  jbyteArray arr;
+  char *tmp;
+  char *in=NULL;
+
+  VL(("in server start\n"));
+
+  if (jarr!=NULL)
+    in = (*env)->GetByteArrayElements(env, jarr, 0);
+
+  conn=(sasl_conn_t *) ptr;
+
+  result=sasl_server_start(conn, mech,
+                          (const char *) in, jlen,
+                          &out, &outlen);
+
+  if ((result!=SASL_OK) && (result!=SASL_CONTINUE))
+  {
+
+    throwexception(env,result);
+    return NULL;
+  }
+
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  return arr;
+}
+
+
+static int getvalue(JNIEnv *env, jobject obj, char *funcname, char **result, int *len)
+{
+    jclass cls;
+    jmethodID mid;
+    const char *str;
+    jstring jstr;
+    
+    /* set up for java callback */
+    cls = (*env)->GetObjectClass(env, obj);
+    mid = (*env)->GetMethodID(env, cls, funcname,
+                                 "(I)Ljava/lang/String;");
+    if (mid == 0) {
+       VL(("Can't find %s callback!!!\n",funcname));
+       return SASL_FAIL;
+    }
+
+    VL(("do the callback\n"));
+    jstr = (jstring) (*env)->CallObjectMethod(env, obj, mid);
+
+    if (jstr) {
+        VL(("convert the result string into a char *\n"));
+        str = (*env)->GetStringUTFChars(env, jstr, 0);
+
+        /* copy password into the result */    
+        *result=(char *) malloc( strlen(str));
+        strcpy(*result, str);
+        *len=strlen(str);
+
+        /* Now we are done with str */
+        (*env)->ReleaseStringUTFChars(env, jstr, str);
+    } else {
+        *result = NULL;
+        *len = 0;
+    }
+
+    return SASL_OK;
+}
+
+static int callall_callbacks(JNIEnv *env, jobject obj, 
+                            int calluid,int callaid,
+                            int callpass,int callrealm)
+{
+    jclass cls;
+    jmethodID mid;
+    
+    /* set up for java callback */
+    cls = (*env)->GetObjectClass(env, obj);
+    mid = (*env)->GetMethodID(env, cls, "do_callbacks", "(IIII)V");
+    if (mid == 0) {
+       VL(("Can't find do_callbacks callback!!!\n"));
+       return SASL_FAIL;
+    }
+
+    /* do the callback */
+    (*env)->CallVoidMethod(env, obj, mid,calluid,callaid,callpass,callrealm);
+
+    VL(("callall_callbacks worked\n"));
+    return SASL_OK;
+}
+
+/*
+ * Fills in all the prompts by doing callbacks to java
+ * returns SASL_INTERACT on sucess
+ */
+
+static int fillin_interactions(JNIEnv *env, jobject obj, 
+                               sasl_interact_t *tlist)
+{
+  sasl_interact_t *ptr=tlist;
+  sasl_interact_t *uid=NULL; int is_uid = 0;
+  sasl_interact_t *aid=NULL; int is_aid = 0;
+  sasl_interact_t *pass=NULL;int is_pass = 0;
+  sasl_interact_t *realm=NULL; int is_realm = 0;
+
+  /* First go through the prompt list to see what we have */
+  while (ptr->id!=SASL_CB_LIST_END)
+  {
+    if (ptr->id==SASL_CB_PASS)
+       {  pass=ptr; is_pass = 1; }
+    if (ptr->id==SASL_CB_AUTHNAME)
+       { aid=ptr; is_aid = 1; }
+    if (ptr->id==SASL_CB_USER)
+       { uid=ptr; is_uid = 1; }
+    if (ptr->id==SASL_CB_GETREALM)
+       { realm = ptr; is_realm = 1; }
+    ptr->result=NULL;
+    
+    /* increment to next sasl_interact_t */
+    ptr++;
+  }
+
+  callall_callbacks(env,obj,is_uid,is_aid,is_pass,is_realm);
+
+  if (is_pass) {
+      VL(("in is_pass\n"));
+
+      getvalue(env,obj,"get_password",(char **) &(pass->result),(int *) &(pass->len));
+  }
+  if (is_aid) {
+      VL(("in is_aid\n"));
+
+      getvalue(env,obj,"get_authid",(char **) &(aid->result),(int *) &(aid->len));
+  }
+  if (is_uid) {
+      VL(("in is_uid\n"));
+
+      getvalue(env,obj,"get_userid",(char **) &(uid->result),(int *) &(uid->len)); 
+  }
+  if (is_realm) {
+      VL(("in is_realm\n"));
+
+      getvalue(env,obj,"get_realm",(char **) &(realm->result),(int *) &(realm->len));
+  }
+
+  /* everything should now be filled in (i think) */
+  VL(("everything should now be filled in (i think)\n"));
+
+  return SASL_INTERACT;
+}
+
+/* client start */
+
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericClient_jni_1sasl_1client_1start(JNIEnv *env, jobject obj, jint ptr, jstring jstr)
+{    
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  const char *mechlist = (*env)->GetStringUTFChars(env, jstr, 0);
+  const char *out;
+  unsigned int outlen=0;
+  const char *mechusing;
+  int result;
+  sasl_interact_t *client_interact=NULL;
+  char *tmp;
+  jbyteArray arr;
+  jstring jmechusing;
+  jclass cls;
+  jmethodID mid;
+
+  VL(("sasl_start"));
+  do {
+
+      result=sasl_client_start(conn, mechlist,
+                              &client_interact,
+                              &out, 
+                               &outlen,
+                              &mechusing);
+
+      if (result==SASL_INTERACT) {
+         int res2 = fillin_interactions(env,obj,client_interact);
+      }
+
+  } while (result==SASL_INTERACT);
+
+  /* ok release mechlist */
+  (*env)->ReleaseStringUTFChars(env, jstr, mechlist);  
+
+  if ((result!=SASL_OK) && (result!=SASL_CONTINUE))
+  {
+    throwexception(env,result);
+    return NULL;
+  }
+
+  /* tell the java layer what mechanism we're using */
+
+  /* set up for java callback */
+  cls = (*env)->GetObjectClass(env, obj);
+  mid = (*env)->GetMethodID(env, cls, "callback_setmechanism",
+                           "(Ljava/lang/String;I)V");
+  if (mid == 0) {
+      throwexception(env,SASL_FAIL);
+    return NULL;
+  }
+
+  VL(("mechusing=%s\n",mechusing));
+
+  /* make into mech */
+  jmechusing= (*env)->NewStringUTF(env,mechusing);
+
+  /* do the callback */
+  (*env)->CallVoidMethod(env, obj, mid,jmechusing);
+
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+  
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  return arr;
+}
+
+/* server step */
+
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericServer_jni_1sasl_1server_1step
+
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jbyteArray jarr, jint jlen)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  int result;
+  const char *out;
+  unsigned int outlen;
+  jbyteArray arr;
+  char *in = NULL;
+  char *tmp;
+  
+  if (jlen > 0)
+      in = (*env)->GetByteArrayElements(env, jarr, 0);
+
+  result=sasl_server_step(conn, (const char *) in, jlen,
+                         &out, &outlen);
+
+  if ((result!=SASL_OK) && (result!=SASL_CONTINUE))
+  {
+      VL (("Throwing exception! %d\n",result));
+      /* throw exception */
+      throwexception(env,result);
+      return NULL;
+  }
+
+  if (result == SASL_OK) {
+      setcomplete(env,obj);
+  }
+
+  if (jlen > 0)
+      (*env)->ReleaseByteArrayElements(env, jarr,in ,0);
+
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  return arr;
+}
+
+
+/* 
+ * Tell client we're done
+ */
+static int setcomplete(JNIEnv *env, jobject obj)
+{
+    jclass cls;
+    jmethodID mid;
+
+    VL (("Complete!\n"));
+    
+    /* set up for java callback */
+    cls = (*env)->GetObjectClass(env, obj);
+    mid = (*env)->GetMethodID(env, cls, "setcomplete",
+                                 "(I)V");
+    if (mid == 0) {
+       VL(("Can't find do_callbacks callback!!!\n"));
+       return SASL_FAIL;
+    }
+
+    /* do the callback */
+    (*env)->CallVoidMethod(env, obj, mid, 5);
+
+    return SASL_OK;
+}
+
+/* client step */
+
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericClient_jni_1sasl_1client_1step
+    (JNIEnv *env, jobject obj, jint ptr, jbyteArray jarr, jint jlen)
+{    
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  /*  const char *in = (*env)->GetStringUTFChars(env, jstr, 0);*/
+  int result;
+  sasl_interact_t *client_interact=NULL;
+  const char *out;
+  unsigned int outlen;
+  jbyteArray arr;
+  char *in;
+  char *tmp;
+  
+  VL(("in client step\n"));
+
+  if (jarr) {
+      in = (*env)->GetByteArrayElements(env, jarr, 0);
+      in[jlen]=0;
+  } else {
+      assert(jlen == 0);
+       in = NULL;
+  }
+
+  VL(("in client step 2\n"));
+
+  globalenv=env;
+  globalobj=obj;
+
+  do {
+      result=sasl_client_step(conn, (const char *) in, jlen,
+                             &client_interact,
+                             &out, &outlen);
+
+      VL(("in client step 3\n"));
+
+      if (result==SASL_INTERACT) {
+         result = fillin_interactions(env,obj,client_interact);
+      }
+  } while (result==SASL_INTERACT);
+
+  if ((result!=SASL_OK) && (result!=SASL_CONTINUE)) {
+      /* throw exception */
+      VL (("Throwing exception %d\n",result));
+      throwexception(env,result);
+      return NULL;
+  }
+
+  if (result == SASL_OK) {
+      VL (("Setting complete\n"));
+      setcomplete(env,obj);
+  }
+
+  if (jarr) {
+      VL(("about to releasebytearrayelements\n"));
+      (*env)->ReleaseByteArrayElements(env, jarr,in ,0);
+  }
+      
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+
+  VL(("in client step 4\n"));
+
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  VL(("returning arr\n"));
+  return arr;
+}
+
+
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1string
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jint propnum, jstring val)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  const char *value = (*env)->GetStringUTFChars(env, val, 0);
+
+  int result=sasl_setprop(conn, propnum, value);
+
+  if (result!=SASL_OK)
+    throwexception(env,result);
+}
+
+
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1int
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jint propnum, jint jval)
+{
+
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  int value=jval;
+  int result;
+
+  VL(("sasl conn = %d\n",conn));
+  VL (("propnum = %d\n",propnum));
+
+  result=sasl_setprop(conn, propnum, &value);  
+
+  VL (("setprop returned %d\n",result));
+
+  if (result!=SASL_OK)
+    throwexception(env,result);
+}
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1bytes
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jint propnum, jbyteArray jarr)
+{
+  char *value = (*env)->GetByteArrayElements(env, jarr, 0);
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  int result;
+
+  result=sasl_setprop(conn, propnum, value);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+}
+
+/* encode */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1encode
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, 
+   jbyteArray jarr, jint jlen)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  char *in = (*env)->GetByteArrayElements(env, jarr, 0);
+  const char *out;
+  unsigned int outlen;
+  char *tmp;
+  int result;
+  jbyteArray arr;
+
+  result=sasl_encode(conn,(const char *) in, jlen, &out, &outlen);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  return arr;
+}
+
+/* decode */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1decode
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)), 
+   jint ptr, jbyteArray jarr, jint jlen)
+{
+
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  char *in = (*env)->GetByteArrayElements(env, jarr, 0);
+  const char *out;
+  unsigned int outlen=9;
+  char *tmp;
+  int inlen=jlen;
+  int result;
+  jbyteArray arr;
+
+  result=sasl_decode(conn, (const char *) in, inlen, &out, &outlen);
+  if (result!=SASL_OK)
+    throwexception(env,result);
+
+
+  /* Because SASLv2 does not allow for persistance, we'll copy
+   * it here */
+  tmp = malloc(outlen);
+  if(!tmp) {
+      throwexception(env, SASL_NOMEM);
+      return NULL;
+  }
+
+  memcpy(tmp, out, outlen);
+  
+  arr=(*env)->NewByteArray(env,outlen);
+  (*env)->SetByteArrayRegion(env,arr, 0, outlen, (char *)tmp);
+
+  (*env)->ReleaseByteArrayElements(env, jarr, in,0);
+
+  return arr;
+
+}
+
+/*JNIEXPORT jbyteArray JNICALL Java_sasl_saslServerConn_jni_1sasl_1server_1decode
+  (JNIEnv *env, jobject obj, jint ptr, jbyteArray in, jint inlen)
+{
+  return Java_sasl_saslClientConn_jni_1sasl_1client_1decode(env,obj,ptr,in,inlen);
+  }*/
+
+JNIEXPORT void JNICALL Java_CyrusSasl_CommonConn_jni_1sasl_1dispose
+  (JNIEnv *env __attribute__((unused)),
+   jobject obj __attribute__((unused)),
+   jint ptr)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+
+  sasl_dispose(&conn);
+
+}
+
+JNIEXPORT jstring JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1getlist
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jstring jpre, jstring jsep, jstring jsuf)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  const char *pre = (*env)->GetStringUTFChars(env, jpre, 0);
+  const char *sep = (*env)->GetStringUTFChars(env, jsep, 0);
+  const char *suf = (*env)->GetStringUTFChars(env, jsuf, 0);
+  const char *list;
+  unsigned int plen;
+  jstring ret;
+
+  int result=sasl_listmech(conn, NULL, pre, sep, suf, &list, &plen, NULL);
+
+  if (result!=SASL_OK)
+  {
+    throwexception(env,result);  
+    return NULL;
+  }
+
+  ret= (*env)->NewStringUTF(env,list);
+  if (ret==NULL)
+    throwexception(env, -1);
+
+  return ret;
+}
+
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1server
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jbyteArray jarr, jint jport)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  unsigned char *ip = (*env)->GetByteArrayElements(env, jarr, 0);
+  char out[52];
+  int result;
+
+  sprintf(out, "%d.%d.%d.%d;%d", ip[0], ip[1], ip[2], ip[3], (int)jport);
+
+  result=sasl_setprop(conn, SASL_IPREMOTEPORT, out);  
+
+  VL(("Set IP_REMOTE: %s: %d\n",out, result));
+
+  /* if not set throw an exception */
+  if (result!=SASL_OK)
+    throwexception(env,result); 
+}
+
+
+
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1client
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jbyteArray jarr, jint jport)
+{
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  unsigned char *ip = (*env)->GetByteArrayElements(env, jarr, 0);
+  char out[52];
+  int result;
+
+  sprintf(out, "%d.%d.%d.%d;%d", ip[0], ip[1], ip[2], ip[3], (int)jport);
+
+  result=sasl_setprop(conn, SASL_IPLOCALPORT, out);
+
+  VL(("Set IP_LOCAL: %s: %d\n",out, result));
+
+  /* if not set throw and exception */
+  if (result!=SASL_OK)
+    throwexception(env,result);  
+}
+
+/* allocate a secprops structure */
+
+static sasl_security_properties_t *make_secprops(int min,int max)
+{
+  sasl_security_properties_t *ret=(sasl_security_properties_t *)
+    malloc(sizeof(sasl_security_properties_t));
+
+  ret->maxbufsize=1024;
+  ret->min_ssf=min;
+  ret->max_ssf=max;
+
+  ret->security_flags=0;
+  ret->property_names=NULL;
+  ret->property_values=NULL;
+
+  return ret;
+}
+
+
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1setSecurity
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr, jint minssf, jint maxssf)
+{
+  int result=SASL_FAIL;
+  sasl_conn_t *conn=(sasl_conn_t *) ptr;
+  sasl_security_properties_t *secprops=NULL;
+  
+  /* set sec props */
+  secprops=make_secprops(minssf,maxssf);
+
+  if (secprops!=NULL)
+    result=sasl_setprop(conn, SASL_SEC_PROPS, secprops);  
+
+  /* if not set throw and exception */
+  if (result!=SASL_OK)
+    throwexception(env,result);
+}
+
+JNIEXPORT jint JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1getSecurity
+  (JNIEnv *env,
+   jobject obj __attribute__((unused)),
+   jint ptr)
+{
+    int r = SASL_FAIL;
+    sasl_conn_t *conn = (sasl_conn_t *) ptr;
+    int *ssfp;
+
+    r = sasl_getprop(conn, SASL_SSF, (const void **) &ssfp);
+    if (r != SASL_OK) {
+       throwexception(env, r);
+    }
+
+    return *ssfp;
+}
+
+
diff --git a/java/CyrusSasl/javasasl.h b/java/CyrusSasl/javasasl.h
new file mode 100644 (file)
index 0000000..2ea751d
--- /dev/null
@@ -0,0 +1,322 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class CyrusSasl_Sasl */
+
+#ifndef _Included_CyrusSasl_Sasl
+#define _Included_CyrusSasl_Sasl
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_GenericClient */
+
+#ifndef _Included_CyrusSasl_GenericClient
+#define _Included_CyrusSasl_GenericClient
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     CyrusSasl_GenericClient
+ * Method:    jni_sasl_client_start
+ * Signature: (ILjava/lang/String;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericClient_jni_1sasl_1client_1start
+  (JNIEnv *, jobject, jint, jstring);
+
+/*
+ * Class:     CyrusSasl_GenericClient
+ * Method:    jni_sasl_client_step
+ * Signature: (I[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericClient_jni_1sasl_1client_1step
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_ClientFactory */
+
+#ifndef _Included_CyrusSasl_ClientFactory
+#define _Included_CyrusSasl_ClientFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     CyrusSasl_ClientFactory
+ * Method:    jni_sasl_client_init
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_CyrusSasl_ClientFactory_jni_1sasl_1client_1init
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     CyrusSasl_ClientFactory
+ * Method:    jni_sasl_client_new
+ * Signature: (Ljava/lang/String;Ljava/lang/String;IZ)I
+ */
+JNIEXPORT jint JNICALL Java_CyrusSasl_ClientFactory_jni_1sasl_1client_1new
+  (JNIEnv *, jobject, jstring, jstring, jint, jboolean);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_GenericCommon */
+
+#ifndef _Included_CyrusSasl_GenericCommon
+#define _Included_CyrusSasl_GenericCommon
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_set_prop_string
+ * Signature: (IILjava/lang/String;)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1string
+  (JNIEnv *, jobject, jint, jint, jstring);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_set_prop_int
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1int
+  (JNIEnv *, jobject, jint, jint, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_set_prop_bytes
+ * Signature: (II[B)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1prop_1bytes
+  (JNIEnv *, jobject, jint, jint, jbyteArray);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_set_server
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1server
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_set_client
+ * Signature: (I[BI)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1set_1client
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_setSecurity
+ * Signature: (III)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1setSecurity
+  (JNIEnv *, jobject, jint, jint, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_getSecurity
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1getSecurity
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_encode
+ * Signature: (I[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1encode
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_decode
+ * Signature: (I[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1decode
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+/*
+ * Class:     CyrusSasl_GenericCommon
+ * Method:    jni_sasl_dispose
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_CyrusSasl_GenericCommon_jni_1sasl_1dispose
+  (JNIEnv *, jobject, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslClient */
+
+#ifndef _Included_CyrusSasl_SaslClient
+#define _Included_CyrusSasl_SaslClient
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslClientFactory */
+
+#ifndef _Included_CyrusSasl_SaslClientFactory
+#define _Included_CyrusSasl_SaslClientFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslException */
+
+#ifndef _Included_CyrusSasl_SaslException
+#define _Included_CyrusSasl_SaslException
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef CyrusSasl_SaslException_serialVersionUID
+#define CyrusSasl_SaslException_serialVersionUID -3042686055658047285LL
+#undef CyrusSasl_SaslException_serialVersionUID
+#define CyrusSasl_SaslException_serialVersionUID -3387516993124229948LL
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslInputStream */
+
+#ifndef _Included_CyrusSasl_SaslInputStream
+#define _Included_CyrusSasl_SaslInputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef CyrusSasl_SaslInputStream_SKIP_BUFFER_SIZE
+#define CyrusSasl_SaslInputStream_SKIP_BUFFER_SIZE 2048L
+#undef CyrusSasl_SaslInputStream_DoEncrypt
+#define CyrusSasl_SaslInputStream_DoEncrypt 1L
+#undef CyrusSasl_SaslInputStream_DoDebug
+#define CyrusSasl_SaslInputStream_DoDebug 0L
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslOutputStream */
+
+#ifndef _Included_CyrusSasl_SaslOutputStream
+#define _Included_CyrusSasl_SaslOutputStream
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef CyrusSasl_SaslOutputStream_DoEncrypt
+#define CyrusSasl_SaslOutputStream_DoEncrypt 1L
+#undef CyrusSasl_SaslOutputStream_DoDebug
+#define CyrusSasl_SaslOutputStream_DoDebug 0L
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslUtils */
+
+#ifndef _Included_CyrusSasl_SaslUtils
+#define _Included_CyrusSasl_SaslUtils
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_ServerFactory */
+
+#ifndef _Included_CyrusSasl_ServerFactory
+#define _Included_CyrusSasl_ServerFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     CyrusSasl_ServerFactory
+ * Method:    jni_sasl_server_init
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1init
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     CyrusSasl_ServerFactory
+ * Method:    jni_sasl_server_new
+ * Signature: (Ljava/lang/String;Ljava/lang/String;I)I
+ */
+JNIEXPORT jint JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1new
+  (JNIEnv *, jobject, jstring, jstring, jint);
+
+/*
+ * Class:     CyrusSasl_ServerFactory
+ * Method:    jni_sasl_server_getlist
+ * Signature: (ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_CyrusSasl_ServerFactory_jni_1sasl_1server_1getlist
+  (JNIEnv *, jobject, jint, jstring, jstring, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslServerFactory */
+
+#ifndef _Included_CyrusSasl_SaslServerFactory
+#define _Included_CyrusSasl_SaslServerFactory
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_SaslServer */
+
+#ifndef _Included_CyrusSasl_SaslServer
+#define _Included_CyrusSasl_SaslServer
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class CyrusSasl_GenericServer */
+
+#ifndef _Included_CyrusSasl_GenericServer
+#define _Included_CyrusSasl_GenericServer
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     CyrusSasl_GenericServer
+ * Method:    jni_sasl_server_start
+ * Signature: (ILjava/lang/String;[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericServer_jni_1sasl_1server_1start
+  (JNIEnv *, jobject, jint, jstring, jbyteArray, jint);
+
+/*
+ * Class:     CyrusSasl_GenericServer
+ * Method:    jni_sasl_server_step
+ * Signature: (I[BI)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_CyrusSasl_GenericServer_jni_1sasl_1server_1step
+  (JNIEnv *, jobject, jint, jbyteArray, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/java/Makefile.am b/java/Makefile.am
new file mode 100644 (file)
index 0000000..849f942
--- /dev/null
@@ -0,0 +1,27 @@
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+SUBDIRS = CyrusSasl javax Test
+EXTRA_DIST = doc
diff --git a/java/Makefile.in b/java/Makefile.in
new file mode 100644 (file)
index 0000000..f9e3e27
--- /dev/null
@@ -0,0 +1,515 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+SUBDIRS = CyrusSasl javax Test
+EXTRA_DIST = doc
+subdir = java
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+       ps-recursive install-info-recursive uninstall-info-recursive \
+       all-recursive install-data-recursive install-exec-recursive \
+       installdirs-recursive install-recursive uninstall-recursive \
+       check-recursive installcheck-recursive
+DIST_COMMON = README $(srcdir)/Makefile.in Makefile.am
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if (etags --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+       else \
+         include_option=--include; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+       clean-generic clean-libtool clean-recursive ctags \
+       ctags-recursive distclean distclean-generic distclean-libtool \
+       distclean-recursive distclean-tags distdir dvi dvi-am \
+       dvi-recursive info info-am info-recursive install install-am \
+       install-data install-data-am install-data-recursive \
+       install-exec install-exec-am install-exec-recursive \
+       install-info install-info-am install-info-recursive install-man \
+       install-recursive install-strip installcheck installcheck-am \
+       installdirs installdirs-am installdirs-recursive \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
+       pdf-recursive ps ps-am ps-recursive tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am \
+       uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/README b/java/README
new file mode 100644 (file)
index 0000000..123db7d
--- /dev/null
@@ -0,0 +1,37 @@
+4-Nov-2000
+
+after a "make install"
+class files are installed in
+
+$(prefix)/lib/java/classes/sasl
+
+to compile programs using it, do:
+
+javac -classpath /usr/java/lib/classes.zip:/usr/local/lib/java/classes/sasl <file>.java
+
+(make sure to substitute your JDK for /usr/java/lib/classes.zip)
+
+to run, do
+
+java -classpath <same path as above> <YourProgram>
+
+----------------------------
+This is a java version of the SASL libraries. It supports all the
+mechanisms in the C version and conforms to the internet draft in the
+doc/ directory. JNI is used.
+
+Sample applications exist in the Test/ directory.
+
+They generally can be run with something like:
+
+java -debug -classpath
+../:/usr/java/lib/classes.zip:/usr/obj/sasl/java/:. jimtest -p 2143 -m
+KERBEROS_V4 cyrus-dev
+
+and
+
+java -debug -classpath
+../:/usr/java/lib/classes.zip:/usr/obj/sasl/java/:. testserver
+
+
+Any feedback is welcome.
\ No newline at end of file
diff --git a/java/Test/Handler.java b/java/Test/Handler.java
new file mode 100644 (file)
index 0000000..de222ef
--- /dev/null
@@ -0,0 +1,111 @@
+
+import java.io.*;
+import javax.security.auth.callback.*;
+
+class Handler implements javax.security.auth.callback.CallbackHandler{
+
+    String authid;
+    String userid;
+    String password;
+    String realm;
+    
+    public Handler()
+    {
+
+    }
+
+    public Handler(String authid, String userid, String password, String realm)
+    {
+       this.authid = authid;
+       this.userid = userid;
+       this.password = password;
+       this.realm = realm;
+    }
+
+
+
+    private String getinput(String prompt)
+    {
+       System.out.println(prompt);
+       System.out.print(">");
+
+       String result="";
+           
+       try {
+           int c;
+           do {
+               c = System.in.read();
+               if (c!='\n')
+                   result+=(char)c;
+           } while (c!='\n');
+           
+           System.out.println("res = "+result);
+       } catch (IOException e) {
+
+       }
+       
+       return result;
+    }
+
+    private void getauthid(NameCallback c)
+    {
+       if (authid!=null) {
+           c.setName(authid);
+           return;
+       }
+
+       /*      authid = System.getProperty("user.name");
+       if (authid!=null) {
+           c.setName(authid);
+           return;
+           } */
+
+       c.setName( getinput(c.getPrompt()));
+    }
+
+    private void getpassword(PasswordCallback c)
+    {
+       if (password!=null) {
+           c.setPassword(password.toCharArray());
+           return;
+       }
+
+       c.setPassword( (getinput("Enter password")).toCharArray());
+    }
+
+    private void getrealm(RealmCallback c)
+    {
+       if (realm!=null) {
+           c.setRealm(realm);
+           return;
+       }         
+       
+       c.setRealm( getinput(c.getPrompt()) );
+    }
+
+    public void invokeCallback(Callback[] callbacks)
+       throws java.io.IOException, UnsupportedCallbackException
+    {
+       for (int lup=0;lup<callbacks.length;lup++)
+       {
+           Callback c = callbacks[lup];
+
+           if (c instanceof NameCallback) {
+               getauthid((NameCallback) c);
+           } else if (c instanceof PasswordCallback) {
+               getpassword((PasswordCallback) c);
+           } else if (c instanceof RealmCallback) {
+               getrealm((RealmCallback) c);
+           } else {
+               System.out.println("TODO!");
+               System.exit(1);
+           }
+       }
+    }
+
+    public void handle(Callback[] callbacks) 
+       throws java.io.IOException, UnsupportedCallbackException 
+    {
+       invokeCallback(callbacks);
+    }
+}
diff --git a/java/Test/Makefile.am b/java/Test/Makefile.am
new file mode 100644 (file)
index 0000000..ccda2f8
--- /dev/null
@@ -0,0 +1,27 @@
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+EXTRA_DIST = ServerHandler.java Handler.java jimtest.java testserver.java \
+            jimtest-compile.sh jimtest.sh
diff --git a/java/Test/Makefile.in b/java/Test/Makefile.in
new file mode 100644 (file)
index 0000000..4ca1ed5
--- /dev/null
@@ -0,0 +1,367 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the Java SASL library
+# Rob Earhart
+#
+################################################################
+#        Copyright 1998 by Carnegie Mellon University
+#
+#                      All Rights Reserved
+#
+#Permission to use, copy, modify, and distribute this software and its
+#documentation for any purpose and without fee is hereby granted,
+#provided that the above copyright notice appear in all copies and that
+#both that copyright notice and this permission notice appear in
+#supporting documentation, and that the name of Carnegie Mellon University
+#not be used in advertising or publicity pertaining to distribution of the
+#software without specific, written prior permission.
+#
+#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.
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+EXTRA_DIST = ServerHandler.java Handler.java jimtest.java testserver.java \
+            jimtest-compile.sh jimtest.sh
+
+subdir = java/Test
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/Test/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+       uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/Test/ServerHandler.java b/java/Test/ServerHandler.java
new file mode 100644 (file)
index 0000000..19f87a1
--- /dev/null
@@ -0,0 +1,112 @@
+
+import java.io.*;
+import javax.security.auth.callback.*;
+
+class ServerHandler implements javax.security.auth.callback.CallbackHandler{
+
+    String authid;
+    String userid;
+    String password;
+    String realm;
+    
+    public ServerHandler()
+    {
+
+    }
+
+    public ServerHandler(String authid, String userid, String password, String realm)
+    {
+       this.authid = authid;
+       this.userid = userid;
+       this.password = password;
+       this.realm = realm;
+    }
+
+
+
+    private String getinput(String prompt)
+    {
+       System.out.println(prompt);
+       System.out.print(">");
+
+       String result="";
+           
+       try {
+           int c;
+           do {
+               c = System.in.read();
+               if (c!='\n')
+                   result+=(char)c;
+           } while (c!='\n');
+           
+           System.out.println("res = "+result);
+       } catch (IOException e) {
+
+       }
+       
+       return result;
+    }
+
+    private void getauthid(NameCallback c)
+    {
+       if (authid!=null) {
+           c.setName(authid);
+           return;
+       }
+
+       /*      authid = System.getProperty("user.name");
+       if (authid!=null) {
+           c.setName(authid);
+           return;
+           } */
+
+       c.setName( getinput(c.getPrompt()));
+    }
+
+    private void getpassword(PasswordCallback c)
+    {
+       if (password!=null) {
+           c.setPassword(password.toCharArray());
+           return;
+       }
+
+       c.setPassword( (getinput("Enter password")).toCharArray());
+    }
+
+    private void getrealm(RealmCallback c)
+    {
+       if (realm!=null) {
+           c.setRealm(realm);
+           return;
+       }         
+       
+       c.setRealm( getinput(c.getPrompt()) );
+    }
+
+    public void invokeCallback(Callback[] callbacks)
+       throws java.io.IOException, UnsupportedCallbackException
+    {
+       for (int lup=0;lup<callbacks.length;lup++)
+       {
+           Callback c = callbacks[lup];
+
+           if (c instanceof NameCallback) {
+               getauthid((NameCallback) c);
+           } else if (c instanceof PasswordCallback) {
+               getpassword((PasswordCallback) c);
+           } else if (c instanceof RealmCallback) {
+               getrealm((RealmCallback) c);
+           } else {
+               System.out.println("TODO!");
+               System.exit(1);
+           }
+       }
+    }
+
+    public void handle(Callback[] callbacks)
+       throws java.io.IOException, UnsupportedCallbackException
+    {
+       invokeCallback(callbacks);
+    }
+
+}
diff --git a/java/Test/jimtest-compile.sh b/java/Test/jimtest-compile.sh
new file mode 100755 (executable)
index 0000000..7dfbea3
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+javac -classpath .:/usr/java/jre/lib/rt.jar:/usr/local/lib/java/classes/sasl *.java
diff --git a/java/Test/jimtest.java b/java/Test/jimtest.java
new file mode 100644 (file)
index 0000000..0faa557
--- /dev/null
@@ -0,0 +1,304 @@
+
+import java.net.*;
+import java.io.*;
+import java.util.Hashtable;
+import CyrusSasl.*;
+
+class jimtest
+{
+    private static PrintWriter os=null;
+    private static InputStreamReader ir=null;
+    private static Socket s=null;
+    private static BufferedReader br=null;
+
+  static void send(String str)
+  {
+      os.print(str+"\r\n");
+      os.flush();
+    
+  }
+
+    static boolean connect(String servername, int port)
+    {
+       try
+           {
+               s=new Socket(servername,port);
+           } catch (UnknownHostException e){
+               System.out.println("invalid host");
+               return false;
+           } catch (IOException e) {
+               System.out.println("invalid host");
+               return false;
+           }
+
+       try {
+           os=new PrintWriter(s.getOutputStream());
+           ir=new InputStreamReader(s.getInputStream());
+           br=new BufferedReader(ir);                  
+
+       } catch (IOException e) {
+           System.out.println("IO no work");   
+           return false;      
+       }
+
+               
+       System.out.println("connected...");
+
+       return true;                                            
+    }
+
+    static String[] parsecapabilities(String line)
+    {
+       String[] ret = new String[100];
+       int size = 0;
+       String tmp;
+       int pos = 0;
+
+       while (pos < line.length() )
+       {
+           char c;
+           tmp = "";
+
+           do {
+               c = line.charAt(pos);
+               tmp+=c;
+               pos++;
+           } while ((c!=' ') && (pos < line.length()));
+           
+           if (tmp.startsWith("AUTH=")==true)
+           {
+               ret[size++] = tmp.substring(5);
+           }
+       }
+       
+       return ret;
+    }
+
+    static String[] askcapabilities()
+    {
+       String line;
+       String mechs[];
+       
+       try {
+           
+           send(". CAPABILITY");
+           
+           do {
+               line = br.readLine();
+           } while (line.startsWith("* CAPABILITY")==false);
+           
+           mechs = parsecapabilities(line);
+
+           do {
+               line = br.readLine();
+           } while (line.startsWith(".")==false);
+
+       } catch (IOException e) {
+           System.out.println("IO no work");   
+           return null;      
+       }
+       
+       return mechs;
+    }
+
+    static SaslClient start_sasl(String[] mechs, String remoteserver, String localaddr, int minssf, int maxssf)
+    {
+       SaslClient conn;
+       Hashtable props = new Hashtable();
+       props.put("javax.security.sasl.encryption.minimum",String.valueOf(minssf));
+       props.put("javax.security.sasl.encryption.maximum",String.valueOf(maxssf));
+       props.put("javax.security.sasl.ip.local",localaddr);
+       props.put("javax.security.sasl.ip.remote",remoteserver);
+
+       Handler cbh = new Handler();
+
+       try {
+           conn = Sasl.createSaslClient(mechs,
+                                        "tmartin",
+                                        "imap",
+                                        remoteserver,
+                                        props,
+                                        cbh);
+
+           if (conn == null) {
+               System.out.println("conn is null");
+           }
+           
+           if (conn.hasInitialResponse()) {
+               /* xxx */
+           }
+
+           send(". AUTHENTICATE "+conn.getMechanismName());
+
+           do {
+
+               String line = br.readLine();
+
+               if (line.startsWith("+ ")==true) {
+
+                   line = line.substring(2);
+
+                   byte[] in = SaslUtils.decode64(line);
+
+                   byte[] out = conn.evaluateChallenge(in);
+
+                   String outline = SaslUtils.encode64(out);
+
+                   send(outline);
+
+               } else if (line.startsWith(". OK")==true) {
+                   System.out.println("S: " + line);
+
+                   if (conn.isComplete()==false) {
+                       System.out.println("Something funny going on here...");
+                       System.exit(1);
+                   }
+                   return conn;
+               } else {
+                   System.out.println("S: "+ line);
+                   /* authentication failed */
+                   return null;
+               } 
+
+           } while (true);
+           
+       } catch (SaslException e) {
+           System.out.println("SASL exception\n");
+       } catch (IOException e) {
+           System.out.println("IO exception\n");
+       }
+
+       return null;
+    }
+
+    static void be_interactive(SaslClient conn)
+    {
+       try {
+           InputStream saslin = conn.getInputStream(s.getInputStream());
+           OutputStream saslout = conn.getOutputStream(s.getOutputStream());
+           int len;
+           byte[] arr;
+
+           while (true)
+            {
+                if ((len = System.in.available())>0) {
+
+                    /* read from keyboard */
+                    arr = new byte[len+1];
+                    System.in.read(arr,0,len);
+
+                    if (arr[len-1]=='\n') {
+                        arr[len-1]= (byte) '\r';
+                        arr[len]= (byte) '\n';
+                    }
+                    
+                    /* write out to stream */               
+                    saslout.write(arr);
+                    saslout.flush();
+
+                } else if ((len = saslin.available())>0) {
+
+                    /* read from socket */
+                    arr = new byte[len];
+                    saslin.read(arr);
+
+                    System.out.print(new String(arr));
+
+                } else {
+                    /* sleep */
+                }
+            }
+
+       } catch (SaslException e) {
+
+       } catch (IOException e) {
+
+       }
+
+       
+    }
+
+    static void usage()
+    {
+       System.out.println("Usage:");
+       System.out.println("jimtest [-k minssf] [-l maxssf] [-m mech] [-p port] server");
+       System.exit(1);
+    }
+
+    public static void main (String args[])
+    {
+       String[] mechs;
+       SaslClient conn;
+
+       String arg;
+       int i = 0;
+       int minssf = 0;
+       int maxssf = 9999;
+       String onemech = null;
+       int port = 143;
+
+        while ((i < (args.length-1) ) && (args[i].startsWith("-"))) {
+           arg = args[i++];
+                   
+           // use this type of check for arguments that require arguments
+           if (arg.equals("-k")) {
+               if (i < args.length)
+                   minssf = Integer.parseInt(args[i++]);
+               else {
+                   System.err.println("-k requires a number");
+                   usage();
+               }
+           } else if (arg.equals("-l")) {
+               if (i < args.length)
+                   maxssf = Integer.parseInt(args[i++]);
+               else {
+                   System.err.println("-l requires a number");
+                   usage();
+               }
+           } else if (arg.equals("-m")) {
+               if (i < args.length)
+                   onemech = args[i++];
+               else {
+                   System.err.println("-m requires parameter");
+                   usage();
+               }
+           } else if (arg.equals("-p")) {
+               if (i < args.length)
+                   port = Integer.parseInt(args[i++]);
+               else {
+                   System.err.println("-p requires a number");
+                   usage();
+               }
+           } else {
+               usage();
+           }
+       }
+
+       if (i != args.length-1) usage();
+
+       String servername = args[i];
+
+       if (connect(servername,port)==false) {
+           System.out.println("Unable to connect to host: "+servername);
+           System.exit(1);
+       }
+
+       mechs = askcapabilities();
+
+       if (onemech!=null) {
+           mechs = new String[1];
+           mechs[0]=onemech;
+       }
+
+       conn = start_sasl(mechs,servername, s.getLocalAddress().getHostName(), minssf,maxssf);
+
+       if (conn == null) {
+           System.out.println("Authentication failed");
+           System.exit(1);
+       }
+
+       be_interactive(conn);
+    }
+
+
+}
diff --git a/java/Test/jimtest.sh b/java/Test/jimtest.sh
new file mode 100755 (executable)
index 0000000..261e397
--- /dev/null
@@ -0,0 +1,10 @@
+#!/bin/sh -p
+
+IMAPSERVER=cyrus.andrew.cmu.edu
+
+LD_LIBRARY_PATH=/usr/local/lib:/usr/openwin/lib:/usr/lib
+export LD_LIBRARY_PATH
+java  -cp .:/usr/java/jre/lib/rt.jar:/usr/local/lib/java/classes/sasl jimtest ${IMAPSERVER}
+
+
+
diff --git a/java/Test/testserver.java b/java/Test/testserver.java
new file mode 100644 (file)
index 0000000..716d9b9
--- /dev/null
@@ -0,0 +1,175 @@
+
+import CyrusSasl.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+class testserver {
+
+    static ServerSocket ssock;
+
+    private static PrintWriter os=null;
+    private static InputStreamReader ir=null;
+    private static Socket s=null;
+    private static BufferedReader br=null;
+
+    private static void give_capabilities() throws IOException
+    {
+       String []list = Sasl.getMechanismNames();
+
+       String cap="* CAPABILITY IMAP4 IMAP4rev1 ACL QUOTA LITERAL+ NAMESPACE UIDPLUS X-NON-HIERARCHICAL-RENAME NO_ATOMIC_RENAME";
+       
+       for (int lup=0;lup<list.length;lup++)
+           cap+= (" AUTH="+list[lup]);
+
+       send(cap);
+
+       send(". OK foo");
+    }
+
+    private static void do_auth(String mech, Socket remoteclient, int minssf, int maxssf) throws IOException
+    {
+       SaslClient conn;
+       Hashtable props = new Hashtable();
+       props.put("javax.security.sasl.encryption.minimum",String.valueOf(minssf));
+       props.put("javax.security.sasl.encryption.maximum",String.valueOf(maxssf));
+       props.put("javax.security.sasl.ip.local",s.getLocalAddress().getHostName());
+       props.put("javax.security.sasl.ip.remote",
+                 remoteclient.getInetAddress().getHostAddress());
+
+       ServerHandler cbh = new ServerHandler();
+
+       try {
+           
+           SaslServer saslconn = Sasl.CreateSaslServer(mech,
+                                                       "imap",
+                                                       s.getLocalAddress().getHostName(),
+                                                       props,
+                                                       cbh);
+
+           byte[]in = null;
+
+           while (true)
+           {
+               byte[] out = saslconn.evaluateResponse(in);
+               
+               if (saslconn.isComplete()==true) {
+                   break;
+               } else {
+                   String outline = "+ ";
+                   if (out!=null) {
+                       System.out.println("outlen = "+ (out.length));
+                       outline = "+ "+SaslUtils.encode64(out);
+                   }
+                   send(outline);
+               } 
+
+               String line = br.readLine();
+
+               System.out.println("in = "+line);
+
+               if (line!=null)
+                   in = SaslUtils.decode64(line);
+               else
+                   in = null;
+           }
+
+           send(". OK Authenticated");
+
+           System.out.println("Authenticated!!!\n");
+
+       } catch (SaslException e) {
+           send(". NO Authentication failed");
+       }
+    }
+
+    private static void pretend_to_be_imapd() throws IOException
+    {
+       String line;
+
+       send("* OK pretend imapd. Use the '.' tag");
+
+       while (true) {
+           
+           line = br.readLine();
+
+           if (line == null) {
+               System.out.println("I think the client quit on us");
+               System.exit(0);
+           }
+
+           if (line.startsWith(". ")==false) {
+               send("* BAD Must use '.' tag");
+               continue;
+           }
+
+           line=line.substring(2);
+
+           if (line.equalsIgnoreCase("CAPABILITY")==true) {
+               
+               give_capabilities();
+
+               continue;
+           }
+
+           if (line.toUpperCase().startsWith("AUTHENTICATE ")==true) {
+               line = line.substring(13);
+               
+               System.out.println("mechanism = "+line);
+
+               do_auth(line,s,0,0);
+
+               continue;
+           }
+
+           if (line.equalsIgnoreCase("NOOP")==true) {
+               send(". OK lalala");
+               continue;
+           }
+
+           if (line.equalsIgnoreCase("LOGOUT")==true) {
+
+               send(". OK yeah i'll exit. seya");
+               s.close();
+               System.exit(0);
+           }
+
+           send("* BAD don't support whatever you tried");
+       }
+
+
+       
+    }
+
+    static void send(String str)
+    {
+       os.print(str+"\r\n");
+       os.flush();
+    }
+
+    public static void main (String args[])
+    {
+       int port = 2143;
+       
+       try {
+       
+           ssock = new ServerSocket(port);
+
+           System.out.println("Listening on port "+port);
+           
+           s = ssock.accept();
+           os=new PrintWriter(s.getOutputStream());
+           ir=new InputStreamReader(s.getInputStream());
+           br=new BufferedReader(ir);                  
+
+
+           pretend_to_be_imapd();
+
+       } catch (IOException e) {
+           System.out.println("IO exception");
+       }
+    }
+
+
+
+}
diff --git a/java/doc/.cvsignore b/java/doc/.cvsignore
new file mode 100644 (file)
index 0000000..13bb78d
--- /dev/null
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+.deps
+.libs
+*.l[ao]
diff --git a/java/doc/draft-weltman-java-sasl-02.txt b/java/doc/draft-weltman-java-sasl-02.txt
new file mode 100644 (file)
index 0000000..89dc9c9
--- /dev/null
@@ -0,0 +1,1444 @@
+
+    Internet Draft                                    Rob Weltman
+                                                        Netscape Communications Corp.
+                                                      Rosanna Lee
+  draft-weltman-java-sasl-02.txt                        Sun Microsystems
+                                                      Rob Earhart
+                                                        Carnegie Mellon
+                                                        June 4, 1999
+
+
+              The Java SASL Application Program Interface
+
+
+Status of this Memo
+
+   This document is an Internet-Draft and is in full conformance with
+   all provisions of Section 10 of RFC2026.
+
+   Internet-Drafts are working documents of the Internet Task Force
+   (IETF), its areas, and its working groups.  Note that other groups
+   may also distribute working documents as Internet-Drafts.
+
+   Internet-Drafts are draft documents valid for a maximum of six
+   months and may be updated, replaced, or obsoleted by other documents
+   at any time.  It is inappropriate to use Internet Drafts as
+   reference material or to cite them other than as "work in progress."
+
+   The list of current Internet-Drafts can be accessed at
+   http://www.ietf.org/ietf/1id-abstracts.txt
+
+   The list of Internet-Draft Shadow Directories can be accessed at
+   http://www.ietf.org/shadow.html.
+
+
+
+Abstract
+
+   This document defines a client-side and a server-side Java language
+   interface for using the Simple Authentication and Security Layer
+   (SASL) mechanisms for adding authentication support to connection-
+   based protocols. The interface promotes sharing of SASL mechanism
+   drivers and security layers between applications using different
+   protocols. It complements but does not replace [SASL], which defines
+   and exemplifies use of the SASL protocol in a language-independent
+   way.
+
+
+
+
+
+
+
+
+
+
+
+
+ Expires 12/99                                                [Page 1]
+\f
+JAVA SASL API                                                June 1999
+
+
+1    Overview of the SASL classes..........................5
+1.1  Interfaces     .......................................5
+1.2  Classes        .......................................5
+2    Overview of SASL API Use..............................6
+3    The java SASL classes.................................7
+3.1  public class Sasl.....................................7
+3.1.1     createSaslClient.................................7
+3.1.2     setSaslClientFactory.............................9
+3.1.3     createSaslServer.................................9
+3.1.4     setSaslServerFactory............................10
+3.2  public interface SaslClient..........................11
+3.2.1     createInitialResponse...........................11
+3.2.2     evaluateChallenge...............................11
+3.2.3     isComplete......................................11
+3.2.4     getSecurityLayer................................11
+3.2.5     getMechanismName................................12
+3.3  public interface SaslClientFactory...................12
+3.3.1     createSaslClient................................12
+3.3.2     getMechanismNames...............................13
+3.4  public interface SaslServer..........................13
+3.4.1     evaluateResponse................................13
+3.4.2     isComplete......................................14
+3.4.3     getSecurityLayer................................14
+3.4.4     getMechanismName................................14
+3.4.5     getAuthorizationID..............................14
+3.5  public interface SaslServerFactory...................15
+3.5.1     createSaslServer................................15
+3.5.2     getMechanismNames...............................16
+3.6  public class SaslException...........................16
+3.6.1     Constructors....................................16
+3.6.2     getException....................................17
+3.6.3     printStackTrace.................................17
+3.7  public interface SecurityLayer.......................17
+3.7.1         encode......................................17
+3.7.2         decode......................................18
+4    Security Considerations..............................19
+5    Bibliography   ......................................19
+6    Authors' Addresses...................................19
+7    Acknowledgements.....................................19
+8    Appendix A - Sample java LDAP program using SASL.....20
+9    Appendix B - Changes from java-sasl-01.txt...........24
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires 12/99                                                 [Page 2]
+\f
+JAVA SASL API                                                June 1999
+
+Introduction
+
+
+   See [SASL], section 3, for an introduction to and overview of the
+   SASL framework for authentication and negotiation of a security
+   layer. The following presents an outline of the concepts.
+
+    ---------------     -------------------      -----------------
+    | Application |-----| Protocol Driver |------| MD5           |
+    ---------------     -------------------   |  -----------------
+                                              |
+                                              |  -----------------
+                                              |--| Kerberos v5   |
+                                              |  -----------------
+                                              |
+                                              |  -----------------
+                                              |--| PKCS-11       |
+                                              |  -----------------
+                                              |
+                                              |
+                                              |
+                                              |  - - - - - - - - -
+                                              |--| xxxYYYxxx     |
+                                                 - - - - - - - - -
+
+   An application chooses a Protocol Driver specific to the protocol it
+   wants to use, and specifies one or more acceptable mechanisms. The
+   Protocol Driver controls the socket, and knows the format/packaging
+   of bytes sent down and received from the socket, but does not know
+   how to authenticate or to encrypt/ decrypt the bytes. It uses one of
+   the Mechanism Drivers to help it perform authentication. The
+   Protocol Driver examines each byte string received from the server
+   during the authentication in a protocol-specific way to determine if
+   the authentication process has been completed. If not, the byte
+   string is passed to the Mechanism Driver to be interpreted as a
+   server challenge; the Mechanism Driver returns an appropriate
+   response, which the Protocol Driver can encode in a protocol-
+   specific way and return to the server.
+
+   If the Protocol Driver concludes from the byte string received from
+   the server that authentication is complete, it may query the
+   Mechanism Driver if it considers the authentication process
+   complete, in order to thwart early completion messages inserted by
+   an intruder.
+
+   On completed authentication, the Protocol Driver may receive from
+   the Mechanism Driver a Security Layer object. From this point on,
+   any data exchanged throught the socket is passed to the Security
+   Layer object for encoding/decoding.
+
+   A complication here is that some authentication methods may require
+   additional user/application input.  That means that a Mechanism
+   Driver may need to call up to an application during the
+   authentication process. To satisfy this requirement, the application
+
+
+Expires 12/99                                                 [Page 3]
+\f
+JAVA SASL API                                                June 1999
+
+   can supply a javax.security.auth.callback.CallbackHandler instance
+   [JAAS] that can be used by the Mechanism Driver to prompt the user
+   for additional input.
+
+   Protocol Drivers are protocol-dependent, and may be built in to a
+   protocol package or an application. There is a generalized framework
+   for registering and finding Mechanism Drivers. The framework uses a
+   factory to produce an appropriate Mechanism Driver. The factory may
+   be preconfigured, explicitly specified by the caller, specified as a
+   list of packages by the caller, or be identified based on a list of
+   packages in the System properties.
+
+   The Mechanism Drivers are protocol-independent, and don't deal
+   directly with network connections, just byte arrays, so they can be
+   implemented in a generalizable way for all protocols.
+
+   A Security Layer Driver typically inherits a state object from the
+   Mechanism Driver, where parameters and resolutions reached during
+   authentication have been stored.
+
+   Different Mechanism Drivers may require different parameters to
+   carry out the authentication process. This is handled by passing a
+   java.util.Hashtable object as an argument to instantiation methods.
+
+   In the following discussion, 'client' refers to the client-side
+   protocol driver that is using the SASL mechanism while 'server'
+   refers to the server-side protocol driver that is using the SASL
+   mechanism.
+
+   In the Java SASL environment, the SaslClient interface represents
+   the client's view of the Mechanism Driver, while the SaslServer
+   interface represents the server's view.
+
+   ---------------                                     ---------------
+   | Application |--+                               +--|   Server    |
+   ---------------  |                               |  ---------------
+                    |                               |
+       -------------------                       -------------------
+       | Protocol Driver |--+   <- - - - ->   +--| Protocol Driver |
+       -------------------  |                 |  -------------------
+                            |                 |
+                 -------------------     -------------------
+                 |   SaslClient    |     |    SaslServer   |
+                 -------------------     -------------------
+                               |              |
+          -----------------    |              |   -----------------
+          | MD5           |----|              |---| MD5           |
+          -----------------    |              |   -----------------
+                               |              |
+          -----------------    |              |   -----------------
+          | Kerberos v5   |----|              |---| Kerberos v5   |
+          -----------------    |              |   -----------------
+                               |              |
+          -----------------    |              |   -----------------
+
+
+Expires 12/99                                                 [Page 4]
+\f
+JAVA SASL API                                                June 1999
+
+          | PKCS-11       |----|              |---| PKCS-11       |
+          -----------------    |              |   -----------------
+                               |              |
+          - - - - - - - - -    |              |   - - - - - - - - -
+          | xxxYYYxxx     |----+              +---| xxxYYYxxx     |
+          - - - - - - - - -                       - - - - - - - - -
+
+   A client using the Java SASL API may communicate with any server
+   implementing the SASL protocol, and a server may use the API to
+   process authentication requests from any client using the SASL
+   protocol. It is not required that both sides use the same language
+   bindings.
+
+1     Overview of the SASL classes
+
+
+1.1   Interfaces
+
+
+   SaslClient                  Performs SASL authentication as a
+                               client.
+
+   SaslClientFactory           An interface for creating instances of
+                               SaslClient. It is not normally accessed
+                               directly by a client, which will use the
+                               Sasl static methods instead. However, a
+                               particular environment may provide and
+                               install a new or different
+                               SaslClientFactory.
+
+   SaslServer                  Performs SASL authentication as a
+                               server.
+
+   SaslServerFactory           An interface for creating instances of
+                               SaslServer. It is not normally accessed
+                               directly by a server, which will use the
+                               Sasl static methods instead. However, a
+                               particular environment may provide and
+                               install a new or different
+                               SaslServerFactory.
+
+   SecurityLayer               An interface for encoding and decoding
+                               data.
+
+
+1.2   Classes
+
+
+   Sasl                        A static class for creating SASL clients
+                               and servers. It transparently locates
+                               and uses any available
+                               SaslClientFactory/SaslServerFactory
+                               instances.
+
+
+
+Expires 12/99                                                 [Page 5]
+\f
+JAVA SASL API                                                June 1999
+
+   SaslException               Exception thrown on errors and failures
+                               in the authentication process.
+
+
+2     Overview of SASL API Use
+
+   An application generally uses the SASL API as follows:
+
+   -    Pass a list of acceptable or known Mechanisms to
+        Sasl.createSaslClient. The method returns an object
+        implementing SaslClient on success.
+
+   -    Create an object implementing the client authentication
+        callback interfaces, which can provide credentials when
+        required by the SaslClient.
+
+   -    Have the SaslClient object begin the authentication process by
+        providing an initial server response, if the protocol supports
+        an initial response.
+
+   -    Responses/challenges are exchanged with the server. If a
+        response indicates authentication has completed, SaslClient is
+        queried for validation, and a SecurityLayer object may be
+        obtained from it. If not, the SaslClient is queried for an
+        appropriate next response to the server. This continues until
+        authentication has completed.
+
+   -    For the rest of the session, messages to the server are encoded
+        first by the Security Layer (if one has been provided by
+        SaslClient), and messages from the server are decoded by it
+        before processing in the application.
+
+
+   A server generally uses the SASL API as follows:
+
+   -    It receives a request from the client requesting authentication
+        for a particular SASL mechanism, accompanied by an optional
+        an initial response.
+
+   -    It processes the initial response and generates a challenge
+        specific for the SASL mechanism to be sent back to the client
+        if the response is processed successfully. If the response is
+        not processed successfully, it sends an error to the client and
+        terminates the authentication session.
+
+   -    Responses/challenges are exchanged with the client. If the
+        server cannot successful process a response, the server sends
+        an error to the client and terminates the authentication. If
+        the server has completed the authentication and has no more
+        challenges to send, it sends a success indication to the
+        client.
+
+   -    If the authentication has completed successfully, the server
+        extracts the authorization ID of the client from the SaslServer
+
+
+Expires 12/99                                                 [Page 6]
+\f
+JAVA SASL API                                                June 1999
+
+        instance (if appropriate) to be used for subsequent access
+        control checks.
+
+   -    For the rest of the session, messages to and from the client
+        are encoded and decoded by the Security Layer, if one has been
+        provided by SaslServer.
+
+   The following sections describe the SASL classes in more detail.
+
+
+3     The Java SASL classes
+
+
+3.1   public class Sasl
+
+   A class capable of providing a SaslClient or SaslServer.
+
+
+3.1.1 createSaslClient
+
+   public static SaslClient
+   createSaslClient(String[] mechanisms,
+                    String authorizationID,
+                    String protocol,
+                    String serverName,
+                    Hashtable props,
+                    javax.security.auth.callback.CallbackHandler cbh)
+                    throws SaslException
+
+   Creates a SaslClient using the parameters supplied. It returns null
+   if no SaslClient can be created using the parameters supplied.
+   Throws SaslException if it cannot create a SaslClient because of an
+   error.
+
+   The algorithm for selection is as follows:
+
+      1.If a factory has been installed via setSaslClientFactory(), try
+        it first. If non-null answer produced, return it.
+      2.Use the packages listed in the javax.security.sasl.client.pkgs
+        property from props to load in a factory and try to create a
+        SaslClient, by looking for a class named ClientFactory. Repeat
+        this for each package on the list until a non-null answer is
+        produced. If non-null answer produced, return it.
+      3.Repeat previous step using the javax.security.sasl.client.pkgs
+        System property.
+      4.If no non-null answer produced, return null.
+
+   Parameters are:
+
+      mechanisms     The non-null list of mechanism names to try. Each
+                      is the IANA-registered name of a SASL mechanism.
+                      (e.g. "GSSAPI", "CRAM-MD5").
+
+
+
+
+Expires 12/99                                                 [Page 7]
+\f
+JAVA SASL API                                                June 1999
+
+      authorizationIDThe possibly null protocol-dependent
+                      identification to be used for authorization, e.g.
+                      user name or distinguished name. When the SASL
+                      authentication completes successfully, the entity
+                      named by authorizationId is granted access. If
+                      null, access is granted to a protocol-dependent
+                      default (for example, in LDAP this is the DN in
+                      the bind request).
+
+      protocol       The non-null string name of the protocol for
+                      which the authentication is being performed, e.g
+                      "pop", "ldap".
+
+      serverName     The non-null fully qualified host name of the
+                      server to authenticate to.
+
+      props          The possibly null additional configuration
+                      properties for the session, e.g.
+
+           javax.security.sasl.encryption.minimum  Minimum key length;
+                                                    default "0" (no
+                                                    session
+                                                    protection). "1"
+                                                    means integrity
+                                                    protection only.
+
+           javax.security.sasl.encryption.maximum  Maximum key length;
+                                                    default "256".
+
+           javax.security.sasl.server.authentication   "true" if
+                                                    server must
+                                                    authenticate to
+                                                    client; default
+                                                    "false".
+
+           javax.security.sasl.ip.local            IP address in
+                                                    dotted decimal
+                                                    format, for
+                                                    kerberos v4; no
+                                                    default.
+
+           javax.security.sasl.ip.remote           IP address in
+                                                    dotted decimal
+                                                    format, for
+                                                    kerberos v4; no
+                                                    default.
+
+           javax.security.sasl.maxbuffer           Maximum size of
+                                                    security layer
+                                                    frames; default "0"
+                                                    (client will
+                                                    not use the
+                                                    security layer).
+
+
+
+Expires 12/99                                                 [Page 8]
+\f
+JAVA SASL API                                                June 1999
+
+           javax.security.sasl.client.pkgs         A space-separated
+                                                    list of package
+                                                    names to use when
+                                                    locating a
+                                                    SaslClientFactory.
+
+      cbh            The possibly null callback handler to used by the
+                      SASL mechanisms to get further information  from
+                      the application/library to complete the
+                      authentication. For example, a SASL mechanism
+                      might require the authentication ID and password
+                      from the caller. The authentication ID may be
+                      requested with a NameCallback, and the password
+                      with a PasswordCallback.
+
+
+3.1.2 setSaslClientFactory
+
+   public static void
+   setSaslClientFactory(SaslClientFactory fac)
+
+   Sets the default SaslClientFactory to use. This method sets fac to
+   be the default factory. It can only be called with a non-null value
+   once per VM. If a factory has been set already, this method throws
+   IllegalStateException.
+
+   Parameters are:
+
+      fac            The possibly null factory to set. If null, it
+                      doesn't do anything.
+
+
+
+3.1.3 createSaslServer
+
+   public static SaslServer
+   createSaslServer(String mechanism,
+                    String protocol,
+                    String serverName,
+                    Hashtable props,
+                    javax.security.auth.callback.CallbackHandler cbh)
+                    throws SaslException
+
+   This method creates a SaslServer for the specified mechanism. It
+   returns null if no SaslServer can be created for the specified
+   mechanism.
+
+   The algorithm for selection is as follows:
+
+      1.If a factory has been installed via setSaslServerFactory(), try
+        it first. If non-null answer produced, return it.
+      2.Use the packages listed in the javax.security.sasl.server.pkgs
+        property in props, if present, to load in a factory and try to
+        create a SaslServer, by looking for a class named
+
+
+Expires 12/99                                                 [Page 9]
+\f
+JAVA SASL API                                                June 1999
+
+        ServerFactory. Repeat this for each package on the list until a
+        non-null answer is produced. If non-null answer produced,
+        return it.
+      3.Use the packages listed in the javax.security.sasl.server.pkgs
+        System property to load in a factory and try to create a
+        SaslServer. Repeat this for each package on the list until a
+        non-null answer is produced. If non-null answer produced,
+        return it.
+      4.If no non-null answer produced, return null.
+
+   Parameters are:
+
+      mechanism      A non-null IANA-registered name of a SASL
+                      mechanism (e.g. "GSSAPI", "CRAM-MD5").
+
+      protocol       The non-null string name of the protocol for
+                      which the authentication is being performed, e.g
+                      "pop", "ldap".
+
+      serverName     The non-null fully qualified host name of the
+                      server to authenticate to.
+
+      props          The possibly null properties to be used by the
+                      SASL mechanisms to configure the authentication
+                      exchange. See Sasl.createSaslClient for examples
+                      of properties.
+
+      cbh            The possibly null callback handler to used by the
+                      SASL mechanisms to get further information  from
+                      the application/library to complete the
+                      authentication. For example, a SASL mechanism
+                      might require the authentication ID and password
+                      from the caller. The authentication ID may be
+                      requested with a NameCallback, and the password
+                      with a PasswordCallback.
+
+
+3.1.4 setSaslServerFactory
+
+   public static void
+   setSaslServerFactory(SaslServerFactory fac)
+
+   Sets the default SaslServerFactory to use. This method sets fac to
+   be the default factory. It can only be called with a non-null value
+   once per VM. If a factory has been set already, this method throws
+   IllegalStateException.
+
+   Parameters are:
+
+      fac            The possibly null factory to set. If null, it
+                      doesn't do anything.
+
+
+
+
+
+Expires 12/99                                                [Page 10]
+\f
+JAVA SASL API                                                June 1999
+
+3.2   public interface SaslClient
+
+   An object implementing this interface can negotiate authentication
+   using one of the IANA-registered mechanisms.
+
+
+3.2.1 createInitialResponse
+
+   public byte[]
+   createInitialResponse() throws SaslException
+
+   This method prepares a byte array to use for the initial response to
+   start the authentication process. A SaslException is thrown if the
+   driver cannot initiate authentication.  The return value may be
+   null, indicating there is no initial response to send to the server.
+
+
+3.2.2 evaluateChallenge
+
+   public byte[]
+   evaluateChallenge(byte[] challenge)
+                    throws SaslException
+
+   If a challenge is received from the server during the authentication
+   process, this method is called to prepare an appropriate next
+   response to submit to the server. The response is null if the
+   challenge accompanied a "SUCCESS" status and the challenge only
+   contains data for the client to update its state and no response
+   needs to be sent to the server. A SaslException is thrown if an
+   error occurred while processing the challenge or generating a
+   response.
+
+   Parameters are:
+
+      challenge      The non-null challenge received from the server.
+
+
+3.2.3 isComplete
+
+   public boolean
+   isComplete()
+
+   This method may be called at any time to determine if the
+   authentication process is finished. Typically, the protocol driver
+   will not do this until it has received something from the server
+   which indicates (in a protocol-specific manner) that the process has
+   completed.
+
+3.2.4 getSecurityLayer
+
+   public SecurityLayer
+   getSecurityLayer() throws SaslException
+
+
+
+
+Expires 12/99                                                [Page 11]
+\f
+JAVA SASL API                                                June 1999
+
+   Once authentication is complete, this method may be called to obtain
+   an object capable of encoding/decoding data content for the rest of
+   the session. An exception is thrown if authentication is not yet
+   complete. It may return null if the mechanism does not define a
+   security layer, or if none was negotiated.
+
+
+3.2.5 getMechanismName
+
+   public String
+   getMechanismName()
+
+   Report the IANA-registered name of the mechanism used by this
+   client, e.g. "GSSAPI" or "CRAM-MD5".
+
+
+
+3.3   public interface SaslClientFactory
+
+   An object implementing this interface can provide a SaslClient.
+   Implementations must be thread-safe and handle multiple simultaneous
+   requests.
+
+
+3.3.1 createSaslClient
+
+   public SaslClient
+   createSaslClient(String[] mechanisms,
+                    String authorizationID,
+                    String protocol,
+                    String serverName,
+                    Hashtable props,
+                    javax.security.auth.callback.CallbackHandler cbh)
+                    throws SaslException
+
+   Creates a SaslClient using the parameters supplied. It returns null
+   if no SaslClient can be created using the parameters supplied.
+   Throws SaslException if it cannot create a SaslClient because of an
+   error.
+
+   Returns a possibly null SaslClient created using the parameters
+   supplied. If null, this factory cannot produce a SaslClient using
+   the parameters supplied.
+
+      Parameters are:
+
+      mechanisms     The non-null list of mechanism names to try. Each
+                      is the IANA-registered name of a SASL mechanism.
+                      (e.g. "GSSAPI", "CRAM-MD5").
+
+      authorizationID The possibly null protocol-dependent
+                      identification to be used for authorization, e.g.
+                      user name or distinguished name. When the SASL
+                      authentication completes successfully, the entity
+
+
+Expires 12/99                                                [Page 12]
+\f
+JAVA SASL API                                                June 1999
+
+                      named by authorizationId is granted access. If
+                      null, access is granted to a protocol-dependent
+                      default (for example, in LDAP this is the DN in
+                      the bind request).
+
+      protocol       The non-null string name of the protocol for
+                      which the authentication is being performed, e.g
+                      "pop", "ldap".
+
+      serverName     The non-null fully qualified host name of the
+                      server to authenticate to.
+
+      props          The possibly null properties to be used by the
+                      SASL mechanisms to configure the authentication
+                      exchange. See Sasl.createSaslClient for examples
+                      of properties.
+
+      cbh            The possibly null callback handler to used by the
+                      SASL mechanisms to get further information  from
+                      the application/library to complete the
+                      authentication. For example, a SASL mechanism
+                      might require the authentication ID and password
+                      from the caller. The authentication ID may be
+                      requested with a NameCallback, and the password
+                      with a PasswordCallback.
+
+
+
+3.3.2 getMechanismNames
+
+   public String[]
+   getMechanismNames()
+
+   Returns a non-null array of names of mechanisms supported by this
+   factory.
+
+
+3.4   public interface SaslServer
+
+   An object implementing this interface can negotiate authentication
+   using one of the IANA-registered mechanisms.
+
+
+3.4.1 evaluateResponse
+
+   public byte[]
+   evaluateResponse(byte[] response)
+                    throws SaslException
+
+   If a response is received from the client during the authentication
+   process, this method is called to prepare an appropriate next
+   challenge to submit to the client. The challenge is null if the
+   authentication has succeeded and no more challenge data is to be
+   sent to the client. It is non-null if the authentication must be
+
+
+Expires 12/99                                                [Page 13]
+\f
+JAVA SASL API                                                June 1999
+
+   continued by sending a challenge to the client, or if the
+   authentication has succeeded but challenge data needs to be
+   processed by the client. A SaslException is thrown if an error
+   occurred while processing the response or generating a challenge.
+   isComplete() should be called after each call to evaluateResponse(),
+   to determine if any further response is needed from the client. The
+   protocol driver will send an indication (in a protocol-specific
+   manner) as to whether the authentication has succeeded, failed, or
+   should be continued, and any accompanying challenge data.
+
+   Parameters are:
+
+      response       Non-null response received from client.
+
+
+3.4.2 isComplete
+
+   public boolean
+   isComplete()
+
+   This method may be called at any time to determine if the
+   authentication process is finished. This method is typically called
+   after each invocation of evaluateResponse() to determine whether the
+   authentication has completed successfully or should be continued.
+
+
+3.4.3 getSecurityLayer
+
+   public SecurityLayer
+   getSecurityLayer() throws SaslException
+
+   Once authentication is complete, this method may be called to obtain
+   an object capable of encoding/decoding data content for the rest of
+   the session. An exception is thrown if authentication is not yet
+   complete. It may return null if the mechanism does not define a
+   security layer, or if none was negotiated.
+
+
+3.4.4 getMechanismName
+
+   public String
+   getMechanismName()
+
+   Returns the non-null IANA-registered name of the mechanism used by
+   this server, e.g. "GSSAPI" or "CRAM-MD5".
+
+
+3.4.5 getAuthorizationID
+
+   public String
+   getAuthorizationID()
+
+   Report the authorization ID in effect for the client of this
+   session. If null, a protocol-dependent default is assumed.
+
+
+Expires 12/99                                                [Page 14]
+\f
+JAVA SASL API                                                June 1999
+
+
+
+
+3.5   public interface SaslServerFactory
+
+   An object implementing this interface can provide a SaslServer.
+   Implementations must be thread-safe and handle multiple simultaneous
+   requests.
+
+
+3.5.1 createSaslServer
+
+   public SaslServer
+   createSaslServer(String mechanism,
+                    String protocol,
+                    String serverName,
+                    Hashtable props,
+                    javax.security.auth.callback.CallbackHandler cbh)
+                    throws SaslException
+
+   Creates a SaslServer using the mechanism supplied. It returns null
+   if no SaslClient can be created using the parameters supplied.
+   Throws SaslException if it cannot create a SaslClient because of an
+   error.
+
+   Returns a possibly null SaslServer which supports the specified
+   mechanism. If null, this factory cannot produce a SaslServer for the
+   specified mechanism.
+
+      Parameters are:
+
+      mechanism      The non-null IANA-registered name of a SASL
+                      mechanism (e.g. "GSSAPI", "CRAM-MD5").
+
+      protocol       The non-null string name of the protocol for
+                      which the authentication is being performed, e.g
+                      "pop", "ldap".
+
+      serverName     The non-null fully qualified host name of the
+                      server.
+
+      props          The possibly null properties to be used by the
+                      SASL mechanisms to configure the authentication
+                      exchange. See Sasl.createSaslClient for examples
+                      of properties.
+
+      cbh            The possibly null callback handler to used by the
+                      SASL mechanisms to get further information  from
+                      the application/library to complete the
+                      authentication. For example, a SASL mechanism
+                      might require the authentication ID and password
+                      from the caller. The authentication ID may be
+                      requested with a NameCallback, and the password
+                      with a PasswordCallback.
+
+
+Expires 12/99                                                [Page 15]
+\f
+JAVA SASL API                                                June 1999
+
+
+
+3.5.2 getMechanismNames
+
+   public String[]
+   getMechanismNames()
+
+   Returns a non-null array of names of mechanisms supported by this
+   factory.
+
+
+3.6   public class SaslException
+   extends IOException
+
+   Exception thrown on errors and failures in authentication.
+
+
+3.6.1 Constructors
+
+   public SaslException()
+
+   Constructs a new instance of SaslException. The root exception and
+   the detailed message are null.
+
+
+   public SaslException(String message)
+
+
+   Constructs a default exception with a detailed message and no root
+   exception.
+
+
+   public SaslException(String messag,
+                        Throwable ex)
+
+   Constructs a new instance of SaslException with a detailed message
+   and a root exception. For example, a SaslException might result from
+   a problem with the callback handler, which might throw a
+   NoSuchCallbackException if it does not support the requested
+   callback, or throw an IOException if it had problems obtaining data
+   for the callback. The SaslException's root exception would be then
+   be the exception thrown by the callback handler.
+
+
+   Parameters are:
+
+      message        Possibly null additional detail about the
+                      exception.
+
+      ex             A possibly null root exception that caused this
+                      exception.
+
+
+
+
+
+Expires 12/99                                                [Page 16]
+\f
+JAVA SASL API                                                June 1999
+
+3.6.2 getException
+
+   public Throwable
+   getException()
+
+   Returns the possibly null root exception that caused this exception.
+
+
+3.6.3 printStackTrace
+
+   public void
+   printStackTrace()
+
+   Prints this exception's stack trace to System.err. If this
+   exception has a root exception, the stack trace of the root
+   exception is printed to System.err instead.
+
+   public void
+   printStackTrace(PrintStream ps)
+
+   Prints this exception's stack trace to a print stream. If this
+   exception has a root exception, the stack trace of the root
+   exception is printed to the print stream instead.
+
+   public void
+   printStackTrace(PrintWriter pw)
+
+   Prints this exception's stack trace to a print writer. If this
+   exception has a root exception, the stack trace of the root
+   exception is printed to the print writer instead.
+
+   Parameters are:
+
+      ps             The non-null print stream to which to print.
+
+      pw             The non-null print writer to which to print.
+
+
+3.7 public interface SecurityLayer
+
+   An object implementing this interface translates buffers back and
+   forth during a session, after the authentication process has
+   completed, to provide a security layer. The security layer may
+   provide data integrity and/or session privacy.
+
+
+3.7.1 encode
+
+   public byte[]
+   encode(byte[] inVals, int offset, int count) throws SASLException
+
+   Take a protocol-dependent byte array and encode it (encrypt, for
+   example) for sending to the server.
+
+
+
+Expires 12/99                                                [Page 17]
+\f
+JAVA SASL API                                                June 1999
+
+
+   Parameters are:
+
+      inVals         A request to be encoded before sending to the
+                      server.
+
+      offset         The inclusive starting offset in the byte array
+                      inVals to use. 0 <= offset < inVals.length.
+
+      count          The number of bytes in inVals to use.
+                      0 <= count < inVals.length-offset.
+
+
+3.7.2 decode
+
+   public byte[]
+   decode(byte[] outVals, int offset, int count) throws SASLException
+
+   Take an encoded byte array received from the server and decode it.
+
+   Parameters are:
+
+      outVals        A response received from the server, to be
+                      decoded.
+
+      offset         The inclusive starting offset in the byte array
+                      outVals to use. 0 <= offset < outVals.length.
+
+      count          The number of bytes in outVals to use.
+                      0 <= count < outVals.length-offset.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires 12/99                                                [Page 18]
+\f
+JAVA SASL API                                                June 1999
+
+4     Security Considerations
+
+   When SASL authentication is performed over unsecured connections, it
+   is possible for an active attacker to spoof the server's protocol-
+   specific indication that authentication is complete.  Clients should
+   protect against this attack by verifying the completion of
+   authentication with the mechanism driver by calling the driver's
+   isComplete() method.
+
+   Additional security considerations are discussed in [SASL].
+
+
+5     Bibliography
+
+   [JAAS] Java Software, Sun Microsystems, Inc., "Java Authentication
+        and Authorization Service," http://java.sun.com/security/jaas,
+        March 1999.
+
+   [SASL] J. Myers, "Simple Authentication and Security Layer (SASL)",
+        RFC 2222, October 1997
+
+
+6     Authors' Addresses
+
+      Rob Weltman
+      Netscape Communications Corp.
+      501 E. Middlefield Rd.
+      Mail Stop MV-029
+      Mountain View, CA 94043-4042
+      USA
+      Email: rweltman@netscape.com
+
+      Rosanna Lee
+      Sun Microsystems
+      Mail Stop UCUP02-206
+      901 San Antonio Road
+      Palo Alto, CA  94303
+      USA
+      Email: rosanna.lee@eng.sun.com
+
+      Rob Earhart
+      Carnegie Mellon
+      5000 Forbes Ave.
+      Pittsburgh, PA 15213-3890
+      USA
+      Email: earhart@cmu.edu
+
+
+7     Acknowledgements
+
+   Scott Seligman of Sun Microsystems, Inc. contributed to the
+   architecture and API proposed in this document.
+
+
+
+
+Expires 12/99                                                [Page 19]
+\f
+JAVA SASL API                                                June 1999
+
+8     Appendix A - Sample java LDAP program using SASL
+
+   /****************************************************************
+    It might look like this in LDAP. The Protocol Driver is
+    implemented as part of the authenticate method of
+    LDAPConnection.
+   ****************************************************************/
+
+   public class LDAPConnection {
+     public void authenticate( String dn,
+                               String[] mechs,
+                               Hashtable props,
+                               CallbackHandler cbh )
+                               throws SaslException {
+
+       // Create SASL client to use for authentication
+       SaslClient saslClnt = Sasl.createSaslClient(
+                   mechs, dn, "ldap", getHost(), props, cbh);
+
+       if (saslClnt == null) {
+           throw new SaslException("SASL client not available");
+       }
+
+       String mechName = saslClnt.getMechanismName();
+       byte[] response = saslClnt.createInitialResponse();
+
+       // Create a bind request message, including the initial
+
+       // response (if any), and send it off
+
+       LDAPSASLBindResponse msg =
+
+           writeRequest( new LDAPSASLBindRequest( dn, mechName,
+
+                                                  response ) );
+
+       // Get the server challenge
+       LDAPSASLBindResponse msg = (LDAPSASLBindResponse)readResponse();
+       // Authentication done?
+       while (!saslClnt.isComplete() &&
+              msg.getStatus() == LDAP_SASL_BIND_IN_PROGRESS) {
+           // No, get an appropriate next response and send it off
+           byte[] challenge = msg.getChallenge();
+           response = saslClnt.evaluateChallenge( challenge );
+           // May be a success message with no further challenge
+           if ( response != null ) {
+               // Wrap the response in another bind request and
+               // send it off
+               writeRequest( new LDAPSASLBindRequest( dn,
+                                               mechName, response ) );
+               msg = (LDAPSASLBindResponse)readResponse();
+           }
+       }
+       // Make sure authentication REALLY is complete
+       if ( !driver.isComplete() ) {
+           /* Authentication session hijacked! */
+           throw new SaslException( "SASL session hijacked!" );
+       }
+        // Get the negotiated security layer, if any
+
+
+Expires 12/99                                                [Page 20]
+\f
+JAVA SASL API                                                June 1999
+
+        security = saslClnt.getSecurityLayer();
+
+   }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires 12/99                                                [Page 21]
+\f
+JAVA SASL API                                                June 1999
+
+   /****************************************************************
+    This might be in an application
+   ****************************************************************/
+
+   /**
+    * A sample callback handler. This implementation is created by
+    * using the input that it will return. Other implementations are
+    * typically more sophisticated and might prompt the user on demand
+    * in order to satisfy the callbacks.
+    */
+   class SimpleCallbackHandler implements CallbackHandler {
+       private char[] passwd;
+       private String authenticationID;
+
+       SimpleCallbackHandler(String principal, Object cred)
+                             throws IOException {
+           authenticationID = principal;
+
+           if (cred instanceof String) {
+               passwd = ((String)cred).toCharArray();
+           } else if (cred instanceof char[]) {
+               passwd = (char[])((char[])cred).clone();
+           } else if (cred instanceof byte[]) {
+               // PasswordCallback expects char[]; assume UTF-8
+               // encoding
+               String orig = new String((byte[])cred, "UTF8");
+               passwd = orig.toCharArray();
+           } else {
+               throw new IOException("Unsupported password format: " +
+                                     cred);
+           }
+       }
+
+       public void invokeCallback(Callback[] callbacks)
+           throws java.io.IOException, UnsupportedCallbackException {
+           for (int i = 0; i < callbacks.length; i++) {
+               if (callbacks[i] instanceof NameCallback) {
+                   ((NameCallback)callbacks[i]).setName(
+                                                     authenticationID);
+
+               } else if (callbacks[i] instanceof PasswordCallback) {
+                   ((PasswordCallback)callbacks[i]).setPassword(
+                                                               passwd);
+               } else {
+                   throw new
+                         UnsupportedCallbackException(callbacks[i]);
+               }
+           }
+       }
+   }
+
+
+
+
+
+
+Expires 12/99                                                [Page 22]
+\f
+JAVA SASL API                                                June 1999
+
+   /***************************************************************
+     And so the application code to do authentication
+   ***************************************************************/
+
+    // Set up all SASL parameters; some may have reasonable defaults
+    Hashtable props = new Hashtable();
+    props.add("javax.security.sasl.encryption.minimum", "40");
+    props.add("javax.security.sasl.encryption.maximum", "128");
+    props.add("javax.security.sasl.server_authentication", "true");
+    props.add("javax.security.sasl.maxbuffer", "4096");
+    // The following two for kerberos v4, only
+    //props.add("javax.security.sasl.ip.local", "192.68.1.10");
+    //props.add("javax.security.sasl.ip.remote", "192.68.1.50");
+
+    // What we want to authenticate as
+    String dn = "cn=Directory Manager";
+
+    // Create an object for possible use by the authentication
+    // process
+    SimpleCallbackHandler cbh = new SimpleCallbackHandler();
+
+    try {
+      // Note: cbh methods may be called during authentication
+      // Note: "connection" includes the SASL Protocol Driver
+      // functionality, and it will internally manage a Mechanism
+      // Driver for GSSAPI, and then a Security Layer object for
+      // data translation
+      String[] mechNames = { "GSSAPI" };
+      connection.authenticate( dn, mechNames, props, cbh );
+    } catch ( SaslException e ) {
+      // Abort, return, maybe try some other authentication
+    }
+
+    // Okay. From here on, everything goes through security, but the
+    // methods have the same signatures as if we were not using SASL
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires 12/99                                                [Page 23]
+\f
+JAVA SASL API                                                June 1999
+
+9     Appendix B - Changes from draft-weltman-java-sasl-01.txt
+
+   The class hierarchy defined in this document is entirely different
+   from that defined in the previous document.
+
+   For callback handling, the newly released
+   javax.security.auth.callback package is used.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires 12/99                                                [Page 24]
+\f
\ No newline at end of file
diff --git a/java/javax/Makefile.am b/java/javax/Makefile.am
new file mode 100644 (file)
index 0000000..f7f20eb
--- /dev/null
@@ -0,0 +1,42 @@
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+SUBDIRS = security
diff --git a/java/javax/Makefile.in b/java/javax/Makefile.in
new file mode 100644 (file)
index 0000000..11c2c27
--- /dev/null
@@ -0,0 +1,530 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+SUBDIRS = security
+subdir = java/javax
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+       ps-recursive install-info-recursive uninstall-info-recursive \
+       all-recursive install-data-recursive install-exec-recursive \
+       installdirs-recursive install-recursive uninstall-recursive \
+       check-recursive installcheck-recursive
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/javax/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if (etags --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+       else \
+         include_option=--include; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+       clean-generic clean-libtool clean-recursive ctags \
+       ctags-recursive distclean distclean-generic distclean-libtool \
+       distclean-recursive distclean-tags distdir dvi dvi-am \
+       dvi-recursive info info-am info-recursive install install-am \
+       install-data install-data-am install-data-recursive \
+       install-exec install-exec-am install-exec-recursive \
+       install-info install-info-am install-info-recursive install-man \
+       install-recursive install-strip installcheck installcheck-am \
+       installdirs installdirs-am installdirs-recursive \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
+       pdf-recursive ps ps-am ps-recursive tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am \
+       uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/javax/security/Makefile.am b/java/javax/security/Makefile.am
new file mode 100644 (file)
index 0000000..dff8b40
--- /dev/null
@@ -0,0 +1,42 @@
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+SUBDIRS = auth
diff --git a/java/javax/security/Makefile.in b/java/javax/security/Makefile.in
new file mode 100644 (file)
index 0000000..ce85792
--- /dev/null
@@ -0,0 +1,530 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+SUBDIRS = auth
+subdir = java/javax/security
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+       ps-recursive install-info-recursive uninstall-info-recursive \
+       all-recursive install-data-recursive install-exec-recursive \
+       installdirs-recursive install-recursive uninstall-recursive \
+       check-recursive installcheck-recursive
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/javax/security/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if (etags --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+       else \
+         include_option=--include; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+       clean-generic clean-libtool clean-recursive ctags \
+       ctags-recursive distclean distclean-generic distclean-libtool \
+       distclean-recursive distclean-tags distdir dvi dvi-am \
+       dvi-recursive info info-am info-recursive install install-am \
+       install-data install-data-am install-data-recursive \
+       install-exec install-exec-am install-exec-recursive \
+       install-info install-info-am install-info-recursive install-man \
+       install-recursive install-strip installcheck installcheck-am \
+       installdirs installdirs-am installdirs-recursive \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
+       pdf-recursive ps ps-am ps-recursive tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am \
+       uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/javax/security/auth/Makefile.am b/java/javax/security/auth/Makefile.am
new file mode 100644 (file)
index 0000000..c370505
--- /dev/null
@@ -0,0 +1,43 @@
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+SUBDIRS = callback
+
diff --git a/java/javax/security/auth/Makefile.in b/java/javax/security/auth/Makefile.in
new file mode 100644 (file)
index 0000000..7b2dd0a
--- /dev/null
@@ -0,0 +1,530 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+SUBDIRS = callback
+subdir = java/javax/security/auth
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
+       ps-recursive install-info-recursive uninstall-info-recursive \
+       all-recursive install-data-recursive install-exec-recursive \
+       installdirs-recursive install-recursive uninstall-recursive \
+       check-recursive installcheck-recursive
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+DIST_SUBDIRS = $(SUBDIRS)
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/javax/security/auth/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $$MAKEFLAGS; amf=$$2; \
+       dot_seen=no; \
+       case "$@" in \
+         distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+         *) list='$(SUBDIRS)' ;; \
+       esac; \
+       rev=''; for subdir in $$list; do \
+         if test "$$subdir" = "."; then :; else \
+           rev="$$subdir $$rev"; \
+         fi; \
+       done; \
+       rev="$$rev ."; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+ctags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       if (etags --etags-include --version) >/dev/null 2>&1; then \
+         include_option=--etags-include; \
+       else \
+         include_option=--include; \
+       fi; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && \
+             tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+         fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../../../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           (cd $$subdir && \
+             $(MAKE) $(AM_MAKEFLAGS) \
+               top_distdir="$(top_distdir)" \
+               distdir=../$(distdir)/$$subdir \
+               distdir) \
+             || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool \
+       distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
+       clean-generic clean-libtool clean-recursive ctags \
+       ctags-recursive distclean distclean-generic distclean-libtool \
+       distclean-recursive distclean-tags distdir dvi dvi-am \
+       dvi-recursive info info-am info-recursive install install-am \
+       install-data install-data-am install-data-recursive \
+       install-exec install-exec-am install-exec-recursive \
+       install-info install-info-am install-info-recursive install-man \
+       install-recursive install-strip installcheck installcheck-am \
+       installdirs installdirs-am installdirs-recursive \
+       maintainer-clean maintainer-clean-generic \
+       maintainer-clean-recursive mostlyclean mostlyclean-generic \
+       mostlyclean-libtool mostlyclean-recursive pdf pdf-am \
+       pdf-recursive ps ps-am ps-recursive tags tags-recursive \
+       uninstall uninstall-am uninstall-info-am \
+       uninstall-info-recursive uninstall-recursive
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/javax/security/auth/callback/Callback.java b/java/javax/security/auth/callback/Callback.java
new file mode 100644 (file)
index 0000000..2aec2a7
--- /dev/null
@@ -0,0 +1,13 @@
+
+package javax.security.auth.callback;
+
+/**
+All Known Implementing Classes:
+ConfirmationCallback, LanguageCallback, NameCallback, PasswordCallback,
+TextInputCallback, TextOutputCallback, ChoiceCallback
+*/
+
+public abstract interface Callback
+{
+    /* nothing. just use as a base */
+}
diff --git a/java/javax/security/auth/callback/CallbackHandler.java b/java/javax/security/auth/callback/CallbackHandler.java
new file mode 100644 (file)
index 0000000..3b3dc29
--- /dev/null
@@ -0,0 +1,8 @@
+
+package javax.security.auth.callback;
+
+public abstract interface CallbackHandler
+{
+    public void handle(Callback[] callbacks)
+       throws java.io.IOException, UnsupportedCallbackException;
+}
diff --git a/java/javax/security/auth/callback/Makefile.am b/java/javax/security/auth/callback/Makefile.am
new file mode 100644 (file)
index 0000000..e5be479
--- /dev/null
@@ -0,0 +1,55 @@
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+javasasldir = $(prefix)/lib/java/classes/sasl/javax/security/auth/callback
+javahtmldir = $(prefix)/html/sasl
+
+javasasl_JAVA = PasswordCallback.java \
+       Callback.java \
+       RealmCallback.java \
+       CallbackHandler.java \
+       UnsupportedCallbackException.java \
+       NameCallback.java
+EXTRA_DIST = $(javasasl_JAVA)
+
+CLASSES = $(javasasl_JAVA:.java=.class)
+
+$(CLASSES): callback.stamp
diff --git a/java/javax/security/auth/callback/Makefile.in b/java/javax/security/auth/callback/Makefile.in
new file mode 100644 (file)
index 0000000..6ffe198
--- /dev/null
@@ -0,0 +1,423 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../../../..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+javasasldir = $(prefix)/lib/java/classes/sasl/javax/security/auth/callback
+javahtmldir = $(prefix)/html/sasl
+
+javasasl_JAVA = PasswordCallback.java \
+       Callback.java \
+       RealmCallback.java \
+       CallbackHandler.java \
+       UnsupportedCallbackException.java \
+       NameCallback.java
+
+EXTRA_DIST = $(javasasl_JAVA)
+
+CLASSES = $(javasasl_JAVA:.java=.class)
+subdir = java/javax/security/auth/callback
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  java/javax/security/auth/callback/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+JAVACFLAGS =
+CLASSPATH_ENV = CLASSPATH=$(JAVAROOT):$(srcdir)/$(JAVAROOT):$$CLASSPATH
+
+classjavasasl.stamp: $(javasasl_JAVA)
+       @if test -n "$?"; then \
+         echo '$(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) $?' ; \
+         $(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) \
+           $(AM_JAVACFLAGS) $(JAVACFLAGS) $?; \
+       else :; fi
+       echo timestamp > classjavasasl.stamp
+install-javasaslJAVA: classjavasasl.stamp
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(javasasldir)
+       for p in *.class; do \
+         echo " $(INSTALL_DATA) $$p $(DESTDIR)$(javasasldir)/$$p"; \
+         $(INSTALL_DATA) $$p $(DESTDIR)$(javasasldir)/$$p; \
+       done
+
+uninstall-javasaslJAVA:
+       @$(NORMAL_UNINSTALL)
+       @for p in *.class; do \
+         echo " rm -f $(DESTDIR)$(javasasldir)/$$p"; \
+         rm -f $(DESTDIR)$(javasasldir)/$$p; \
+       done
+
+clean-javasaslJAVA:
+       -rm -f *.class classjavasasl.stamp
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ../../../../..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile classjavasasl.stamp
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(javasasldir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-javasaslJAVA clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-javasaslJAVA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-javasaslJAVA
+
+.PHONY: all all-am check check-am clean clean-generic clean-javasaslJAVA \
+       clean-libtool distclean distclean-generic distclean-libtool \
+       distdir dvi dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-javasaslJAVA install-man install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+       uninstall-info-am uninstall-javasaslJAVA
+
+
+$(CLASSES): callback.stamp
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/java/javax/security/auth/callback/NameCallback.java b/java/javax/security/auth/callback/NameCallback.java
new file mode 100644 (file)
index 0000000..6f149d8
--- /dev/null
@@ -0,0 +1,40 @@
+package javax.security.auth.callback;
+
+public class NameCallback implements Callback
+{
+    private String prompt;
+    private String defaultName;
+    private String name;
+
+    public NameCallback(String prompt)
+    {
+       this.prompt = prompt;
+    }
+
+    public NameCallback(String prompt, String defaultName) 
+    {
+       this.prompt = prompt;
+       this.defaultName = defaultName;
+    }
+
+    public String getDefaultName() 
+    {
+       return defaultName;
+    }
+    
+    public String getPrompt()
+    {
+       return prompt;
+    }
+    
+    public String getName()
+    {
+       return name;
+    }
+
+    public void setName(String name) 
+    {
+       this.name = name;
+    }
+}
+
diff --git a/java/javax/security/auth/callback/PasswordCallback.java b/java/javax/security/auth/callback/PasswordCallback.java
new file mode 100644 (file)
index 0000000..7353f0e
--- /dev/null
@@ -0,0 +1,34 @@
+package javax.security.auth.callback;
+
+public class PasswordCallback implements Callback
+{
+    private String prompt;
+    private boolean echoOn = false;
+    private String password;
+
+    public PasswordCallback(String prompt)
+    {
+       this.prompt = prompt;
+    }
+
+    public PasswordCallback(String prompt, boolean echoOn)
+    {
+       this.prompt = prompt;
+       this.echoOn = echoOn;
+    }
+    
+    public boolean isEchoOn()
+    {
+       return echoOn;
+    }
+    
+    public String getPassword()
+    {
+       return password;
+    }
+
+    public void setPassword(char[] password) 
+    {
+       this.password = new String(password);
+    }
+}
diff --git a/java/javax/security/auth/callback/RealmCallback.java b/java/javax/security/auth/callback/RealmCallback.java
new file mode 100644 (file)
index 0000000..4faa6cb
--- /dev/null
@@ -0,0 +1,40 @@
+package javax.security.auth.callback;
+
+public class RealmCallback implements Callback
+{
+    private String prompt;
+    private String defaultName;
+    private String name;
+
+    public RealmCallback(String prompt)
+    {
+       this.prompt = prompt;
+    }
+
+    public RealmCallback(String prompt, String defaultName) 
+    {
+       this.prompt = prompt;
+       this.defaultName = defaultName;
+    }
+
+    public String getDefaultRealm() 
+    {
+       return defaultName;
+    }
+    
+    public String getPrompt()
+    {
+       return prompt;
+    }
+    
+    public String getRealm()
+    {
+       return name;
+    }
+
+    public void setRealm(String name) 
+    {
+       this.name = name;
+    }
+}
+
diff --git a/java/javax/security/auth/callback/UnsupportedCallbackException.java b/java/javax/security/auth/callback/UnsupportedCallbackException.java
new file mode 100644 (file)
index 0000000..6b78f33
--- /dev/null
@@ -0,0 +1,25 @@
+package javax.security.auth.callback;
+
+
+public class UnsupportedCallbackException extends Exception
+{
+    Callback callback;
+
+    public UnsupportedCallbackException(Callback callback)
+    {
+       super();
+       this.callback = callback;
+    }
+
+    public UnsupportedCallbackException(Callback callback, String msg) 
+    {
+       super(msg);
+       this.callback = callback;
+    }
+
+    public Callback getCallback()
+    {
+       return callback;
+    }
+
+}
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644 (file)
index 0000000..894f131
--- /dev/null
@@ -0,0 +1,100 @@
+# Makefile.am for the SASL library
+# Rob Earhart
+# $Id: Makefile.am,v 1.85.2.1 2009/04/27 17:58:26 murch Exp $
+# Copyright (c) 2000 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.
+#
+
+# Library version info - here at the top, for sanity
+sasl_version = 2:23:0
+
+INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/plugins -I$(top_builddir)/include -I$(top_srcdir)/sasldb
+
+EXTRA_DIST = windlopen.c staticopen.h NTMakefile
+EXTRA_LIBRARIES = libsasl2.a
+noinst_LIBRARIES = @SASL_STATIC_LIBS@
+libsasl2_a_SOURCES=
+
+common_headers = saslint.h
+common_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c dlopen.c ../plugins/plugin_common.c
+
+LTLIBOBJS = @LTLIBOBJS@
+LIBOBJS = @LIBOBJS@
+LIB_DOOR= @LIB_DOOR@
+
+lib_LTLIBRARIES = libsasl2.la
+
+libsasl2_la_SOURCES = $(common_sources) $(common_headers)
+libsasl2_la_LDFLAGS = -version-info $(sasl_version)
+libsasl2_la_DEPENDENCIES = $(LTLIBOBJS)
+libsasl2_la_LIBADD = $(LTLIBOBJS) $(SASL_DL_LIB) $(LIB_SOCKET) $(LIB_DOOR)
+
+if MACOSX
+framedir = /Library/Frameworks/SASL2.framework
+install-exec-hook:
+       $(mkinstalldirs) $(framedir)/Versions/A
+       ln -fs $(libdir)/libsasl2.dylib $(framedir)/Versions/A/SASL2
+       cd $(framedir) ; ln -fs Versions/A/SASL2 .
+else
+install-exec-hook:
+endif
+
+libsasl2.a: libsasl2.la $(SASL_STATIC_OBJS)
+       @echo adding static plugins and dependencies
+       $(AR) cru .libs/$@ $(SASL_STATIC_OBJS)
+       @for i in ./libsasl2.la ../sasldb/libsasldb.la ../plugins/lib*.la; do \
+       if test ! -f $$i; then continue; fi; . $$i; \
+       for j in $$dependency_libs foo; do \
+       case $$j in foo) ;; \
+       -L*) for k in $$depdirs foo; do \
+           if test $$k = $$j; then break; fi; done; \
+         if test $$k = foo; then depdirs="$$depdirs $$j"; fi ;; \
+       -l*) for k in $$deplibs foo; do \
+           if test $$k = $$j; then break; fi; done; \
+         if test $$k = foo; then deplibs="$$deplibs $$j"; fi ;; \
+       esac; done; dependency_libs=""; done; \
+       sed -e "/^dependency_libs=/s%=.*%='$${depdirs}$${deplibs}'%" \
+       libsasl2.la >TMP.$$ && mv TMP.$$ libsasl2.la
+       rm -f $@
+       ln -s .libs/$@ $@
+
+$(SASL_STATIC_OBJS): linksrcs
+
+linksrcs:
+       -ln -s $(SASL_STATIC_SRCS) .
+
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644 (file)
index 0000000..453dc90
--- /dev/null
@@ -0,0 +1,655 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the SASL library
+# Rob Earhart
+# $Id: Makefile.am,v 1.85.2.1 2009/04/27 17:58:26 murch Exp $
+# Copyright (c) 2000 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.
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+# Library version info - here at the top, for sanity
+sasl_version = 2:23:0
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/plugins -I$(top_builddir)/include -I$(top_srcdir)/sasldb
+
+EXTRA_DIST = windlopen.c staticopen.h NTMakefile
+EXTRA_LIBRARIES = libsasl2.a
+noinst_LIBRARIES = @SASL_STATIC_LIBS@
+libsasl2_a_SOURCES = 
+
+common_headers = saslint.h
+common_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c dlopen.c ../plugins/plugin_common.c
+
+lib_LTLIBRARIES = libsasl2.la
+
+libsasl2_la_SOURCES = $(common_sources) $(common_headers)
+libsasl2_la_LDFLAGS = -version-info $(sasl_version)
+libsasl2_la_DEPENDENCIES = $(LTLIBOBJS)
+libsasl2_la_LIBADD = $(LTLIBOBJS) $(SASL_DL_LIB) $(LIB_SOCKET) $(LIB_DOOR)
+
+@MACOSX_TRUE@framedir = /Library/Frameworks/SASL2.framework
+subdir = lib
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libsasl2_a_AR = $(AR) cru
+libsasl2_a_LIBADD =
+am_libsasl2_a_OBJECTS =
+libsasl2_a_OBJECTS = $(am_libsasl2_a_OBJECTS)
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+am__objects_1 = auxprop.lo canonusr.lo checkpw.lo client.lo common.lo \
+       config.lo external.lo md5.lo saslutil.lo server.lo seterror.lo \
+       dlopen.lo plugin_common.lo
+am__objects_2 =
+am_libsasl2_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+libsasl2_la_OBJECTS = $(am_libsasl2_la_OBJECTS)
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/getaddrinfo.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/getnameinfo.Plo $(DEPDIR)/getsubopt.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/snprintf.Plo ./$(DEPDIR)/auxprop.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/canonusr.Plo ./$(DEPDIR)/checkpw.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/client.Plo ./$(DEPDIR)/common.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/config.Plo ./$(DEPDIR)/dlopen.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/external.Plo ./$(DEPDIR)/md5.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/plugin_common.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/saslutil.Plo ./$(DEPDIR)/server.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/seterror.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libsasl2_a_SOURCES) $(libsasl2_la_SOURCES)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am getaddrinfo.c \
+       getnameinfo.c getsubopt.c snprintf.c
+SOURCES = $(libsasl2_a_SOURCES) $(libsasl2_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  lib/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f="`echo $$p | sed -e 's|^.*/||'`"; \
+           echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+           $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+         else :; fi; \
+       done
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+         $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libsasl2.la: $(libsasl2_la_OBJECTS) $(libsasl2_la_DEPENDENCIES) 
+       $(LINK) -rpath $(libdir) $(libsasl2_la_LDFLAGS) $(libsasl2_la_OBJECTS) $(libsasl2_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getnameinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getsubopt.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/snprintf.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auxprop.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/canonusr.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/checkpw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/config.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dlopen.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/external.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saslutil.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seterror.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+plugin_common.o: ../plugins/plugin_common.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_common.o -MD -MP -MF "$(DEPDIR)/plugin_common.Tpo" \
+@am__fastdepCC_TRUE@     -c -o plugin_common.o `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/plugin_common.Tpo" "$(DEPDIR)/plugin_common.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/plugin_common.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../plugins/plugin_common.c' object='plugin_common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/plugin_common.Po' tmpdepfile='$(DEPDIR)/plugin_common.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_common.o `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c
+
+plugin_common.obj: ../plugins/plugin_common.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_common.obj -MD -MP -MF "$(DEPDIR)/plugin_common.Tpo" \
+@am__fastdepCC_TRUE@     -c -o plugin_common.obj `if test -f '../plugins/plugin_common.c'; then $(CYGPATH_W) '../plugins/plugin_common.c'; else $(CYGPATH_W) '$(srcdir)/../plugins/plugin_common.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/plugin_common.Tpo" "$(DEPDIR)/plugin_common.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/plugin_common.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../plugins/plugin_common.c' object='plugin_common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/plugin_common.Po' tmpdepfile='$(DEPDIR)/plugin_common.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_common.obj `if test -f '../plugins/plugin_common.c'; then $(CYGPATH_W) '../plugins/plugin_common.c'; else $(CYGPATH_W) '$(srcdir)/../plugins/plugin_common.c'; fi`
+
+plugin_common.lo: ../plugins/plugin_common.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT plugin_common.lo -MD -MP -MF "$(DEPDIR)/plugin_common.Tpo" \
+@am__fastdepCC_TRUE@     -c -o plugin_common.lo `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/plugin_common.Tpo" "$(DEPDIR)/plugin_common.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/plugin_common.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../plugins/plugin_common.c' object='plugin_common.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/plugin_common.Plo' tmpdepfile='$(DEPDIR)/plugin_common.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o plugin_common.lo `test -f '../plugins/plugin_common.c' || echo '$(srcdir)/'`../plugins/plugin_common.c
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+       clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf $(DEPDIR) ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-libLTLIBRARIES
+       @$(NORMAL_INSTALL)
+       $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf $(DEPDIR) ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES clean-libtool clean-noinstLIBRARIES ctags \
+       distclean distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am \
+       install-libLTLIBRARIES install-man install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-libLTLIBRARIES
+
+@MACOSX_TRUE@install-exec-hook:
+@MACOSX_TRUE@  $(mkinstalldirs) $(framedir)/Versions/A
+@MACOSX_TRUE@  ln -fs $(libdir)/libsasl2.dylib $(framedir)/Versions/A/SASL2
+@MACOSX_TRUE@  cd $(framedir) ; ln -fs Versions/A/SASL2 .
+@MACOSX_FALSE@install-exec-hook:
+
+libsasl2.a: libsasl2.la $(SASL_STATIC_OBJS)
+       @echo adding static plugins and dependencies
+       $(AR) cru .libs/$@ $(SASL_STATIC_OBJS)
+       @for i in ./libsasl2.la ../sasldb/libsasldb.la ../plugins/lib*.la; do \
+       if test ! -f $$i; then continue; fi; . $$i; \
+       for j in $$dependency_libs foo; do \
+       case $$j in foo) ;; \
+       -L*) for k in $$depdirs foo; do \
+           if test $$k = $$j; then break; fi; done; \
+         if test $$k = foo; then depdirs="$$depdirs $$j"; fi ;; \
+       -l*) for k in $$deplibs foo; do \
+           if test $$k = $$j; then break; fi; done; \
+         if test $$k = foo; then deplibs="$$deplibs $$j"; fi ;; \
+       esac; done; dependency_libs=""; done; \
+       sed -e "/^dependency_libs=/s%=.*%='$${depdirs}$${deplibs}'%" \
+       libsasl2.la >TMP.$$ && mv TMP.$$ libsasl2.la
+       rm -f $@
+       ln -s .libs/$@ $@
+
+$(SASL_STATIC_OBJS): linksrcs
+
+linksrcs:
+       -ln -s $(SASL_STATIC_SRCS) .
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/NTMakefile b/lib/NTMakefile
new file mode 100755 (executable)
index 0000000..220f80b
--- /dev/null
@@ -0,0 +1,120 @@
+!INCLUDE ..\win32\common.mak
+
+# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ...
+# emulation on Windows, so there is no need to build getaddrinfo.c
+
+!IF "$(VCVER)" == "6"
+compat_sources = getaddrinfo.c getnameinfo.c
+compat_objs = getaddrinfo.obj getnameinfo.obj
+!ENDIF
+
+
+libsasl_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c windlopen.c getsubopt.c plugin_common.c plugin_common.h $(compat_sources)
+libsasl_objs = auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj external.obj md5.obj saslutil.obj server.obj seterror.obj windlopen.obj getsubopt.obj plugin_common.obj $(compat_objs)
+libsasl_res = libsasl.res
+libsasl_out = libsasl.dll libsasl.exp libsasl.lib $(libsasl_res)
+
+CPPFLAGS = /D NEED_GETOPT /I "..\win32\include" /I "." /I "..\include" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSASL_EXPORTS"
+
+!IF $(TARGET_WIN_SYSTEM) >= 51
+CPPFLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(CPPFLAGS)
+!ENDIF 
+
+all_objs = $(libsasl_objs)
+all_out = $(libsasl_out)
+
+libdir = $(prefix)\lib
+bindir = $(prefix)\bin
+exclude_list = binexclude.lst
+
+all: all-recursive
+
+#
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
+#
+# In order to force xcopy not to confirm if the second parameter is file or directory,
+# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
+# instead of libsasl.lib. Ugly, but works!
+#
+install: libsasl.dll
+       @echo libsasl.exp > $(exclude_list)
+       @echo libsasl.lib >> $(exclude_list)
+       @echo libsasl.res >> $(exclude_list)
+       @xcopy libsasl.* $(bindir) /I /F /Y /EXCLUDE:$(exclude_list)
+       @xcopy libsasl.l* $(libdir) /I /F /Y
+
+all-recursive: libsasl.dll
+
+libsasl.dll: $(libsasl_objs) $(libsasl_res)
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"libsasl.dll" /implib:"libsasl.lib" /pdb:"libsasl.pdb" $(libsasl_objs) $(libsasl_res)
+<<
+
+plugin_common.c: ..\plugins\plugin_common.c plugin_common.h
+       copy ..\plugins\plugin_common.c .
+
+plugin_common.h: ..\plugins\plugin_common.h
+       copy ..\plugins\plugin_common.h .
+
+client.c common.c external.c plugin_common.c server.c seterror.c: ..\include\saslplug.h
+
+CLEAN :
+       -@erase $(all_objs)
+       -@erase "*.idb"
+       -@erase "*.pdb"
+       -@erase $(all_out)
+       -@erase plugin_common.h
+       -@erase plugin_common.c
+       -@erase $(exclude_list)
+
+$(libsasl_res): NTMakefile
+       rc /fo"$(libsasl_res)" <<
+#include "afxres.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
+ PRODUCTVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Carnegie Mellon University\0"
+            VALUE "FileDescription", "CMU SASL API v2\0"
+            VALUE "FileVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP).0\0"
+            VALUE "InternalName", "libsasl\0"
+            VALUE "LegalCopyright", "Copyright (c) Carnegie Mellon University 2005\0"
+            VALUE "OriginalFilename", "libsasl.dll\0"
+            VALUE "ProductName", "Carnegie Mellon University SASL\0"
+            VALUE "ProductVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP)-0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+<<
+
+.c.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
diff --git a/lib/auxprop.c b/lib/auxprop.c
new file mode 100644 (file)
index 0000000..a3f54c0
--- /dev/null
@@ -0,0 +1,1122 @@
+/* auxprop.c - auxilliary property support
+ * Rob Siemborski
+ * $Id: auxprop.c,v 1.16 2006/03/14 14:23:55 mel 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.
+ */
+
+#include <config.h>
+#include <sasl.h>
+#include <prop.h>
+#include <ctype.h>
+#include "saslint.h"
+
+struct proppool 
+{
+    struct proppool *next;
+
+    size_t size;          /* Size of Block */
+    size_t unused;        /* Space unused in this pool between end
+                          * of char** area and beginning of char* area */
+
+    char data[1];         /* Variable Sized */
+};
+
+struct propctx  {
+    struct propval *values;
+    struct propval *prev_val; /* Previous value used by set/setvalues */
+
+    unsigned used_values, allocated_values;
+
+    char *data_end; /* Bottom of string area in current pool */
+    char **list_end; /* Top of list area in current pool */
+
+    struct proppool *mem_base;
+    struct proppool *mem_cur;
+};
+
+typedef struct auxprop_plug_list 
+{
+    struct auxprop_plug_list *next;
+    const sasl_auxprop_plug_t *plug;
+} auxprop_plug_list_t;
+
+static auxprop_plug_list_t *auxprop_head = NULL;
+
+static struct proppool *alloc_proppool(size_t size) 
+{
+    struct proppool *ret;
+    /* minus 1 for the one that is already a part of the array
+     * in the struct */
+    size_t total_size = sizeof(struct proppool) + size - 1;
+    ret = sasl_ALLOC(total_size);
+    if(!ret) return NULL;
+
+    memset(ret, 0, total_size);
+
+    ret->size = ret->unused = size;
+
+    return ret;
+}
+
+/* Resize a proppool.  Invalidates the unused value for this pool */
+static struct proppool *resize_proppool(struct proppool *pool, size_t size)
+{
+    struct proppool *ret;
+    
+    if(pool->size >= size) return pool;
+    ret = sasl_REALLOC(pool, sizeof(struct proppool) + size);
+    if(!ret) return NULL;
+
+    ret->size = size;
+
+    return ret;
+}
+
+static int prop_init(struct propctx *ctx, unsigned estimate) 
+{
+    const unsigned VALUES_SIZE = PROP_DEFAULT * sizeof(struct propval);
+
+    ctx->mem_base = alloc_proppool(VALUES_SIZE + estimate);
+    if(!ctx->mem_base) return SASL_NOMEM;
+
+    ctx->mem_cur = ctx->mem_base;
+
+    ctx->values = (struct propval *)ctx->mem_base->data;
+    ctx->mem_base->unused = ctx->mem_base->size - VALUES_SIZE;
+    ctx->allocated_values = PROP_DEFAULT;
+    ctx->used_values = 0;
+
+    ctx->data_end = ctx->mem_base->data + ctx->mem_base->size;
+    ctx->list_end = (char **)(ctx->mem_base->data + VALUES_SIZE);
+
+    ctx->prev_val = NULL;
+
+    return SASL_OK;
+}
+
+/* create a property context
+ *  estimate -- an estimate of the storage needed for requests & responses
+ *              0 will use module default
+ * returns NULL on error
+ */
+struct propctx *prop_new(unsigned estimate) 
+{
+    struct propctx *new_ctx;
+
+    if(!estimate) estimate = PROP_DEFAULT * 255;
+
+    new_ctx = sasl_ALLOC(sizeof(struct propctx));
+    if(!new_ctx) return NULL;
+
+    if(prop_init(new_ctx, estimate) != SASL_OK) {
+       prop_dispose(&new_ctx);
+    }
+
+    return new_ctx;
+}
+
+/* create new propctx which duplicates the contents of an existing propctx
+ * returns -1 on error
+ */
+int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx) 
+{
+    struct proppool *pool;
+    struct propctx *retval = NULL;
+    unsigned i;
+    int result;
+    unsigned total_size = 0;
+    size_t values_size;
+    
+    if(!src_ctx || !dst_ctx) return SASL_BADPARAM;
+
+    /* What is the total allocated size of src_ctx? */
+    pool = src_ctx->mem_base;
+    while(pool) {
+       total_size += (unsigned) pool->size;
+       pool = pool->next;
+    }
+
+    /* allocate the new context */
+    retval = prop_new(total_size);
+    if(!retval) return SASL_NOMEM;
+
+    retval->used_values = src_ctx->used_values;
+    retval->allocated_values = src_ctx->used_values + 1;
+
+    values_size = (retval->allocated_values * sizeof(struct propval));
+
+    retval->mem_base->unused = retval->mem_base->size - values_size;
+
+    retval->list_end = (char **)(retval->mem_base->data + values_size);
+    /* data_end should still be OK */
+
+    /* Now dup the values */
+    for(i=0; i<src_ctx->used_values; i++) {
+       retval->values[i].name = src_ctx->values[i].name;
+       result = prop_setvals(retval, retval->values[i].name,
+                             src_ctx->values[i].values);
+       if(result != SASL_OK)
+           goto fail;
+    }
+
+    retval->prev_val = src_ctx->prev_val;
+
+    *dst_ctx = retval;
+    return SASL_OK;
+
+    fail:
+    if(retval) prop_dispose(&retval);
+    return result;
+}
+
+/*
+ * dispose of property context
+ *  ctx      -- is disposed and set to NULL; noop if ctx or *ctx is NULL
+ */
+void prop_dispose(struct propctx **ctx)
+{
+    struct proppool *tmp;
+    
+    if(!ctx || !*ctx) return;
+
+    while((*ctx)->mem_base) {
+       tmp = (*ctx)->mem_base;
+       (*ctx)->mem_base = tmp->next;
+       sasl_FREE(tmp);
+    }
+    
+    sasl_FREE(*ctx);
+    *ctx = NULL;
+
+    return;
+}
+
+/* Add property names to request
+ *  ctx       -- context from prop_new()
+ *  names     -- list of property names; must persist until context freed
+ *               or requests cleared
+ *
+ * NOTE: may clear values from context as side-effect
+ * returns -1 on error
+ */
+int prop_request(struct propctx *ctx, const char **names) 
+{
+    unsigned i, new_values, total_values;
+
+    if(!ctx || !names) return SASL_BADPARAM;
+
+    /* Count how many we need to add */
+    for(new_values=0; names[new_values]; new_values++);
+
+    /* Do we need to add ANY? */
+    if(!new_values) return SASL_OK;
+
+    /* We always want at least one extra to mark the end of the array */
+    total_values = new_values + ctx->used_values + 1;
+
+    /* Do we need to increase the size of our propval table? */
+    if(total_values > ctx->allocated_values) {
+       unsigned max_in_pool;
+
+       /* Do we need a larger base pool? */
+       max_in_pool = (unsigned) (ctx->mem_base->size / sizeof(struct propval));
+       
+       if(total_values <= max_in_pool) {
+           /* Don't increase the size of the base pool, just use what
+              we need */
+           ctx->allocated_values = total_values;
+           ctx->mem_base->unused =
+               ctx->mem_base->size - (sizeof(struct propval)
+                                      * ctx->allocated_values);
+       } else {
+           /* We need to allocate more! */
+           unsigned new_alloc_length;
+           size_t new_size;
+
+           new_alloc_length = 2 * ctx->allocated_values;
+           while(total_values > new_alloc_length) {
+               new_alloc_length *= 2;
+           }
+
+           new_size = new_alloc_length * sizeof(struct propval);
+           ctx->mem_base = resize_proppool(ctx->mem_base, new_size);
+
+           if(!ctx->mem_base) {
+               ctx->values = NULL;
+               ctx->allocated_values = ctx->used_values = 0;
+               return SASL_NOMEM;
+           }
+
+           /* It worked! Update the structure! */
+           ctx->values = (struct propval *)ctx->mem_base->data;
+           ctx->allocated_values = new_alloc_length;
+           ctx->mem_base->unused = ctx->mem_base->size
+               - sizeof(struct propval) * ctx->allocated_values;
+       }
+
+       /* Clear out new propvals */
+       memset(&(ctx->values[ctx->used_values]), 0,
+              sizeof(struct propval) * (ctx->allocated_values - ctx->used_values));
+
+        /* Finish updating the context -- we've extended the list! */
+       /* ctx->list_end = (char **)(ctx->values + ctx->allocated_values); */
+       /* xxx test here */
+       ctx->list_end = (char **)(ctx->values + total_values);
+    }
+
+    /* Now do the copy, or referencing rather */
+    for(i=0;i<new_values;i++) {
+       unsigned j, flag;
+
+       flag = 0;
+
+       /* Check for dups */
+       for(j=0;j<ctx->used_values;j++) {
+           if(!strcmp(ctx->values[j].name, names[i])) {
+               flag = 1;
+               break;
+           }
+       }
+
+       /* We already have it... skip! */
+       if(flag) continue;
+
+       ctx->values[ctx->used_values++].name = names[i];
+    }
+
+    prop_clear(ctx, 0);
+
+    return SASL_OK;
+}
+
+/* return array of struct propval from the context
+ *  return value persists until next call to
+ *   prop_request, prop_clear or prop_dispose on context
+ */
+const struct propval *prop_get(struct propctx *ctx) 
+{
+    if(!ctx) return NULL;
+    
+    return ctx->values;
+}
+
+/* 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 -1 on error (no properties ever requested, ctx NULL, etc)
+ *  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
+ */
+int prop_getnames(struct propctx *ctx, const char **names,
+                 struct propval *vals) 
+{
+    int found_names = 0;
+    
+    struct propval *cur = vals;
+    const char **curname;
+
+    if(!ctx || !names || !vals) return SASL_BADPARAM;
+    
+    for(curname = names; *curname; curname++) {
+       struct propval *val;
+       for(val = ctx->values; val->name; val++) {
+           if(!strcmp(*curname,val->name)) { 
+               found_names++;
+               memcpy(cur, val, sizeof(struct propval));
+               goto next;
+           }
+       }
+
+       /* If we are here, we didn't find it */
+       memset(cur, 0, sizeof(struct propval));
+       
+       next:
+       cur++;
+    }
+
+    return found_names;
+}
+
+
+/* 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) 
+{
+    struct proppool *new_pool, *tmp;
+    unsigned i;
+
+    /* We're going to need a new proppool once we reset things */
+    new_pool = alloc_proppool(ctx->mem_base->size +
+                             (ctx->used_values+1) * sizeof(struct propval));
+
+    if(requests) {
+       /* We're wiping the whole shebang */
+       ctx->used_values = 0;
+    } else {
+       /* Need to keep around old requets */
+       struct propval *new_values = (struct propval *)new_pool->data;
+       for(i=0; i<ctx->used_values; i++) {
+           new_values[i].name = ctx->values[i].name;
+       }
+    }
+
+    while(ctx->mem_base) {
+       tmp = ctx->mem_base;
+       ctx->mem_base = tmp->next;
+       sasl_FREE(tmp);
+    }
+    
+    /* Update allocation-related metadata */
+    ctx->allocated_values = ctx->used_values+1;
+    new_pool->unused =
+       new_pool->size - (ctx->allocated_values * sizeof(struct propval));
+
+    /* Setup pointers for the values array */
+    ctx->values = (struct propval *)new_pool->data;
+    ctx->prev_val = NULL;
+
+    /* Setup the pools */
+    ctx->mem_base = ctx->mem_cur = new_pool;
+
+    /* Reset list_end and data_end for the new memory pool */
+    ctx->list_end =
+       (char **)((char *)ctx->mem_base->data + ctx->allocated_values * sizeof(struct propval));
+    ctx->data_end = (char *)ctx->mem_base->data + ctx->mem_base->size;
+
+    return;
+}
+
+/*
+ * erase the value of a property
+ */
+void prop_erase(struct propctx *ctx, const char *name)
+{
+    struct propval *val;
+    int i;
+
+    if(!ctx || !name) return;
+
+    for(val = ctx->values; val->name; val++) {
+       if(!strcmp(name,val->name)) {
+           if(!val->values) break;
+
+           /*
+            * Yes, this is casting away the const, but
+            * we should be okay because the only place this
+            * memory should be is in the proppool's
+            */
+           for(i=0;val->values[i];i++) {
+               memset((void *)(val->values[i]),0,strlen(val->values[i]));
+               val->values[i] = NULL;
+           }
+
+           val->values = NULL;
+           val->nvalues = 0;
+           val->valsize = 0;
+           break;
+       }
+    }
+    
+    return;
+}
+
+/****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 0 on success and amount of additional space needed on failure
+ */
+int prop_format(struct propctx *ctx, const char *sep, int seplen,
+               char *outbuf, unsigned outmax, unsigned *outlen) 
+{
+    unsigned needed, flag = 0;
+    struct propval *val;
+    
+    if (!ctx || !outbuf) return SASL_BADPARAM;
+
+    if (!sep) seplen = 0;    
+    if (seplen < 0) seplen = (int) strlen(sep);
+/* If seplen is negative now we have overflow.
+   But if you have a string longer than 2Gb, you are an idiot anyway */
+    if (seplen < 0) return SASL_BADPARAM;
+
+    needed = seplen * (ctx->used_values - 1);
+    for(val = ctx->values; val->name; val++) {
+       needed += (unsigned) strlen(val->name);
+    }
+    
+    if(!outmax) return (needed + 1); /* Because of unsigned funkiness */
+    if(needed > (outmax - 1)) return (needed - (outmax - 1));
+
+    *outbuf = '\0';
+    if(outlen) *outlen = needed;
+
+    if(needed == 0) return SASL_OK;
+
+    for(val = ctx->values; val->name; val++) {
+       if(seplen && flag) {
+           strncat(outbuf, sep, seplen);
+       } else {
+           flag = 1;
+       }
+       strcat(outbuf, val->name);
+    }
+    
+    return SASL_OK;
+}
+
+/* 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
+ */
+int prop_set(struct propctx *ctx, const char *name,
+            const char *value, int vallen)
+{
+    struct propval *cur;
+
+    if(!ctx) return SASL_BADPARAM;
+    if(!name && !ctx->prev_val) return SASL_BADPARAM; 
+
+    if(name) {
+       struct propval *val;
+
+       ctx->prev_val = NULL;
+       
+       for(val = ctx->values; val->name; val++) {
+           if(!strcmp(name,val->name)){
+               ctx->prev_val = val;
+               break;
+           }
+       }
+
+       /* Couldn't find it! */
+       if(!ctx->prev_val) return SASL_BADPARAM;
+    }
+
+    cur = ctx->prev_val;
+
+    if(name) /* New Entry */ {
+       unsigned nvalues = 1; /* 1 for NULL entry */
+       const char **old_values = NULL;
+       char **tmp, **tmp2;
+       size_t size;
+       
+       if(cur->values) {
+
+           if(!value) {
+               /* If we would be adding a null value, then we are done */
+               return SASL_OK;
+           }
+
+           old_values = cur->values;
+           tmp = (char **)cur->values;
+           while(*tmp) {
+               nvalues++;
+               tmp++;
+           }
+
+       }
+
+       if(value) {
+           nvalues++; /* for the new value */
+       }
+
+       size = nvalues * sizeof(char*);
+
+       if(size > ctx->mem_cur->unused) {
+           size_t needed;
+
+           for(needed = ctx->mem_cur->size * 2; needed < size; needed *= 2);
+
+           /* Allocate a new proppool */
+           ctx->mem_cur->next = alloc_proppool(needed);
+           if(!ctx->mem_cur->next) return SASL_NOMEM;
+
+           ctx->mem_cur = ctx->mem_cur->next;
+
+           ctx->list_end = (char **)ctx->mem_cur->data;
+           ctx->data_end = ctx->mem_cur->data + needed;
+       }
+
+       /* Grab the memory */
+       ctx->mem_cur->unused -= size;
+       cur->values = (const char **)ctx->list_end;
+       cur->values[nvalues - 1] = NULL;
+
+       /* Finish updating the context */
+       ctx->list_end = (char **)(cur->values + nvalues);
+
+       /* If we don't have an actual value to fill in, we are done */
+       if(!value)
+           return SASL_OK;
+
+       tmp2 = (char **)cur->values;
+       if(old_values) {
+           tmp = (char **)old_values;
+           
+           while(*tmp) {
+               *tmp2 = *tmp;
+               tmp++; tmp2++;
+           }
+       }
+           
+       /* Now allocate the last entry */
+       if(vallen <= 0)
+           size = (size_t)(strlen(value) + 1);
+       else
+           size = (size_t)(vallen + 1);
+
+       if(size > ctx->mem_cur->unused) {
+           size_t needed;
+           
+           needed = ctx->mem_cur->size * 2;
+           
+           while(needed < size) {
+               needed *= 2;
+           }
+
+           /* Allocate a new proppool */
+           ctx->mem_cur->next = alloc_proppool(needed);
+           if(!ctx->mem_cur->next) return SASL_NOMEM;
+
+           ctx->mem_cur = ctx->mem_cur->next;
+           ctx->list_end = (char **)ctx->mem_cur->data;
+           ctx->data_end = ctx->mem_cur->data + needed;
+       }
+
+       /* Update the data_end pointer */
+       ctx->data_end -= size;
+       ctx->mem_cur->unused -= size;
+
+       /* Copy and setup the new value! */
+       memcpy(ctx->data_end, value, size-1);
+       ctx->data_end[size - 1] = '\0';
+       cur->values[nvalues - 2] = ctx->data_end;
+
+       cur->nvalues++;
+       cur->valsize += ((unsigned) size - 1);
+    } else /* Appending an entry */ {
+       char **tmp;
+       size_t size;
+
+       /* If we are setting it to be NULL, we are done */
+       if(!value) return SASL_OK;
+
+       size = sizeof(char*);
+
+       /* Is it in the current pool, and will it fit in the unused space? */
+       if(size > ctx->mem_cur->unused &&
+           (void *)cur->values > (void *)(ctx->mem_cur->data) &&
+           (void *)cur->values < (void *)(ctx->mem_cur->data + ctx->mem_cur->size)) {
+           /* recursively call the not-fast way */
+           return prop_set(ctx, cur->name, value, vallen);
+       }
+
+       /* Note the invariant: the previous value list must be
+          at the top of the CURRENT pool at this point */
+
+       /* Grab the memory */
+       ctx->mem_cur->unused -= size;
+       ctx->list_end++;
+
+       *(ctx->list_end - 1) = NULL;
+       tmp = (ctx->list_end - 2);
+
+       /* Now allocate the last entry */
+       if(vallen <= 0)
+           size = strlen(value) + 1;
+       else
+           size = vallen + 1;
+
+       if(size > ctx->mem_cur->unused) {
+           size_t needed;
+           
+           needed = ctx->mem_cur->size * 2;
+           
+           while(needed < size) {
+               needed *= 2;
+           }
+
+           /* Allocate a new proppool */
+           ctx->mem_cur->next = alloc_proppool(needed);
+           if(!ctx->mem_cur->next) return SASL_NOMEM;
+
+           ctx->mem_cur = ctx->mem_cur->next;
+           ctx->list_end = (char **)ctx->mem_cur->data;
+           ctx->data_end = ctx->mem_cur->data + needed;
+       }
+
+       /* Update the data_end pointer */
+       ctx->data_end -= size;
+       ctx->mem_cur->unused -= size;
+
+       /* Copy and setup the new value! */
+       memcpy(ctx->data_end, value, size-1);
+       ctx->data_end[size - 1] = '\0';
+       *tmp = ctx->data_end;
+
+       cur->nvalues++;
+       cur->valsize += ((unsigned) size - 1);
+    }
+    
+    return SASL_OK;
+}
+
+
+/* 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
+ */
+int prop_setvals(struct propctx *ctx, const char *name,
+                const char **values)
+{
+    const char **val = values;
+    int result = SASL_OK;
+
+    if(!ctx) return SASL_BADPARAM;
+
+    /* If they want us to add no values, we can do that */
+    if(!values) return SASL_OK;
+    
+    /* Basically, use prop_set to do all our dirty work for us */
+    if(name) {
+       result = prop_set(ctx, name, *val, 0);
+       val++;
+    }
+
+    for(;*val;val++) {
+       if(result != SASL_OK) return result;
+       result = prop_set(ctx, NULL, *val,0);
+    }
+
+    return result;
+}
+
+/* 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
+ */
+int sasl_auxprop_request(sasl_conn_t *conn, const char **propnames) 
+{
+    int result;
+    sasl_server_conn_t *sconn;
+
+    if(!conn) return SASL_BADPARAM;
+    if(conn->type != SASL_CONN_SERVER)
+       PARAMERROR(conn);
+    
+    sconn = (sasl_server_conn_t *)conn;
+
+    if(!propnames) {
+       prop_clear(sconn->sparams->propctx,1);
+       return SASL_OK;
+    }
+    
+    result = prop_request(sconn->sparams->propctx, propnames);
+    RETURN(conn, result);
+}
+
+
+/* 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.
+ */
+struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn) 
+{
+    sasl_server_conn_t *sconn;
+    
+    if(!conn || conn->type != SASL_CONN_SERVER) return NULL;
+
+    sconn = (sasl_server_conn_t *)conn;
+
+    return sconn->sparams->propctx;
+}
+
+/* add an auxiliary property plugin */
+int sasl_auxprop_add_plugin(const char *plugname,
+                           sasl_auxprop_init_t *auxpropfunc)
+{
+    int result, out_version;
+    auxprop_plug_list_t *new_item;
+    sasl_auxprop_plug_t *plug;
+    
+    result = auxpropfunc(sasl_global_utils, SASL_AUXPROP_PLUG_VERSION,
+                        &out_version, &plug, plugname);
+
+    if(result != SASL_OK) {
+       _sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n",
+                 sasl_errstring(result, NULL, NULL));
+       return result;
+    }
+
+    /* We require that this function is implemented */
+    if(!plug->auxprop_lookup) return SASL_BADPROT;
+
+    new_item = sasl_ALLOC(sizeof(auxprop_plug_list_t));
+    if(!new_item) return SASL_NOMEM;    
+
+    /* These will load from least-important to most important */
+    new_item->plug = plug;
+    new_item->next = auxprop_head;
+    auxprop_head = new_item;
+
+    return SASL_OK;
+}
+
+void _sasl_auxprop_free() 
+{
+    auxprop_plug_list_t *ptr, *ptr_next;
+    
+    for(ptr = auxprop_head; ptr; ptr = ptr_next) {
+       ptr_next = ptr->next;
+       if(ptr->plug->auxprop_free)
+           ptr->plug->auxprop_free(ptr->plug->glob_context,
+                                   sasl_global_utils);
+       sasl_FREE(ptr);
+    }
+
+    auxprop_head = NULL;
+}
+
+
+/* Do the callbacks for auxprop lookups */
+void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
+                         unsigned flags,
+                         const char *user, unsigned ulen) 
+{
+    sasl_getopt_t *getopt;
+    int ret, found = 0;
+    void *context;
+    const char *plist = NULL;
+    auxprop_plug_list_t *ptr;
+
+    if(_sasl_getcallback(sparams->utils->conn,
+                        SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
+       ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
+       if(ret != SASL_OK) plist = NULL;
+    }
+
+    if(!plist) {
+       /* Do lookup in all plugins */
+       for(ptr = auxprop_head; ptr; ptr = ptr->next) {
+           found=1;
+           ptr->plug->auxprop_lookup(ptr->plug->glob_context,
+                                     sparams, flags, user, ulen);
+       }
+    } else {
+       char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;
+
+       if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return;
+       thisplugin = freeptr = pluginlist;
+       
+       /* Do lookup in all *specified* plugins, in order */
+       while(*thisplugin) {
+           char *p;
+           int last=0;
+           
+           while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
+           if(!(*thisplugin)) break;
+           
+           for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
+           if(*p == '\0') last = 1;
+           else *p='\0';
+           
+           for(ptr = auxprop_head; ptr; ptr = ptr->next) {
+               /* Skip non-matching plugins */
+               if(!ptr->plug->name
+                  || strcasecmp(ptr->plug->name, thisplugin))
+                   continue;
+           
+               found=1;
+               ptr->plug->auxprop_lookup(ptr->plug->glob_context,
+                                         sparams, flags, user, ulen);
+           }
+
+           if(last) break;
+
+           thisplugin = p+1;
+       }
+
+       sasl_FREE(freeptr);
+    }
+
+    if(!found)
+       _sasl_log(sparams->utils->conn, SASL_LOG_DEBUG,
+                 "could not find auxprop plugin, was searching for '%s'",
+                 plist ? plist : "[all]");
+}
+
+/* Do the callbacks for auxprop stores */
+int sasl_auxprop_store(sasl_conn_t *conn,
+                      struct propctx *ctx, const char *user)
+{
+    sasl_getopt_t *getopt;
+    int ret, found = 0;
+    void *context;
+    const char *plist = NULL;
+    auxprop_plug_list_t *ptr;
+    sasl_server_params_t *sparams = NULL;
+    unsigned userlen = 0;
+
+    if (ctx) {
+       if (!conn || !user)
+           return SASL_BADPARAM;
+
+       sparams = ((sasl_server_conn_t *) conn)->sparams;
+       userlen = (unsigned) strlen(user);
+    }
+    
+    /* Pickup getopt callback from the connection, if conn is not NULL */
+    if(_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
+       ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
+       if(ret != SASL_OK) plist = NULL;
+    }
+
+    ret = SASL_OK;
+    if(!plist) {
+       /* Do store in all plugins */
+       for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
+           found=1;
+           if (ptr->plug->auxprop_store)
+               ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
+                                              sparams, ctx, user, userlen);
+       }
+    } else {
+       char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;
+
+       if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FAIL;
+       thisplugin = freeptr = pluginlist;
+       
+       /* Do store in all *specified* plugins, in order */
+       while(*thisplugin) {
+           char *p;
+           int last=0;
+           
+           while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
+           if(!(*thisplugin)) break;
+           
+           for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
+           if(*p == '\0') last = 1;
+           else *p='\0';
+           
+           for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
+               /* Skip non-matching plugins */
+               if((!ptr->plug->name
+                   || strcasecmp(ptr->plug->name, thisplugin)))
+                   continue;
+
+               found=1;
+               if (ptr->plug->auxprop_store)
+                   ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
+                                                  sparams, ctx, user, userlen);
+           }
+
+           if(last) break;
+
+           thisplugin = p+1;
+       }
+
+       sasl_FREE(freeptr);
+    }
+
+    if(!found) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "could not find auxprop plugin, was searching for %s",
+                 plist ? plist : "[all]");
+       return SASL_FAIL;
+    }
+
+    return ret;
+}
+
+/* It would be nice if we can show other information like Author, Company, Year, plugin version */
+static void
+_sasl_print_mechanism (
+  sasl_auxprop_plug_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char delimiter;
+
+    if (stage == SASL_INFO_LIST_START) {
+       printf ("List of auxprop plugins follows\n");
+       return;
+    } else if (stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    /* Process the mechanism */
+    printf ("Plugin \"%s\" ", m->name);
+
+#ifdef NOT_YET
+    switch (m->condition) {
+       case SASL_OK:
+           printf ("[loaded]");
+           break;
+
+       case SASL_CONTINUE:
+           printf ("[delayed]");
+           break;
+
+       case SASL_NOUSER:
+           printf ("[no users]");
+           break;
+
+       default:
+           printf ("[unknown]");
+           break;
+    }
+#endif
+
+    printf (", \tAPI version: %d\n", /* m->version */ SASL_AUXPROP_PLUG_VERSION);
+
+    /* TODO - Update for auxprop_export, etc. */
+    printf ("\tsupports store: %s\n",
+           (m->auxprop_store != NULL) ? "yes" : "no"
+           );
+
+    /* No features defined yet */
+#ifdef NOT_YET
+    printf ("\n\tfeatures:");
+#endif
+
+    printf ("\n");
+}
+
+/* Dump information about available auxprop plugins (separate functions are
+   used for canon and server authentication plugins) */
+int auxprop_plugin_info (
+  const char *c_mech_list,             /* space separated mechanism list or NULL for ALL */
+  auxprop_info_callback_t *info_cb,
+  void *info_cb_rock
+)
+{
+    auxprop_plug_list_t *m;
+    sasl_auxprop_plug_t plug_data;
+    char * cur_mech;
+    char *mech_list = NULL;
+    char * p;
+
+    if (info_cb == NULL) {
+       info_cb = _sasl_print_mechanism;
+    }
+
+    if (auxprop_head != NULL) {
+       info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock);
+
+       if (c_mech_list == NULL) {
+           m = auxprop_head; /* m point to beginning of the list */
+
+           while (m != NULL) {
+                /* TODO: Need to be careful when dealing with auxprop_export, etc. */
+               memcpy (&plug_data, m->plug, sizeof(plug_data));
+
+               info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+           
+               m = m->next;
+           }
+       } else {
+            mech_list = strdup(c_mech_list);
+
+           cur_mech = mech_list;
+
+           while (cur_mech != NULL) {
+               p = strchr (cur_mech, ' ');
+               if (p != NULL) {
+                   *p = '\0';
+                   p++;
+               }
+
+               m = auxprop_head; /* m point to beginning of the list */
+
+               while (m != NULL) {
+                   if (strcasecmp (cur_mech, m->plug->name) == 0) {
+                       memcpy (&plug_data, m->plug, sizeof(plug_data));
+
+                       info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+                   }
+           
+                   m = m->next;
+               }
+
+               cur_mech = p;
+           }
+
+            free (mech_list);
+       }
+
+       info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock);
+
+       return (SASL_OK);
+    }
+
+    return (SASL_NOTINIT);
+}
diff --git a/lib/canonusr.c b/lib/canonusr.c
new file mode 100644 (file)
index 0000000..bfffc7e
--- /dev/null
@@ -0,0 +1,376 @@
+/* canonusr.c - user canonicalization support
+ * Rob Siemborski
+ * $Id: canonusr.c,v 1.15 2004/02/20 23:54:51 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.
+ */
+
+#include <config.h>
+#include <sasl.h>
+#include <string.h>
+#include <ctype.h>
+#include <prop.h>
+#include <stdio.h>
+
+#include "saslint.h"
+
+typedef struct canonuser_plug_list 
+{
+    struct canonuser_plug_list *next;
+    char name[PATH_MAX];
+    const sasl_canonuser_plug_t *plug;
+} canonuser_plug_list_t;
+
+static canonuser_plug_list_t *canonuser_head = NULL;
+
+/* default behavior:
+ *                   eliminate leading & trailing whitespace,
+ *                   null-terminate, and get into the outparams
+ *
+ *                   (handled by INTERNAL plugin) */
+/* Also does auxprop lookups once username is canonicalized */
+/* a zero ulen or alen indicates that it is strlen(value) */
+int _sasl_canon_user(sasl_conn_t *conn,
+                     const char *user, unsigned ulen,
+                     unsigned flags,
+                     sasl_out_params_t *oparams)
+{
+    canonuser_plug_list_t *ptr;
+    sasl_server_conn_t *sconn = NULL;
+    sasl_client_conn_t *cconn = NULL;
+    sasl_canon_user_t *cuser_cb;
+    sasl_getopt_t *getopt;
+    void *context;
+    int result;
+    const char *plugin_name = NULL;
+    char *user_buf;
+    unsigned *lenp;
+
+    if(!conn) return SASL_BADPARAM;    
+    if(!user || !oparams) return SASL_BADPARAM;
+
+    if(flags & SASL_CU_AUTHID) {
+       user_buf = conn->authid_buf;
+       lenp = &(oparams->alen);
+    } else if (flags & SASL_CU_AUTHZID) {
+       user_buf = conn->user_buf;
+       lenp = &(oparams->ulen);
+    } else {
+       return SASL_BADPARAM;
+    }
+    
+    if(conn->type == SASL_CONN_SERVER) sconn = (sasl_server_conn_t *)conn;
+    else if(conn->type == SASL_CONN_CLIENT) cconn = (sasl_client_conn_t *)conn;
+    else return SASL_FAIL;
+    
+    if(!ulen) ulen = (unsigned int)strlen(user);
+    
+    /* check to see if we have a callback to make*/
+    result = _sasl_getcallback(conn, SASL_CB_CANON_USER,
+                              &cuser_cb, &context);
+    if(result == SASL_OK && cuser_cb) {
+       result = cuser_cb(conn, context,
+                       user, ulen,
+                       flags, (conn->type == SASL_CONN_SERVER ?
+                               ((sasl_server_conn_t *)conn)->user_realm :
+                               NULL),
+                       user_buf, CANON_BUF_SIZE, lenp);
+       
+
+       if (result != SASL_OK) return result;
+
+       /* Point the input copy at the stored buffer */
+       user = user_buf;
+       ulen = *lenp;
+    }
+
+    /* which plugin are we supposed to use? */
+    result = _sasl_getcallback(conn, SASL_CB_GETOPT,
+                              &getopt, &context);
+    if(result == SASL_OK && getopt) {
+       getopt(context, NULL, "canon_user_plugin", &plugin_name, NULL);
+    }
+
+    if(!plugin_name) {
+       /* Use Defualt */
+       plugin_name = "INTERNAL";
+    }
+    
+    for(ptr = canonuser_head; ptr; ptr = ptr->next) {
+       /* A match is if we match the internal name of the plugin, or if
+        * we match the filename (old-style) */
+       if((ptr->plug->name && !strcmp(plugin_name, ptr->plug->name))
+          || !strcmp(plugin_name, ptr->name)) break;
+    }
+
+    /* We clearly don't have this one! */
+    if(!ptr) {
+       sasl_seterror(conn, 0, "desired canon_user plugin %s not found",
+                     plugin_name);
+       return SASL_NOMECH;
+    }
+    
+    if(sconn) {
+       /* we're a server */
+       result = ptr->plug->canon_user_server(ptr->plug->glob_context,
+                                             sconn->sparams,
+                                             user, ulen,
+                                             flags,
+                                             user_buf,
+                                             CANON_BUF_SIZE, lenp);
+    } else {
+       /* we're a client */
+       result = ptr->plug->canon_user_client(ptr->plug->glob_context,
+                                             cconn->cparams,
+                                             user, ulen,
+                                             flags,
+                                             user_buf,
+                                             CANON_BUF_SIZE, lenp);
+    }
+
+    if(result != SASL_OK) return result;
+
+    if((flags & SASL_CU_AUTHID) && (flags & SASL_CU_AUTHZID)) {
+       /* We did both, so we need to copy the result into
+        * the buffer for the authzid from the buffer for the authid */
+       memcpy(conn->user_buf, conn->authid_buf, CANON_BUF_SIZE);
+       oparams->ulen = oparams->alen;
+    }
+       
+    /* Set the appropriate oparams (lengths have already been set by lenp) */
+    if(flags & SASL_CU_AUTHID) {
+       oparams->authid = conn->authid_buf;
+    }
+
+    if (flags & SASL_CU_AUTHZID) {
+       oparams->user = conn->user_buf;
+    }
+
+#ifndef macintosh
+    /* do auxprop lookups (server only) */
+    if(sconn) {
+       if(flags & SASL_CU_AUTHID) {
+           _sasl_auxprop_lookup(sconn->sparams, 0,
+                                oparams->authid, oparams->alen);
+       }
+       if(flags & SASL_CU_AUTHZID) {
+           _sasl_auxprop_lookup(sconn->sparams, SASL_AUXPROP_AUTHZID,
+                                oparams->user, oparams->ulen);
+       }
+    }
+#endif
+
+
+    RETURN(conn, SASL_OK);
+}
+
+void _sasl_canonuser_free() 
+{
+    canonuser_plug_list_t *ptr, *ptr_next;
+    
+    for(ptr = canonuser_head; ptr; ptr = ptr_next) {
+       ptr_next = ptr->next;
+       if(ptr->plug->canon_user_free)
+           ptr->plug->canon_user_free(ptr->plug->glob_context,
+                                      sasl_global_utils);
+       sasl_FREE(ptr);
+    }
+
+    canonuser_head = NULL;
+}
+
+int sasl_canonuser_add_plugin(const char *plugname,
+                             sasl_canonuser_init_t *canonuserfunc) 
+{
+    int result, out_version;
+    canonuser_plug_list_t *new_item;
+    sasl_canonuser_plug_t *plug;
+
+    if(!plugname || strlen(plugname) > (PATH_MAX - 1)) {
+       sasl_seterror(NULL, 0,
+                     "bad plugname passed to sasl_canonuser_add_plugin\n");
+       return SASL_BADPARAM;
+    }
+    
+    result = canonuserfunc(sasl_global_utils, SASL_CANONUSER_PLUG_VERSION,
+                          &out_version, &plug, plugname);
+
+    if(result != SASL_OK) {
+       _sasl_log(NULL, SASL_LOG_ERR, "canonuserfunc error %i\n",result);
+       return result;
+    }
+
+    if(!plug->canon_user_server && !plug->canon_user_client) {
+       /* We need at least one of these implemented */
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "canonuser plugin without either client or server side");
+       return SASL_BADPROT;
+    }
+    
+    new_item = sasl_ALLOC(sizeof(canonuser_plug_list_t));
+    if(!new_item) return SASL_NOMEM;
+
+    strncpy(new_item->name, plugname, PATH_MAX);
+
+    new_item->plug = plug;
+    new_item->next = canonuser_head;
+    canonuser_head = new_item;
+
+    return SASL_OK;
+}
+
+#ifdef MIN
+#undef MIN
+#endif
+#define MIN(a,b) (((a) < (b))? (a):(b))
+
+static int _canonuser_internal(const sasl_utils_t *utils,
+                              const char *user, unsigned ulen,
+                              unsigned flags __attribute__((unused)),
+                              char *out_user,
+                              unsigned out_umax, unsigned *out_ulen) 
+{
+    unsigned i;
+    char *in_buf, *userin;
+    const char *begin_u;
+    size_t u_apprealm = 0;
+    sasl_server_conn_t *sconn = NULL;
+
+    if(!utils || !user) return SASL_BADPARAM;
+
+    in_buf = sasl_ALLOC((ulen + 2) * sizeof(char));
+    if(!in_buf) return SASL_NOMEM;
+
+    userin = in_buf;
+
+    memcpy(userin, user, ulen);
+    userin[ulen] = '\0';
+    
+    /* Strip User ID */
+    for(i=0;isspace((int)userin[i]) && i<ulen;i++);
+    begin_u = &(userin[i]);
+    if(i>0) ulen -= i;
+
+    for(;ulen > 0 && isspace((int)begin_u[ulen-1]); ulen--);
+    if(begin_u == &(userin[ulen])) {
+       sasl_FREE(in_buf);
+       utils->seterror(utils->conn, 0, "All-whitespace username.");
+       return SASL_FAIL;
+    }
+
+    if(utils->conn && utils->conn->type == SASL_CONN_SERVER)
+       sconn = (sasl_server_conn_t *)utils->conn;
+
+    /* Need to append realm if necessary (see sasl.h) */
+    if(sconn && sconn->user_realm && !strchr(user, '@')) {
+       u_apprealm = strlen(sconn->user_realm) + 1;
+    }
+    
+    /* Now Copy */
+    memcpy(out_user, begin_u, MIN(ulen, out_umax));
+    if(sconn && u_apprealm) {
+       if(ulen >= out_umax) return SASL_BUFOVER;
+       out_user[ulen] = '@';
+       memcpy(&(out_user[ulen+1]), sconn->user_realm,
+              MIN(u_apprealm-1, out_umax-ulen-1));
+    }
+    out_user[MIN(ulen + u_apprealm,out_umax)] = '\0';
+
+    if(ulen + u_apprealm > out_umax) return SASL_BUFOVER;
+
+    if(out_ulen) *out_ulen = MIN(ulen + u_apprealm,out_umax);
+    
+    sasl_FREE(in_buf);
+    return SASL_OK;
+}
+
+static int _cu_internal_server(void *glob_context __attribute__((unused)),
+                              sasl_server_params_t *sparams,
+                              const char *user, unsigned ulen,
+                              unsigned flags,
+                              char *out_user,
+                              unsigned out_umax, unsigned *out_ulen) 
+{
+    return _canonuser_internal(sparams->utils,
+                              user, ulen,
+                              flags, out_user, out_umax, out_ulen);
+}
+
+static int _cu_internal_client(void *glob_context __attribute__((unused)),
+                              sasl_client_params_t *cparams,
+                              const char *user, unsigned ulen,
+                              unsigned flags,
+                              char *out_user,
+                              unsigned out_umax, unsigned *out_ulen) 
+{
+    return _canonuser_internal(cparams->utils,
+                              user, ulen,
+                              flags, out_user, out_umax, out_ulen);
+}
+
+static sasl_canonuser_plug_t canonuser_internal_plugin = {
+        0, /* features */
+       0, /* spare */
+       NULL, /* glob_context */
+       "INTERNAL", /* name */
+       NULL, /* canon_user_free */
+       _cu_internal_server,
+       _cu_internal_client,
+       NULL,
+       NULL,
+       NULL
+};
+
+int internal_canonuser_init(const sasl_utils_t *utils __attribute__((unused)),
+                            int max_version,
+                            int *out_version,
+                            sasl_canonuser_plug_t **plug,
+                            const char *plugname __attribute__((unused))) 
+{
+    if(!out_version || !plug) return SASL_BADPARAM;
+
+    if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS;
+    
+    *out_version = SASL_CANONUSER_PLUG_VERSION;
+
+    *plug = &canonuser_internal_plugin;
+
+    return SASL_OK;
+}
diff --git a/lib/checkpw.c b/lib/checkpw.c
new file mode 100644 (file)
index 0000000..c27cac6
--- /dev/null
@@ -0,0 +1,977 @@
+/* SASL server API implementation
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: checkpw.c,v 1.73 2006/03/13 18:30:41 mel 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.
+ */
+
+#include <config.h>
+
+/* checkpw stuff */
+
+#include <stdio.h>
+#include "sasl.h"
+#include "saslutil.h"
+#include "saslplug.h"
+#include "saslint.h"
+
+#include <assert.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#ifdef USE_DOORS
+#include <sys/mman.h>
+#include <door.h>
+#endif
+
+#include <stdlib.h>
+
+#ifndef WIN32
+#include <strings.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+#else
+#include <string.h>
+#endif
+
+#include <sys/types.h>
+#include <ctype.h>
+
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif /* HAVE_PWD_H */
+#ifdef HAVE_SHADOW_H
+#include <shadow.h>
+#endif /* HAVE_SHADOW_H */
+
+#if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON)
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <sys/un.h>
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+#endif
+
+
+/* we store the following secret to check plaintext passwords:
+ *
+ * <salt> \0 <secret>
+ *
+ * where <secret> = MD5(<salt>, "sasldb", <pass>)
+ */
+static int _sasl_make_plain_secret(const char *salt, 
+                                  const char *passwd, size_t passlen,
+                                  sasl_secret_t **secret)
+{
+    MD5_CTX ctx;
+    unsigned sec_len = 16 + 1 + 16; /* salt + "\0" + hash */
+
+    *secret = (sasl_secret_t *) sasl_ALLOC(sizeof(sasl_secret_t) +
+                                          sec_len * sizeof(char));
+    if (*secret == NULL) {
+       return SASL_NOMEM;
+    }
+
+    _sasl_MD5Init(&ctx);
+    _sasl_MD5Update(&ctx, salt, 16);
+    _sasl_MD5Update(&ctx, "sasldb", 6);
+    _sasl_MD5Update(&ctx, passwd, (unsigned int) passlen);
+    memcpy((*secret)->data, salt, 16);
+    (*secret)->data[16] = '\0';
+    _sasl_MD5Final((*secret)->data + 17, &ctx);
+    (*secret)->len = sec_len;
+    
+    return SASL_OK;
+}
+
+/* erase & dispose of a sasl_secret_t
+ */
+static int auxprop_verify_password(sasl_conn_t *conn,
+                                  const char *userstr,
+                                  const char *passwd,
+                                  const char *service __attribute__((unused)),
+                                  const char *user_realm __attribute__((unused)))
+{
+    int ret = SASL_FAIL;
+    char *userid = NULL;
+    char *realm = NULL;
+    int result = SASL_OK;
+    sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn;
+    const char *password_request[] = { SASL_AUX_PASSWORD,
+                                      "*cmusaslsecretPLAIN",
+                                      NULL };
+    struct propval auxprop_values[3];
+    
+    if (!conn || !userstr)
+       return SASL_BADPARAM;
+
+    /* We need to clear any previous results and re-canonify to 
+     * ensure correctness */
+
+    prop_clear(sconn->sparams->propctx, 0);
+       
+    /* ensure its requested */
+    result = prop_request(sconn->sparams->propctx, password_request);
+
+    if(result != SASL_OK) return result;
+
+    result = _sasl_canon_user(conn, userstr, 0,
+                             SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                             &(conn->oparams));
+    if(result != SASL_OK) return result;
+    
+    result = prop_getnames(sconn->sparams->propctx, password_request,
+                          auxprop_values);
+    if(result < 0)
+       return result;
+
+    if((!auxprop_values[0].name
+         || !auxprop_values[0].values || !auxprop_values[0].values[0])
+       && (!auxprop_values[1].name
+         || !auxprop_values[1].values || !auxprop_values[1].values[0]))
+           return SASL_NOUSER;
+        
+    /* It is possible for us to get useful information out of just
+     * the lookup, so we won't check that we have a password until now */
+    if(!passwd) {
+       ret = SASL_BADPARAM;
+       goto done;
+    }
+
+    /* At the point this has been called, the username has been canonified
+     * and we've done the auxprop lookup.  This should be easy. */
+    if(auxprop_values[0].name
+       && auxprop_values[0].values
+       && auxprop_values[0].values[0]
+       && !strcmp(auxprop_values[0].values[0], passwd)) {
+       /* We have a plaintext version and it matched! */
+       return SASL_OK;
+    } else if(auxprop_values[1].name
+             && auxprop_values[1].values
+             && auxprop_values[1].values[0]) {
+       const char *db_secret = auxprop_values[1].values[0];
+       sasl_secret_t *construct;
+       
+       ret = _sasl_make_plain_secret(db_secret, passwd,
+                                     strlen(passwd),
+                                     &construct);
+       if (ret != SASL_OK) {
+           goto done;
+       }
+
+       if (!memcmp(db_secret, construct->data, construct->len)) {
+           /* password verified! */
+           ret = SASL_OK;
+       } else {
+           /* passwords do not match */
+           ret = SASL_BADAUTH;
+       }
+
+       sasl_FREE(construct);
+    } else {
+       /* passwords do not match */
+       ret = SASL_BADAUTH;
+    }
+
+    /* erase the plaintext password */
+    sconn->sparams->utils->prop_erase(sconn->sparams->propctx,
+                                     password_request[0]);
+
+ done:
+    if (userid) sasl_FREE(userid);
+    if (realm)  sasl_FREE(realm);
+
+    /* We're not going to erase the property here because other people
+     * may want it */
+    return ret;
+}
+
+#ifdef DO_SASL_CHECKAPOP
+int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
+                             const char *userstr,
+                             const char *challenge,
+                             const char *response,
+                             const char *user_realm __attribute__((unused)))
+{
+    int ret = SASL_BADAUTH;
+    char *userid = NULL;
+    char *realm = NULL;
+    unsigned char digest[16];
+    char digeststr[33];
+    const char *password_request[] = { SASL_AUX_PASSWORD, NULL };
+    struct propval auxprop_values[2];
+    sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn;
+    MD5_CTX ctx;
+    int i;
+
+    if (!conn || !userstr || !challenge || !response)
+       PARAMERROR(conn)
+
+    /* We've done the auxprop lookup already (in our caller) */
+    /* sadly, APOP has no provision for storing secrets */
+    ret = prop_getnames(sconn->sparams->propctx, password_request,
+                       auxprop_values);
+    if(ret < 0) {
+       sasl_seterror(conn, 0, "could not perform password lookup");
+       goto done;
+    }
+    
+    if(!auxprop_values[0].name ||
+       !auxprop_values[0].values ||
+       !auxprop_values[0].values[0]) {
+       sasl_seterror(conn, 0, "could not find password");
+       ret = SASL_NOUSER;
+       goto done;
+    }
+    
+    _sasl_MD5Init(&ctx);
+    _sasl_MD5Update(&ctx, challenge, strlen(challenge));
+    _sasl_MD5Update(&ctx, auxprop_values[0].values[0],
+                   strlen(auxprop_values[0].values[0]));
+    _sasl_MD5Final(digest, &ctx);
+
+    /* erase the plaintext password */
+    sconn->sparams->utils->prop_erase(sconn->sparams->propctx,
+                                     password_request[0]);
+
+    /* convert digest from binary to ASCII hex */
+    for (i = 0; i < 16; i++)
+      sprintf(digeststr + (i*2), "%02x", digest[i]);
+
+    if (!strncasecmp(digeststr, response, 32)) {
+      /* password verified! */
+      ret = SASL_OK;
+    } else {
+      /* passwords do not match */
+      ret = SASL_BADAUTH;
+    }
+
+ done:
+    if (ret == SASL_BADAUTH) sasl_seterror(conn, SASL_NOLOG,
+                                          "login incorrect");
+    if (userid) sasl_FREE(userid);
+    if (realm)  sasl_FREE(realm);
+
+    return ret;
+}
+#endif /* DO_SASL_CHECKAPOP */
+
+#if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON)
+/*
+ * Wait for file descriptor to be writable. Return with error if timeout.
+ */
+static int write_wait(int fd, unsigned delta)
+{
+    fd_set wfds;
+    fd_set efds;
+    struct timeval tv;
+
+    /* 
+     * Wait for file descriptor fd to be writable. Retry on
+     * interruptions. Return with error upon timeout.
+     */
+    while (1) {
+       FD_ZERO(&wfds);
+       FD_ZERO(&efds);
+       FD_SET(fd, &wfds);
+       FD_SET(fd, &efds);
+       tv.tv_sec = (long) delta;
+       tv.tv_usec = 0;
+       switch(select(fd + 1, 0, &wfds, &efds, &tv)) {
+       case 0:
+           /* Timeout. */
+           errno = ETIMEDOUT;
+           return -1;
+       case +1:
+           if (FD_ISSET(fd, &wfds)) {
+               /* Success, file descriptor is writable. */
+               return 0;
+           }
+           return -1;
+       case -1:
+           if (errno == EINTR || errno == EAGAIN)
+               continue;
+       default:
+           /* Error catch-all. */
+           return -1;
+       }
+    }
+    /* Not reached. */
+    return -1;
+}
+
+/*
+ * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt'
+ * until all the data is written out or an error/timeout occurs.
+ */
+static int retry_writev(int fd, struct iovec *iov, int iovcnt, unsigned delta)
+{
+    int n;
+    int i;
+    int written = 0;
+    static int iov_max =
+#ifdef MAXIOV
+       MAXIOV
+#else
+#ifdef IOV_MAX
+       IOV_MAX
+#else
+       8192
+#endif
+#endif
+       ;
+    
+    for (;;) {
+       while (iovcnt && iov[0].iov_len == 0) {
+           iov++;
+           iovcnt--;
+       }
+
+       if (!iovcnt) return written;
+
+       if (delta > 0) {
+           if (write_wait(fd, delta))
+               return -1;
+       }
+       n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
+       if (n == -1) {
+           if (errno == EINVAL && iov_max > 10) {
+               iov_max /= 2;
+               continue;
+           }
+           if (errno == EINTR) continue;
+           return -1;
+       }
+
+       written += n;
+
+       for (i = 0; i < iovcnt; i++) {
+           if ((int) iov[i].iov_len > n) {
+               iov[i].iov_base = (char *)iov[i].iov_base + n;
+               iov[i].iov_len -= n;
+               break;
+           }
+           n -= iov[i].iov_len;
+           iov[i].iov_len = 0;
+       }
+
+       if (i == iovcnt) return written;
+    }
+}
+
+#endif
+
+#ifdef HAVE_PWCHECK
+/* pwcheck daemon-authenticated login */
+static int pwcheck_verify_password(sasl_conn_t *conn,
+                                  const char *userid, 
+                                  const char *passwd,
+                                  const char *service __attribute__((unused)),
+                                  const char *user_realm 
+                                              __attribute__((unused)))
+{
+    int s;
+    struct sockaddr_un srvaddr;
+    int r;
+    struct iovec iov[10];
+    static char response[1024];
+    unsigned start, n;
+    char pwpath[1024];
+
+    if (strlen(PWCHECKDIR)+8+1 > sizeof(pwpath)) return SASL_FAIL;
+
+    strcpy(pwpath, PWCHECKDIR);
+    strcat(pwpath, "/pwcheck");
+
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s == -1) return errno;
+
+    memset((char *)&srvaddr, 0, sizeof(srvaddr));
+    srvaddr.sun_family = AF_UNIX;
+    strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path));
+    r = connect(s, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
+    if (r == -1) {
+       sasl_seterror(conn,0,"cannot connect to pwcheck server");
+       return SASL_FAIL;
+    }
+
+    iov[0].iov_base = (char *)userid;
+    iov[0].iov_len = strlen(userid)+1;
+    iov[1].iov_base = (char *)passwd;
+    iov[1].iov_len = strlen(passwd)+1;
+
+    retry_writev(s, iov, 2, 0);
+
+    start = 0;
+    while (start < sizeof(response) - 1) {
+       n = read(s, response+start, sizeof(response) - 1 - start);
+       if (n < 1) break;
+       start += n;
+    }
+
+    close(s);
+
+    if (start > 1 && !strncmp(response, "OK", 2)) {
+       return SASL_OK;
+    }
+
+    response[start] = '\0';
+    sasl_seterror(conn,0,response);
+    return SASL_BADAUTH;
+}
+
+#endif
+
+#if defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON)
+static int read_wait(int fd, unsigned delta)
+{
+    fd_set rfds;
+    fd_set efds;
+    struct timeval tv;
+    /* 
+     * Wait for file descriptor fd to be readable. Retry on 
+     * interruptions. Return with error upon timeout.
+     */
+    while (1) {
+       FD_ZERO(&rfds);
+       FD_ZERO(&efds);
+       FD_SET(fd, &rfds);
+       FD_SET(fd, &efds);
+       tv.tv_sec = (long) delta;
+       tv.tv_usec = 0;
+       switch(select(fd + 1, &rfds, 0, &efds, &tv)) {
+       case 0:
+           /* Timeout. */
+           errno = ETIMEDOUT;
+           return -1;
+       case +1:
+           if (FD_ISSET(fd, &rfds)) {
+               /* Success, file descriptor is readable. */
+               return 0;
+           }
+           return -1;
+       case -1:
+           if (errno == EINTR || errno == EAGAIN)
+               continue;
+       default:
+           /* Error catch-all. */
+           return -1;
+       }
+    }
+    /* Not reached. */
+    return -1;
+}
+
+/*
+ * Keep calling the read() system call until all the data is read in, 
+ * timeout, EOF, or an error occurs. This function returns the number 
+ * of useful bytes, or -1 if timeout/error.
+ */
+static int retry_read(int fd, void *buf0, unsigned nbyte, unsigned delta)
+{
+    int nr;
+    unsigned nleft = nbyte;
+    char *buf = (char*) buf0;
+    
+    while (nleft >= 1) {
+       if (delta > 0) {
+           if (read_wait(fd, delta))
+               return -1;
+       }
+       nr = read(fd, buf, nleft);
+       if (nr < 0) {
+           if (errno == EINTR || errno == EAGAIN)
+               continue;
+           return -1;
+       } else if (nr == 0) {
+           break;
+       }
+      buf += nr;
+      nleft -= nr;
+    }
+    return nbyte - nleft;
+}
+#endif
+
+#ifdef HAVE_SASLAUTHD
+/* saslauthd-authenticated login */
+static int saslauthd_verify_password(sasl_conn_t *conn,
+                                    const char *userid, 
+                                    const char *passwd,
+                                    const char *service,
+                                    const char *user_realm)
+{
+    char response[1024];
+    char query[8192];
+    char *query_end = query;
+    int s;
+    struct sockaddr_un srvaddr;
+    sasl_getopt_t *getopt;
+    void *context;
+    char pwpath[sizeof(srvaddr.sun_path)];
+    const char *p = NULL;
+    char *freeme = NULL;
+#ifdef USE_DOORS
+    door_arg_t arg;
+#endif
+
+    /* check to see if the user configured a rundir */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
+       getopt(context, NULL, "saslauthd_path", &p, NULL);
+    }
+    if (p) {
+       strncpy(pwpath, p, sizeof(pwpath));
+    } else {
+       if (strlen(PATH_SASLAUTHD_RUNDIR) + 4 + 1 > sizeof(pwpath))
+           return SASL_FAIL;
+
+       strcpy(pwpath, PATH_SASLAUTHD_RUNDIR);
+       strcat(pwpath, "/mux");
+    }
+
+    /* Split out username/realm if necessary */
+    if(strrchr(userid,'@') != NULL) {
+       char *rtmp;
+       
+       if(_sasl_strdup(userid, &freeme, NULL) != SASL_OK)
+           goto fail;
+
+       userid = freeme;
+       rtmp = strrchr(userid,'@');
+       *rtmp = '\0';
+       user_realm = rtmp + 1;
+    }
+
+    /*
+     * build request of the form:
+     *
+     * count authid count password count service count realm
+     */
+    {
+       unsigned short u_len, p_len, s_len, r_len;
+       u_len = (strlen(userid));
+       p_len = (strlen(passwd));
+       s_len = (strlen(service));
+       r_len = ((user_realm ? strlen(user_realm) : 0));
+
+       if (u_len + p_len + s_len + r_len + 30 > (unsigned short) sizeof(query)) {
+           /* request just too damn big */
+            sasl_seterror(conn, 0, "saslauthd request too large");
+           goto fail;
+       }
+
+       u_len = htons(u_len);
+       p_len = htons(p_len);
+       s_len = htons(s_len);
+       r_len = htons(r_len);
+
+       memcpy(query_end, &u_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*userid) *query_end++ = *userid++;
+
+       memcpy(query_end, &p_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*passwd) *query_end++ = *passwd++;
+
+       memcpy(query_end, &s_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*service) *query_end++ = *service++;
+
+       memcpy(query_end, &r_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       if (user_realm) while (*user_realm) *query_end++ = *user_realm++;
+    }
+
+#ifdef USE_DOORS
+    s = open(pwpath, O_RDONLY);
+    if (s < 0) {
+       sasl_seterror(conn, 0, "cannot open door to saslauthd server: %m", errno);
+       goto fail;
+    }
+
+    arg.data_ptr = query;
+    arg.data_size = query_end - query;
+    arg.desc_ptr = NULL;
+    arg.desc_num = 0;
+    arg.rbuf = response;
+    arg.rsize = sizeof(response);
+
+    if (door_call(s, &arg) < 0) {
+      /* Parameters are undefined */
+      close(s);
+      sasl_seterror(conn, 0, "door call to saslauthd server failed: %m", errno);
+      goto fail;
+    }
+
+    if (arg.data_ptr != response || arg.data_size >= sizeof(response)) {
+       /* oh damn, we got back a really long response */
+       munmap(arg.rbuf, arg.rsize);
+       close(s);
+       sasl_seterror(conn, 0, "saslauthd sent an overly long response");
+       goto fail;
+    }
+    response[arg.data_size] = '\0';
+
+    close(s);
+#else
+    /* unix sockets */
+
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s == -1) {
+       sasl_seterror(conn, 0, "cannot create socket for saslauthd: %m", errno);
+       goto fail;
+    }
+
+    memset((char *)&srvaddr, 0, sizeof(srvaddr));
+    srvaddr.sun_family = AF_UNIX;
+    strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path));
+
+    {
+       int r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
+       if (r == -1) {
+           close(s);
+           sasl_seterror(conn, 0, "cannot connect to saslauthd server: %m", errno);
+           goto fail;
+       }
+    }
+
+    {
+       struct iovec iov[8];
+       iov[0].iov_len = query_end - query;
+       iov[0].iov_base = query;
+
+       if (retry_writev(s, iov, 1, 0) == -1) {
+           close(s);
+            sasl_seterror(conn, 0, "write failed");
+           goto fail;
+       }
+    }
+
+    {
+       unsigned short count = 0;
+
+       /*
+        * read response of the form:
+        *
+        * count result
+        */
+       if (retry_read(s, &count, sizeof(count), 0) < (int) sizeof(count)) {
+           sasl_seterror(conn, 0, "size read failed");
+           goto fail;
+       }
+       
+       count = ntohs(count);
+       if (count < 2) { /* MUST have at least "OK" or "NO" */
+           close(s);
+           sasl_seterror(conn, 0, "bad response from saslauthd");
+           goto fail;
+       }
+       
+       count = (int)sizeof(response) <= count ? sizeof(response) - 1 : count;
+       if (retry_read(s, response, count, 0) < count) {
+           close(s);
+           sasl_seterror(conn, 0, "read failed");
+           goto fail;
+       }
+       response[count] = '\0';
+    }
+
+    close(s);
+#endif /* USE_DOORS */
+  
+    if(freeme) free(freeme);
+
+    if (!strncmp(response, "OK", 2)) {
+       return SASL_OK;
+    }
+  
+    sasl_seterror(conn, SASL_NOLOG, "authentication failed");
+    return SASL_BADAUTH;
+
+ fail:
+    if (freeme) free(freeme);
+    return SASL_FAIL;
+}
+
+#endif
+
+#ifdef HAVE_AUTHDAEMON
+/* 
+ * Preliminary support for Courier's authdaemond.
+ */
+#define AUTHDAEMON_IO_TIMEOUT 30
+
+static int authdaemon_blocking(int fd, int block)
+{
+    int f, r;
+
+    /* Get the fd's blocking bit. */
+    f = fcntl(fd, F_GETFL, 0);
+    if (f == -1)
+       return -1;
+
+    /* Adjust the bitmap accordingly. */
+#ifndef O_NONBLOCK
+#define NB_BITMASK FNDELAY
+#else
+#define NB_BITMASK O_NONBLOCK
+#endif
+    if (block)
+       f &= ~NB_BITMASK;
+    else
+       f |=  NB_BITMASK;
+#undef NB_BITMASK
+
+    /* Adjust the fd's blocking bit. */
+    r = fcntl(fd, F_SETFL, f);
+    if (r)
+       return -1;
+
+    /* Success. */
+    return 0;
+}
+
+static int authdaemon_connect(sasl_conn_t *conn, const char *path)
+{
+    int r, s = -1;
+    struct sockaddr_un srvaddr;
+
+    if (strlen(path) >= sizeof(srvaddr.sun_path)) {
+       sasl_seterror(conn, 0, "unix socket path too large", errno);
+       goto fail;
+    }
+
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s == -1) {
+       sasl_seterror(conn, 0, "cannot create socket for connection to Courier authdaemond: %m", errno);
+       goto fail;
+    }
+
+    memset((char *)&srvaddr, 0, sizeof(srvaddr));
+    srvaddr.sun_family = AF_UNIX;
+    strncpy(srvaddr.sun_path, path, sizeof(srvaddr.sun_path) - 1);
+
+    /* Use nonblocking unix socket connect(2). */
+    if (authdaemon_blocking(s, 0)) {
+       sasl_seterror(conn, 0, "cannot set nonblocking bit: %m", errno);
+       goto fail;
+    }
+
+    r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
+    if (r == -1) {
+       sasl_seterror(conn, 0, "cannot connect to Courier authdaemond: %m", errno);
+       goto fail;
+    }
+
+    if (authdaemon_blocking(s, 1)) {
+       sasl_seterror(conn, 0, "cannot clear nonblocking bit: %m", errno);
+       goto fail;
+    }
+
+    return s;
+fail:
+    if (s >= 0)
+       close(s);
+    return -1;
+}
+
+static char *authdaemon_build_query(const char *service,
+                                   const char *authtype,
+                                   const char *user,
+                                   const char *passwd)
+{
+    int sz;
+    int l = strlen(service) 
+            + 1
+            + strlen(authtype) 
+            + 1
+            + strlen(user)
+            + 1
+            + strlen(passwd) 
+            + 1;
+    char *buf, n[5];
+    if (snprintf(n, sizeof(n), "%d", l) >= (int)sizeof(n))
+       return NULL;
+    sz = strlen(n) + l + 20;
+    if (!(buf = sasl_ALLOC(sz)))
+       return NULL;
+    snprintf(buf, 
+             sz, 
+             "AUTH %s\n%s\n%s\n%s\n%s\n\n",
+             n,
+             service,
+             authtype,
+             user,
+             passwd);
+    return buf;
+}
+
+static int authdaemon_read(int fd, void *buf0, unsigned sz)
+{
+    int nr;
+    char *buf = (char*) buf0;
+    if (sz <= 1)
+       return -1;
+    if ((nr = retry_read(fd, buf0, sz - 1, AUTHDAEMON_IO_TIMEOUT)) < 0)
+       return -1;
+    /* We need a null-terminated buffer. */
+    buf[nr] = 0;
+    /* Check for overflow condition. */
+    return nr + 1 < (int)sz ? 0 : -1;
+}
+
+static int authdaemon_write(int fd, void *buf0, unsigned sz)
+{
+    int nw;
+    struct iovec io;
+    io.iov_len = sz;
+    io.iov_base = buf0;
+    nw = retry_writev(fd, &io, 1, AUTHDAEMON_IO_TIMEOUT);
+    return nw == (int)sz ? 0 : -1;
+}
+
+static int authdaemon_talk(sasl_conn_t *conn, int sock, char *authreq)
+{
+    char *str;
+    char buf[8192];
+
+    if (authdaemon_write(sock, authreq, strlen(authreq)))
+       goto _err_out;
+    if (authdaemon_read(sock, buf, sizeof(buf)))
+       goto _err_out;
+    for (str = buf; *str; ) {
+       char *sub;
+
+       for (sub = str; *str; ++str) {
+           if (*str == '\n') {
+               *str++ = 0;
+               break;
+           }
+       }
+       if (strcmp(sub, ".") == 0) {
+           /* success */
+           return SASL_OK;
+       }
+       if (strcmp(sub, "FAIL") == 0) {
+           /* passwords do not match */
+           sasl_seterror(conn, SASL_NOLOG, "authentication failed");
+           return SASL_BADAUTH;
+       }
+    }
+_err_out:
+    /* catchall: authentication error */
+    sasl_seterror(conn, 0, "could not verify password");
+    return SASL_FAIL;
+}
+
+static int authdaemon_verify_password(sasl_conn_t *conn,
+                                     const char *userid, 
+                                     const char *passwd,
+                                     const char *service,
+                                     const char *user_realm __attribute__((unused)))
+{
+    const char *p = NULL;
+    sasl_getopt_t *getopt;
+    void *context;
+    int result = SASL_FAIL;
+    char *query = NULL;
+    int sock = -1;
+
+    /* check to see if the user configured a rundir */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
+       getopt(context, NULL, "authdaemond_path", &p, NULL);
+    }
+    if (!p) {
+       /*
+        * XXX should we peek at Courier's build-time config ?
+        */
+       p = PATH_AUTHDAEMON_SOCKET;
+    }
+
+    if ((sock = authdaemon_connect(conn, p)) < 0)
+       goto out;
+    if (!(query = authdaemon_build_query(service, "login", userid, passwd)))
+       goto out;
+    result = authdaemon_talk(conn, sock, query);
+out:
+    if (sock >= 0)
+       close(sock), sock = -1;
+    if (query)
+       sasl_FREE(query), query = 0;
+    return result;
+}
+#endif
+
+#ifdef HAVE_ALWAYSTRUE
+static int always_true(sasl_conn_t *conn,
+                      const char *userstr,
+                      const char *passwd __attribute__((unused)),
+                      const char *service __attribute__((unused)),
+                      const char *user_realm __attribute__((unused))) 
+{
+    _sasl_log(conn, SASL_LOG_WARN, "AlwaysTrue Password Verifier Verified: %s",
+             userstr);
+    return SASL_OK;
+}
+#endif
+
+struct sasl_verify_password_s _sasl_verify_password[] = {
+    { "auxprop", &auxprop_verify_password },
+#ifdef HAVE_PWCHECK
+    { "pwcheck", &pwcheck_verify_password },
+#endif
+#ifdef HAVE_SASLAUTHD
+    { "saslauthd", &saslauthd_verify_password },
+#endif
+#ifdef HAVE_AUTHDAEMON
+    { "authdaemond", &authdaemon_verify_password },
+#endif
+#ifdef HAVE_ALWAYSTRUE
+    { "alwaystrue", &always_true },
+#endif
+    { NULL, NULL }
+};
diff --git a/lib/client.c b/lib/client.c
new file mode 100644 (file)
index 0000000..9fdcf46
--- /dev/null
@@ -0,0 +1,1025 @@
+/* SASL client API implementation
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: client.c,v 1.67 2006/04/26 15:33:41 mel 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* SASL Headers */
+#include "sasl.h"
+#include "saslplug.h"
+#include "saslutil.h"
+#include "saslint.h"
+
+static cmech_list_t *cmechlist; /* global var which holds the list */
+sasl_global_callbacks_t global_callbacks_client; 
+static int _sasl_client_active = 0;
+
+static int init_mechlist()
+{
+  cmechlist->mutex = sasl_MUTEX_ALLOC();
+  if(!cmechlist->mutex) return SASL_FAIL;
+  
+  cmechlist->utils=_sasl_alloc_utils(NULL, &global_callbacks_client);
+  if (cmechlist->utils==NULL)
+    return SASL_NOMEM;
+
+  cmechlist->mech_list=NULL;
+  cmechlist->mech_length=0;
+
+  return SASL_OK;
+}
+
+static int client_done(void) {
+  cmechanism_t *cm;
+  cmechanism_t *cprevm;
+
+  if(!_sasl_client_active)
+      return SASL_NOTINIT;
+  else
+      _sasl_client_active--;
+  
+  if(_sasl_client_active) {
+      /* Don't de-init yet! Our refcount is nonzero. */
+      return SASL_CONTINUE;
+  }
+  
+  cm=cmechlist->mech_list; /* m point to begging of the list */
+  while (cm!=NULL)
+  {
+    cprevm=cm;
+    cm=cm->next;
+
+    if (cprevm->m.plug->mech_free) {
+       cprevm->m.plug->mech_free(cprevm->m.plug->glob_context,
+                               cmechlist->utils);
+    }
+
+    sasl_FREE(cprevm->m.plugname);
+    sasl_FREE(cprevm);    
+  }
+  sasl_MUTEX_FREE(cmechlist->mutex);
+  _sasl_free_utils(&cmechlist->utils);
+  sasl_FREE(cmechlist);
+
+  cmechlist = NULL;
+
+  return SASL_OK;
+}
+
+int sasl_client_add_plugin(const char *plugname,
+                          sasl_client_plug_init_t *entry_point)
+{
+  int plugcount;
+  sasl_client_plug_t *pluglist;
+  cmechanism_t *mech;
+  int result;
+  int version;
+  int lupe;
+
+  if(!plugname || !entry_point) return SASL_BADPARAM;
+  
+  result = entry_point(cmechlist->utils, SASL_CLIENT_PLUG_VERSION, &version,
+                      &pluglist, &plugcount);
+
+  if (result != SASL_OK)
+  {
+    _sasl_log(NULL, SASL_LOG_WARN,
+             "entry_point failed in sasl_client_add_plugin for %s",
+             plugname);
+    return result;
+  }
+
+  if (version != SASL_CLIENT_PLUG_VERSION)
+  {
+    _sasl_log(NULL, SASL_LOG_WARN,
+             "version conflict in sasl_client_add_plugin for %s", plugname);
+    return SASL_BADVERS;
+  }
+
+  for (lupe=0;lupe< plugcount ;lupe++)
+    {
+      mech = sasl_ALLOC(sizeof(cmechanism_t));
+      if (! mech) return SASL_NOMEM;
+
+      mech->m.plug=pluglist++;
+      if(_sasl_strdup(plugname, &mech->m.plugname, NULL) != SASL_OK) {
+       sasl_FREE(mech);
+       return SASL_NOMEM;
+      }
+      mech->m.version = version;
+      mech->next = cmechlist->mech_list;
+      cmechlist->mech_list = mech;
+      cmechlist->mech_length++;
+    }
+
+  return SASL_OK;
+}
+
+static int
+client_idle(sasl_conn_t *conn)
+{
+  cmechanism_t *m;
+  if (! cmechlist)
+    return 0;
+
+  for (m = cmechlist->mech_list;
+       m;
+       m = m->next)
+    if (m->m.plug->idle
+       &&  m->m.plug->idle(m->m.plug->glob_context,
+                         conn,
+                         conn ? ((sasl_client_conn_t *)conn)->cparams : NULL))
+      return 1;
+  return 0;
+}
+
+/* initialize the SASL client drivers
+ *  callbacks      -- base callbacks for all client connections
+ * returns:
+ *  SASL_OK        -- Success
+ *  SASL_NOMEM     -- Not enough memory
+ *  SASL_BADVERS   -- Mechanism version mismatch
+ *  SASL_BADPARAM  -- error in config file
+ *  SASL_NOMECH    -- No mechanisms available
+ *  ...
+ */
+
+int sasl_client_init(const sasl_callback_t *callbacks)
+{
+  int ret;
+  const add_plugin_list_t ep_list[] = {
+      { "sasl_client_plug_init", (add_plugin_t *)sasl_client_add_plugin },
+      { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin },
+      { NULL, NULL }
+  };
+
+  if(_sasl_client_active) {
+      /* We're already active, just increase our refcount */
+      /* xxx do something with the callback structure? */
+      _sasl_client_active++;
+      return SASL_OK;
+  }
+
+  global_callbacks_client.callbacks = callbacks;
+  global_callbacks_client.appname = NULL;
+
+  cmechlist=sasl_ALLOC(sizeof(cmech_list_t));
+  if (cmechlist==NULL) return SASL_NOMEM;
+
+  /* We need to call client_done if we fail now */
+  _sasl_client_active = 1;
+
+  /* load plugins */
+  ret=init_mechlist();  
+  if (ret!=SASL_OK) {
+      client_done();
+      return ret;
+  }
+
+  sasl_client_add_plugin("EXTERNAL", &external_client_plug_init);
+
+  ret = _sasl_common_init(&global_callbacks_client);
+
+  if (ret == SASL_OK)
+      ret = _sasl_load_plugins(ep_list,
+                              _sasl_find_getpath_callback(callbacks),
+                              _sasl_find_verifyfile_callback(callbacks));
+  
+  if (ret == SASL_OK) {
+      _sasl_client_cleanup_hook = &client_done;
+      _sasl_client_idle_hook = &client_idle;
+
+      ret = _sasl_build_mechlist();
+  } else {
+      client_done();
+  }
+      
+  return ret;
+}
+
+static void client_dispose(sasl_conn_t *pconn)
+{
+  sasl_client_conn_t *c_conn=(sasl_client_conn_t *) pconn;
+
+  if (c_conn->mech && c_conn->mech->m.plug->mech_dispose) {
+    c_conn->mech->m.plug->mech_dispose(pconn->context,
+                                    c_conn->cparams->utils);
+  }
+
+  pconn->context = NULL;
+
+  if (c_conn->clientFQDN)
+      sasl_FREE(c_conn->clientFQDN);
+
+  if (c_conn->cparams) {
+      _sasl_free_utils(&(c_conn->cparams->utils));
+      sasl_FREE(c_conn->cparams);
+  }
+
+  _sasl_conn_dispose(pconn);
+}
+
+/* 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
+ *  secflags      -- security flags (see above)
+ * in/out:
+ *  pconn         -- connection negotiation structure
+ *                   pointer to NULL => allocate new
+ *                   non-NULL => recycle storage and go for next available mech
+ *
+ * Returns:
+ *  SASL_OK       -- success
+ *  SASL_NOMECH   -- no mechanism meets requested properties
+ *  SASL_NOMEM    -- not enough memory
+ */
+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)
+{
+  int result;
+  char name[MAXHOSTNAMELEN];
+  sasl_client_conn_t *conn;
+  sasl_utils_t *utils;
+
+  if(_sasl_client_active==0) return SASL_NOTINIT;
+  
+  /* Remember, serverFQDN, iplocalport and ipremoteport can be NULL and be valid! */
+  if (!pconn || !service)
+    return SASL_BADPARAM;
+
+  *pconn=sasl_ALLOC(sizeof(sasl_client_conn_t));
+  if (*pconn==NULL) {
+      _sasl_log(NULL, SASL_LOG_ERR,
+               "Out of memory allocating connection context");
+      return SASL_NOMEM;
+  }
+  memset(*pconn, 0, sizeof(sasl_client_conn_t));
+
+  (*pconn)->destroy_conn = &client_dispose;
+
+  conn = (sasl_client_conn_t *)*pconn;
+  
+  conn->mech = NULL;
+
+  conn->cparams=sasl_ALLOC(sizeof(sasl_client_params_t));
+  if (conn->cparams==NULL) 
+      MEMERROR(*pconn);
+  memset(conn->cparams,0,sizeof(sasl_client_params_t));
+
+  result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_CLIENT,
+                          &client_idle, serverFQDN,
+                          iplocalport, ipremoteport,
+                          prompt_supp, &global_callbacks_client);
+  if (result != SASL_OK) RETURN(*pconn, result);
+  
+  utils=_sasl_alloc_utils(*pconn, &global_callbacks_client);
+  if (utils==NULL)
+      MEMERROR(*pconn);
+  
+  utils->conn= *pconn;
+
+  /* Setup the non-lazy parts of cparams, the rest is done in
+   * sasl_client_start */
+  conn->cparams->utils = utils;
+  conn->cparams->canon_user = &_sasl_canon_user;
+  conn->cparams->flags = flags;
+  conn->cparams->prompt_supp = (*pconn)->callbacks;
+  
+  /* get the clientFQDN (serverFQDN was set in _sasl_conn_init) */
+  memset(name, 0, sizeof(name));
+  gethostname(name, MAXHOSTNAMELEN);
+
+  result = _sasl_strdup(name, &conn->clientFQDN, NULL);
+
+  if(result == SASL_OK) return SASL_OK;
+
+  /* result isn't SASL_OK */
+  _sasl_conn_dispose(*pconn);
+  sasl_FREE(*pconn);
+  *pconn = NULL;
+  _sasl_log(NULL, SASL_LOG_ERR, "Out of memory in sasl_client_new");
+  return result;
+}
+
+static int have_prompts(sasl_conn_t *conn,
+                       const sasl_client_plug_t *mech)
+{
+  static const unsigned long default_prompts[] = {
+    SASL_CB_AUTHNAME,
+    SASL_CB_PASS,
+    SASL_CB_LIST_END
+  };
+
+  const unsigned long *prompt;
+  int (*pproc)();
+  void *pcontext;
+  int result;
+
+  for (prompt = (mech->required_prompts
+                ? mech->required_prompts :
+                default_prompts);
+       *prompt != SASL_CB_LIST_END;
+       prompt++) {
+    result = _sasl_getcallback(conn, *prompt, &pproc, &pcontext);
+    if (result != SASL_OK && result != SASL_INTERACT)
+      return 0;                        /* we don't have this required prompt */
+  }
+
+  return 1; /* we have all the prompts */
+}
+
+/* select a mechanism for a connection
+ *  mechlist      -- mechanisms server has available (punctuation ignored)
+ *  secret        -- optional secret from previous session
+ * output:
+ *  prompt_need   -- on SASL_INTERACT, list of prompts needed to continue
+ *  clientout     -- the initial client response to send to the server
+ *  mech          -- set to mechanism name
+ *
+ * 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
+ */
+
+/* xxx confirm this with rfc 2222
+ * SASL mechanism allowable characters are "AZaz-_"
+ * seperators can be any other characters and of any length
+ * even variable lengths between
+ *
+ * Apps should be encouraged to simply use space or comma space
+ * though
+ */
+int sasl_client_start(sasl_conn_t *conn,
+                     const char *mechlist,
+                     sasl_interact_t **prompt_need,
+                     const char **clientout,
+                     unsigned *clientoutlen,
+                     const char **mech)
+{
+    sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn;
+    char name[SASL_MECHNAMEMAX + 1];
+    cmechanism_t *m=NULL,*bestm=NULL;
+    size_t pos=0,place;
+    size_t list_len;
+    sasl_ssf_t bestssf = 0, minssf = 0;
+    int result;
+
+    if(_sasl_client_active==0) return SASL_NOTINIT;
+
+    if (!conn) return SASL_BADPARAM;
+
+    /* verify parameters */
+    if (mechlist == NULL)
+       PARAMERROR(conn);
+
+    /* if prompt_need != NULL we've already been here
+       and just need to do the continue step again */
+
+    /* do a step */
+    /* FIXME: Hopefully they only give us our own prompt_need back */
+    if (prompt_need && *prompt_need != NULL) {
+       goto dostep;
+    }
+
+    if(conn->props.min_ssf < conn->external.ssf) {
+       minssf = 0;
+    } else {
+       minssf = conn->props.min_ssf - conn->external.ssf;
+    }
+
+    /* parse mechlist */
+    list_len = strlen(mechlist);
+
+    while (pos<list_len)
+    {
+       place=0;
+       while ((pos<list_len) && (isalnum((unsigned char)mechlist[pos])
+                                 || mechlist[pos] == '_'
+                                 || mechlist[pos] == '-')) {
+           name[place]=mechlist[pos];
+           pos++;
+           place++;
+           if (SASL_MECHNAMEMAX < place) {
+               place--;
+               while(pos<list_len && (isalnum((unsigned char)mechlist[pos])
+                                      || mechlist[pos] == '_'
+                                      || mechlist[pos] == '-'))
+                   pos++;
+           }
+       }
+       pos++;
+       name[place]=0;
+
+       if (! place) continue;
+
+       /* foreach in client list */
+       for (m = cmechlist->mech_list; m != NULL; m = m->next) {
+           int myflags;
+           
+           /* Is this the mechanism the server is suggesting? */
+           if (strcasecmp(m->m.plug->mech_name, name))
+               continue; /* no */
+
+           /* Do we have the prompts for it? */
+           if (!have_prompts(conn, m->m.plug))
+               break;
+
+           /* Is it strong enough? */
+           if (minssf > m->m.plug->max_ssf)
+               break;
+
+           /* Does it meet our security properties? */
+           myflags = conn->props.security_flags;
+           
+           /* if there's an external layer this is no longer plaintext */
+           if ((conn->props.min_ssf <= conn->external.ssf) && 
+               (conn->external.ssf > 1)) {
+               myflags &= ~SASL_SEC_NOPLAINTEXT;
+           }
+
+           if (((myflags ^ m->m.plug->security_flags) & myflags) != 0) {
+               break;
+           }
+
+           /* Can we meet it's features? */
+           if ((m->m.plug->features & SASL_FEAT_NEEDSERVERFQDN)
+               && !conn->serverFQDN) {
+               break;
+           }
+
+           /* Can it meet our features? */
+           if ((conn->flags & SASL_NEED_PROXY) &&
+               !(m->m.plug->features & SASL_FEAT_ALLOWS_PROXY)) {
+               break;
+           }
+           
+#ifdef PREFER_MECH
+           if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) &&
+               bestm && m->m.plug->max_ssf <= bestssf) {
+               /* this mechanism isn't our favorite, and it's no better
+                  than what we already have! */
+               break;
+           }
+#else
+           if (bestm && m->m.plug->max_ssf <= bestssf) {
+               /* this mechanism is no better than what we already have! */
+               break;
+           }
+#endif
+
+           /* compare security flags, only take new mechanism if it has
+            * all the security flags of the previous one.
+            *
+            * From the mechanisms we ship with, this yields the order:
+            *
+            * SRP
+            * GSSAPI + KERBEROS_V4
+            * DIGEST + OTP
+            * CRAM + EXTERNAL
+            * PLAIN + LOGIN + ANONYMOUS
+            *
+            * This might be improved on by comparing the numeric value of
+            * the bitwise-or'd security flags, which splits DIGEST/OTP,
+            * CRAM/EXTERNAL, and PLAIN/LOGIN from ANONYMOUS, but then we
+            * are depending on the numeric values of the flags (which may
+            * change, and their ordering could be considered dumb luck.
+            */
+
+           if (bestm &&
+               ((m->m.plug->security_flags ^ bestm->m.plug->security_flags) &
+                bestm->m.plug->security_flags)) {
+               break;
+           }
+
+           if (mech) {
+               *mech = m->m.plug->mech_name;
+           }
+           bestssf = m->m.plug->max_ssf;
+           bestm = m;
+           break;
+       }
+    }
+
+    if (bestm == NULL) {
+       sasl_seterror(conn, 0, "No worthy mechs found");
+       result = SASL_NOMECH;
+       goto done;
+    }
+
+    /* make (the rest of) cparams */
+    c_conn->cparams->service = conn->service;
+    c_conn->cparams->servicelen = (unsigned) strlen(conn->service);
+    
+    if (conn->serverFQDN) {
+       c_conn->cparams->serverFQDN = conn->serverFQDN; 
+       c_conn->cparams->slen = (unsigned) strlen(conn->serverFQDN);
+    }
+
+    c_conn->cparams->clientFQDN = c_conn->clientFQDN; 
+    c_conn->cparams->clen = (unsigned) strlen(c_conn->clientFQDN);
+
+    c_conn->cparams->external_ssf = conn->external.ssf;
+    c_conn->cparams->props = conn->props;
+    c_conn->mech = bestm;
+
+    /* init that plugin */
+    result = c_conn->mech->m.plug->mech_new(c_conn->mech->m.plug->glob_context,
+                                         c_conn->cparams,
+                                         &(conn->context));
+    if(result != SASL_OK) goto done;
+
+    /* do a step -- but only if we can do a client-send-first */
+ dostep:
+    if(clientout) {
+        if(c_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) {
+            *clientout = NULL;
+            *clientoutlen = 0;
+            result = SASL_CONTINUE;
+        } else {
+            result = sasl_client_step(conn, NULL, 0, prompt_need,
+                                      clientout, clientoutlen);
+        }
+    }
+    else
+       result = SASL_CONTINUE;
+
+ done:
+    RETURN(conn, result);
+}
+
+/* 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
+ *
+ * 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
+ */
+
+int sasl_client_step(sasl_conn_t *conn,
+                    const char *serverin,
+                    unsigned serverinlen,
+                    sasl_interact_t **prompt_need,
+                    const char **clientout,
+                    unsigned *clientoutlen)
+{
+  sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn;
+  int result;
+
+  if(_sasl_client_active==0) return SASL_NOTINIT;
+  if(!conn) return SASL_BADPARAM;
+
+  /* check parameters */
+  if ((serverin==NULL) && (serverinlen>0))
+      PARAMERROR(conn);
+
+  /* Don't do another step if the plugin told us that we're done */
+  if (conn->oparams.doneflag) {
+      _sasl_log(conn, SASL_LOG_ERR, "attempting client step after doneflag");
+      return SASL_FAIL;
+  }
+
+  if(clientout) *clientout = NULL;
+  if(clientoutlen) *clientoutlen = 0;
+
+  /* do a step */
+  result = c_conn->mech->m.plug->mech_step(conn->context,
+                                        c_conn->cparams,
+                                        serverin,
+                                        serverinlen,
+                                        prompt_need,
+                                        clientout, clientoutlen,
+                                        &conn->oparams);
+
+  if (result == SASL_OK) {
+      /* So we're done on this end, but if both
+       * 1. the mech does server-send-last
+       * 2. the protocol does not
+       * we need to return no data */
+      if(!*clientout && !(conn->flags & SASL_SUCCESS_DATA)) {
+         *clientout = "";
+         *clientoutlen = 0;
+      }
+      
+      if(!conn->oparams.maxoutbuf) {
+         conn->oparams.maxoutbuf = conn->props.maxbufsize;
+      }
+
+      if(conn->oparams.user == NULL || conn->oparams.authid == NULL) {
+         sasl_seterror(conn, 0,
+                       "mech did not call canon_user for both authzid and authid");
+         result = SASL_BADPROT;
+      }
+  }  
+
+  RETURN(conn,result);
+}
+
+/* returns the length of all the mechanisms
+ * added up 
+ */
+
+static unsigned mech_names_len()
+{
+  cmechanism_t *listptr;
+  unsigned result = 0;
+
+  for (listptr = cmechlist->mech_list;
+       listptr;
+       listptr = listptr->next)
+    result += (unsigned) strlen(listptr->m.plug->mech_name);
+
+  return result;
+}
+
+
+int _sasl_client_listmech(sasl_conn_t *conn,
+                         const char *prefix,
+                         const char *sep,
+                         const char *suffix,
+                         const char **result,
+                         unsigned *plen,
+                         int *pcount)
+{
+    cmechanism_t *m=NULL;
+    sasl_ssf_t minssf = 0;
+    int ret;
+    size_t resultlen;
+    int flag;
+    const char *mysep;
+
+    if(_sasl_client_active == 0) return SASL_NOTINIT;
+    if (!conn) return SASL_BADPARAM;
+    if(conn->type != SASL_CONN_CLIENT) PARAMERROR(conn);
+    
+    if (! result)
+       PARAMERROR(conn);
+    
+    if (plen != NULL)
+       *plen = 0;
+    if (pcount != NULL)
+       *pcount = 0;
+
+    if (sep) {
+       mysep = sep;
+    } else {
+       mysep = " ";
+    }
+
+    if(conn->props.min_ssf < conn->external.ssf) {
+       minssf = 0;
+    } else {
+       minssf = conn->props.min_ssf - conn->external.ssf;
+    }
+
+    if (! cmechlist || cmechlist->mech_length <= 0)
+       INTERROR(conn, SASL_NOMECH);
+
+    resultlen = (prefix ? strlen(prefix) : 0)
+       + (strlen(mysep) * (cmechlist->mech_length - 1))
+       + mech_names_len()
+       + (suffix ? strlen(suffix) : 0)
+       + 1;
+    ret = _buf_alloc(&conn->mechlist_buf,
+                    &conn->mechlist_buf_len, resultlen);
+    if(ret != SASL_OK) MEMERROR(conn);
+
+    if (prefix)
+       strcpy (conn->mechlist_buf,prefix);
+    else
+       *(conn->mechlist_buf) = '\0';
+
+    flag = 0;
+    for (m = cmechlist->mech_list; m != NULL; m = m->next) {
+           /* do we have the prompts for it? */
+           if (!have_prompts(conn, m->m.plug))
+               continue;
+
+           /* is it strong enough? */
+           if (minssf > m->m.plug->max_ssf)
+               continue;
+
+           /* does it meet our security properties? */
+           if (((conn->props.security_flags ^ m->m.plug->security_flags)
+                & conn->props.security_flags) != 0) {
+               continue;
+           }
+
+           /* Can we meet it's features? */
+           if ((m->m.plug->features & SASL_FEAT_NEEDSERVERFQDN)
+               && !conn->serverFQDN) {
+               continue;
+           }
+
+           /* Can it meet our features? */
+           if ((conn->flags & SASL_NEED_PROXY) &&
+               !(m->m.plug->features & SASL_FEAT_ALLOWS_PROXY)) {
+               continue;
+           }
+
+           /* Okay, we like it, add it to the list! */
+
+           if (pcount != NULL)
+               (*pcount)++;
+
+           /* print seperator */
+           if (flag) {
+               strcat(conn->mechlist_buf, mysep);
+           } else {
+               flag = 1;
+           }
+           
+           /* now print the mechanism name */
+           strcat(conn->mechlist_buf, m->m.plug->mech_name);
+    }
+    
+  if (suffix)
+      strcat(conn->mechlist_buf,suffix);
+
+  if (plen!=NULL)
+      *plen = (unsigned) strlen(conn->mechlist_buf);
+
+  *result = conn->mechlist_buf;
+
+  return SASL_OK;
+}
+
+sasl_string_list_t *_sasl_client_mechs(void) 
+{
+  cmechanism_t *listptr;
+  sasl_string_list_t *retval = NULL, *next=NULL;
+
+  if(!_sasl_client_active) return NULL;
+
+  /* make list */
+  for (listptr = cmechlist->mech_list; listptr; listptr = listptr->next) {
+      next = sasl_ALLOC(sizeof(sasl_string_list_t));
+
+      if(!next && !retval) return NULL;
+      else if(!next) {
+         next = retval->next;
+         do {
+             sasl_FREE(retval);
+             retval = next;
+             next = retval->next;
+         } while(next);
+         return NULL;
+      }
+      
+      next->d = listptr->m.plug->mech_name;
+
+      if(!retval) {
+         next->next = NULL;
+         retval = next;
+      } else {
+         next->next = retval;
+         retval = next;
+      }
+  }
+
+  return retval;
+}
+
+
+
+
+/* It would be nice if we can show other information like Author, Company, Year, plugin version */
+static void
+_sasl_print_mechanism (
+  client_sasl_mechanism_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char delimiter;
+
+    if (stage == SASL_INFO_LIST_START) {
+       printf ("List of client plugins follows\n");
+       return;
+    } else if (stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    /* Process the mechanism */
+    printf ("Plugin \"%s\" ", m->plugname);
+
+    /* There is no delay loading for client side plugins */
+    printf ("[loaded]");
+
+    printf (", \tAPI version: %d\n", m->version);
+
+    if (m->plug != NULL) {
+       printf ("\tSASL mechanism: %s, best SSF: %d\n",
+               m->plug->mech_name,
+               m->plug->max_ssf);
+
+       printf ("\tsecurity flags:");
+       
+       delimiter = ' ';
+       if (m->plug->security_flags & SASL_SEC_NOANONYMOUS) {
+           printf ("%cNO_ANONYMOUS", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_NOPLAINTEXT) {
+           printf ("%cNO_PLAINTEXT", delimiter);
+           delimiter = '|';
+       }
+       
+       if (m->plug->security_flags & SASL_SEC_NOACTIVE) {
+           printf ("%cNO_ACTIVE", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_NODICTIONARY) {
+           printf ("%cNO_DICTIONARY", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_FORWARD_SECRECY) {
+           printf ("%cFORWARD_SECRECY", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_PASS_CREDENTIALS) {
+           printf ("%cPASS_CREDENTIALS", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_MUTUAL_AUTH) {
+           printf ("%cMUTUAL_AUTH", delimiter);
+           delimiter = '|';
+       }
+
+
+
+       printf ("\n\tfeatures:");
+       
+       delimiter = ' ';
+       if (m->plug->features & SASL_FEAT_WANT_CLIENT_FIRST) {
+           printf ("%cWANT_CLIENT_FIRST", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_SERVER_FIRST) {
+           printf ("%cSERVER_FIRST", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_ALLOWS_PROXY) {
+           printf ("%cPROXY_AUTHENTICATION", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_NEEDSERVERFQDN) {
+           printf ("%cNEED_SERVER_FQDN", delimiter);
+           delimiter = '|';
+       }
+    }
+
+/* Delay loading is not supported for the client side plugins:
+    if (m->f) {
+       printf ("\n\twill be loaded from \"%s\"", m->f);
+    }
+ */
+
+    printf ("\n");
+}
+
+
+/* Dump information about available client plugins */
+int sasl_client_plugin_info (
+  const char *c_mech_list,             /* space separated mechanism list or NULL for ALL */
+  sasl_client_info_callback_t *info_cb,
+  void *info_cb_rock
+)
+{
+    cmechanism_t *m;
+    client_sasl_mechanism_t plug_data;
+    char * cur_mech;
+    char * mech_list = NULL;
+    char * p;
+
+    if (info_cb == NULL) {
+       info_cb = _sasl_print_mechanism;
+    }
+
+    if (cmechlist != NULL) {
+       info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock);
+
+       if (c_mech_list == NULL) {
+           m = cmechlist->mech_list; /* m point to beginning of the list */
+
+           while (m != NULL) {
+               memcpy (&plug_data, &m->m, sizeof(plug_data));
+
+               info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+           
+               m = m->next;
+           }
+       } else {
+            mech_list = strdup (c_mech_list);
+
+           cur_mech = mech_list;
+
+           while (cur_mech != NULL) {
+               p = strchr (cur_mech, ' ');
+               if (p != NULL) {
+                   *p = '\0';
+                   p++;
+               }
+
+               m = cmechlist->mech_list; /* m point to beginning of the list */
+
+               while (m != NULL) {
+                   if (strcasecmp (cur_mech, m->m.plug->mech_name) == 0) {
+                       memcpy (&plug_data, &m->m, sizeof(plug_data));
+
+                       info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+                   }
+           
+                   m = m->next;
+               }
+
+               cur_mech = p;
+           }
+
+            free (mech_list);
+       }
+
+       info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock);
+
+       return (SASL_OK);
+    }
+
+    return (SASL_NOTINIT);
+}
diff --git a/lib/common.c b/lib/common.c
new file mode 100644 (file)
index 0000000..6a1ae35
--- /dev/null
@@ -0,0 +1,2490 @@
+/* common.c - Functions that are common to server and clinet
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: common.c,v 1.114 2006/04/19 18:39:59 mel 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#ifdef HAVE_SYSLOG
+#include <syslog.h>
+#endif
+#include <stdarg.h>
+#include <ctype.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+#include "saslint.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+static const char *implementation_string = "Cyrus SASL";
+
+#define        VSTR0(maj, min, step)   #maj "." #min "." #step
+#define        VSTR(maj, min, step)    VSTR0(maj, min, step)
+#define        SASL_VERSION_STRING     VSTR(SASL_VERSION_MAJOR, SASL_VERSION_MINOR, \
+                               SASL_VERSION_STEP)
+
+static int _sasl_getpath(void *context __attribute__((unused)), const char **path);
+static int _sasl_getpath_simple(void *context __attribute__((unused)), const char **path);
+static int _sasl_getconfpath(void *context __attribute__((unused)), char ** path);
+static int _sasl_getconfpath_simple(void *context __attribute__((unused)), const char **path);
+
+#if !defined(WIN32)
+static char * _sasl_get_default_unix_path(void *context __attribute__((unused)),
+                            char * env_var_name, char * default_value);
+#else
+/* NB: Always returned allocated value */
+static char * _sasl_get_default_win_path(void *context __attribute__((unused)),
+                            char * reg_attr_name, char * default_value);
+#endif
+
+
+static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $";
+
+/* It turns out to be convenient to have a shared sasl_utils_t */
+LIBSASL_VAR const sasl_utils_t *sasl_global_utils = NULL;
+
+/* Should be a null-terminated array that lists the available mechanisms */
+static char **global_mech_list = NULL;
+
+void *free_mutex = NULL;
+
+int (*_sasl_client_cleanup_hook)(void) = NULL;
+int (*_sasl_server_cleanup_hook)(void) = NULL;
+int (*_sasl_client_idle_hook)(sasl_conn_t *conn) = NULL;
+int (*_sasl_server_idle_hook)(sasl_conn_t *conn) = NULL;
+
+sasl_allocation_utils_t _sasl_allocation_utils={
+  (sasl_malloc_t *)  &malloc,
+  (sasl_calloc_t *)  &calloc,
+  (sasl_realloc_t *) &realloc,
+  (sasl_free_t *) &free
+};
+
+#define SASL_ENCODEV_EXTRA  4096
+
+/* Default getpath/getconfpath callbacks. These can be edited by sasl_set_path(). */
+static sasl_callback_t default_getpath_cb = {
+    SASL_CB_GETPATH, &_sasl_getpath, NULL
+};
+static sasl_callback_t default_getconfpath_cb = {
+    SASL_CB_GETCONFPATH, &_sasl_getconfpath, NULL
+};
+
+static char * default_plugin_path = NULL;
+static char * default_conf_path = NULL;
+
+/* Intenal mutex functions do as little as possible (no thread protection) */
+static void *sasl_mutex_alloc(void)
+{
+  return (void *)0x1;
+}
+
+static int sasl_mutex_lock(void *mutex __attribute__((unused)))
+{
+    return SASL_OK;
+}
+
+static int sasl_mutex_unlock(void *mutex __attribute__((unused)))
+{
+    return SASL_OK;
+}
+
+static void sasl_mutex_free(void *mutex __attribute__((unused)))
+{
+    return;
+}
+
+sasl_mutex_utils_t _sasl_mutex_utils={
+  &sasl_mutex_alloc,
+  &sasl_mutex_lock,
+  &sasl_mutex_unlock,
+  &sasl_mutex_free
+};
+
+void sasl_set_mutex(sasl_mutex_alloc_t *n, sasl_mutex_lock_t *l,
+                   sasl_mutex_unlock_t *u, sasl_mutex_free_t *d)
+{
+  _sasl_mutex_utils.alloc=n;
+  _sasl_mutex_utils.lock=l;
+  _sasl_mutex_utils.unlock=u;
+  _sasl_mutex_utils.free=d;
+}
+
+/* copy a string to malloced memory */
+int _sasl_strdup(const char *in, char **out, size_t *outlen)
+{
+  size_t len = strlen(in);
+  if (outlen) *outlen = len;
+  *out=sasl_ALLOC((unsigned) len + 1);
+  if (! *out) return SASL_NOMEM;
+  strcpy((char *) *out, in);
+  return SASL_OK;
+}
+
+/* adds a string to the buffer; reallocing if need be */
+int _sasl_add_string(char **out, size_t *alloclen,
+                    size_t *outlen, const char *add)
+{
+  size_t addlen;
+
+  if (add==NULL) add = "(null)";
+
+  addlen=strlen(add); /* only compute once */
+  if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK)
+    return SASL_NOMEM;
+
+  strncpy(*out + *outlen, add, addlen);
+  *outlen += addlen;
+
+  return SASL_OK;
+}
+
+/* a simpler way to set plugin path or configuration file path
+ * without the need to set sasl_getpath_t callback.
+ *
+ * This function can be called before sasl_server_init/sasl_client_init.
+ *
+ * Don't call this function without locking in a multithreaded application.
+ */  
+int sasl_set_path (int path_type, char * path)
+{
+    int result;
+
+    if (path == NULL) {
+        return (SASL_FAIL);
+    }
+
+    switch (path_type) {
+        case SASL_PATH_TYPE_PLUGIN:
+            if (default_plugin_path != NULL) {
+                sasl_FREE (default_plugin_path);
+                default_plugin_path = NULL;
+            }
+            result = _sasl_strdup (path, &default_plugin_path, NULL);
+            if (result != SASL_OK) {
+                return (result);
+            }
+
+            /* Update the default getpath_t callback */
+            default_getpath_cb.proc = (int (*)()) &_sasl_getpath_simple;
+            break;
+
+        case SASL_PATH_TYPE_CONFIG:
+            if (default_conf_path != NULL) {
+                sasl_FREE (default_conf_path);
+                default_conf_path = NULL;
+            }
+            result = _sasl_strdup (path, &default_conf_path, NULL);
+            if (result != SASL_OK) {
+                return (result);
+            }
+
+            /* Update the default getpath_t callback */
+            default_getconfpath_cb.proc = (int (*)()) &_sasl_getconfpath_simple;
+            break;
+
+        default:
+            return (SASL_FAIL);
+    }
+
+    return (SASL_OK);
+}
+
+/* return the version of the cyrus sasl library as compiled,
+ * using 32 bits: high byte is major version, second byte is minor version,
+ * low 16 bits are step # */
+void sasl_version(const char **implementation, int *version) 
+{
+    if(implementation) *implementation = implementation_string;
+    /* NB: the format is not the same as in SASL_VERSION_FULL */
+    if(version) *version = (SASL_VERSION_MAJOR << 24) | 
+                          (SASL_VERSION_MINOR << 16) |
+                          (SASL_VERSION_STEP);
+}
+
+/* Extended version of sasl_version above */
+void sasl_version_info (const char **implementation, const char **version_string,
+                   int *version_major, int *version_minor, int *version_step,
+                   int *version_patch)
+{
+    if (implementation) *implementation = implementation_string;
+    if (version_string) *version_string = SASL_VERSION_STRING;
+    if (version_major) *version_major = SASL_VERSION_MAJOR;
+    if (version_minor) *version_minor = SASL_VERSION_MINOR;
+    if (version_step) *version_step = SASL_VERSION_STEP;
+    /* Version patch is always 0 for CMU SASL */
+    if (version_patch) *version_patch = 0;
+}
+
+/* security-encode a regular string.  Mostly a wrapper for sasl_encodev */
+/* output is only valid until next call to sasl_encode or sasl_encodev */
+int sasl_encode(sasl_conn_t *conn, const char *input,
+               unsigned inputlen,
+               const char **output, unsigned *outputlen)
+{
+    int result;
+    struct iovec tmp;
+
+    if(!conn) return SASL_BADPARAM;
+    if(!input || !inputlen || !output || !outputlen)
+       PARAMERROR(conn);
+    
+    /* maxoutbuf checking is done in sasl_encodev */
+
+    /* Note: We are casting a const pointer here, but it's okay
+     * because we believe people downstream of us are well-behaved, and the
+     * alternative is an absolute mess, performance-wise. */
+    tmp.iov_base = (void *)input;
+    tmp.iov_len = inputlen;
+    
+    result = sasl_encodev(conn, &tmp, 1, output, outputlen);
+
+    RETURN(conn, result);
+}
+
+/* Internal function that doesn't do any verification */
+static int
+_sasl_encodev (sasl_conn_t *conn,
+              const struct iovec *invec,
+               unsigned numiov,
+               int * p_num_packets,     /* number of packets generated so far */
+              const char **output,     /* previous output, if *p_num_packets > 0 */
+               unsigned *outputlen)
+{
+    int result;
+    char * new_buf;
+
+    assert (conn->oparams.encode != NULL);
+
+    if (*p_num_packets == 1) {
+        /* This is the second call to this function,
+           so we need to allocate a new output buffer
+           and copy existing data there. */
+        conn->multipacket_encoded_data.curlen = *outputlen;
+        if (conn->multipacket_encoded_data.data == NULL) {
+            conn->multipacket_encoded_data.reallen = 
+                 conn->multipacket_encoded_data.curlen + SASL_ENCODEV_EXTRA;
+            conn->multipacket_encoded_data.data =
+                 sasl_ALLOC(conn->multipacket_encoded_data.reallen + 1);
+
+            if (conn->multipacket_encoded_data.data == NULL) {
+                MEMERROR(conn);
+            }
+        } else {
+            /* A buffer left from a previous sasl_encodev call.
+               Make sure it is big enough. */
+            if (conn->multipacket_encoded_data.curlen >
+                conn->multipacket_encoded_data.reallen) {
+                conn->multipacket_encoded_data.reallen = 
+                    conn->multipacket_encoded_data.curlen + SASL_ENCODEV_EXTRA;
+
+               new_buf = sasl_REALLOC(conn->multipacket_encoded_data.data,
+                            conn->multipacket_encoded_data.reallen + 1);
+                if (new_buf == NULL) {
+                    MEMERROR(conn);
+                }
+                conn->multipacket_encoded_data.data = new_buf;
+            }
+        }
+
+        memcpy (conn->multipacket_encoded_data.data,
+                *output,
+                *outputlen);
+    }
+
+    result = conn->oparams.encode(conn->context,
+                                  invec,
+                                  numiov,
+                                 output,
+                                  outputlen);
+
+    if (*p_num_packets > 0 && result == SASL_OK) {
+        /* Is the allocated buffer big enough? If not, grow it. */
+        if ((conn->multipacket_encoded_data.curlen + *outputlen) >
+             conn->multipacket_encoded_data.reallen) {
+            conn->multipacket_encoded_data.reallen =
+                conn->multipacket_encoded_data.curlen + *outputlen;
+           new_buf = sasl_REALLOC(conn->multipacket_encoded_data.data,
+                        conn->multipacket_encoded_data.reallen + 1);
+            if (new_buf == NULL) {
+                MEMERROR(conn);
+            }
+            conn->multipacket_encoded_data.data = new_buf;
+        }
+
+        /* Append new data to the end of the buffer */
+        memcpy (conn->multipacket_encoded_data.data +
+                conn->multipacket_encoded_data.curlen,
+                *output,
+                *outputlen);
+        conn->multipacket_encoded_data.curlen += *outputlen;
+
+        *output = conn->multipacket_encoded_data.data;
+        *outputlen = conn->multipacket_encoded_data.curlen;
+    }
+
+    (*p_num_packets)++;
+
+    RETURN(conn, result);
+}
+
+/* security-encode an iovec */
+/* output is only valid until the next call to sasl_encode or sasl_encodev */
+int sasl_encodev(sasl_conn_t *conn,
+                const struct iovec *invec,
+                 unsigned numiov,
+                const char **output,
+                 unsigned *outputlen)
+{
+    int result;
+    unsigned i;
+    unsigned j;
+    size_t total_size = 0;
+    struct iovec *cur_invec = NULL;
+    struct iovec last_invec;
+    unsigned cur_numiov;
+    char * next_buf = NULL;
+    unsigned remainder_len;
+    unsigned index_offset;
+    unsigned allocated = 0;
+    /* Number of generated SASL packets */
+    int num_packets = 0;
+
+    if (!conn) return SASL_BADPARAM;
+    if (! invec || ! output || ! outputlen || numiov < 1) {
+       PARAMERROR(conn);
+    }
+
+    if (!conn->props.maxbufsize) {
+       sasl_seterror(conn, 0,
+                     "called sasl_encode[v] with application that does not support security layers");
+       return SASL_TOOWEAK;
+    }
+
+    /* If oparams.encode is NULL, this means there is no SASL security
+       layer in effect, so no SASL framing is needed. */
+    if (conn->oparams.encode == NULL)  {
+       result = _iovec_to_buf(invec, numiov, &conn->encode_buf);
+       if (result != SASL_OK) INTERROR(conn, result);
+       
+       *output = conn->encode_buf->data;
+       *outputlen = (unsigned) conn->encode_buf->curlen;
+
+        RETURN(conn, result);
+    }
+
+    /* This might be better to check on a per-plugin basis, but I think
+     * it's cleaner and more effective here.  It also encourages plugins
+     * to be honest about what they accept */
+
+    last_invec.iov_base = NULL;
+    remainder_len = 0;
+    next_buf = NULL;
+    i = 0;
+    while (i < numiov) {
+        if ((total_size + invec[i].iov_len) > conn->oparams.maxoutbuf) {
+
+            /* CLAIM: total_size < conn->oparams.maxoutbuf */
+            
+            /* Fit as many bytes in last_invec, so that we have conn->oparams.maxoutbuf
+               bytes in total. */
+            last_invec.iov_len = conn->oparams.maxoutbuf - total_size;
+            /* Point to the first byte of the current record. */
+            last_invec.iov_base = invec[i].iov_base;
+
+            /* Note that total_size < conn->oparams.maxoutbuf */
+            /* The total size of the iov is bigger then the other end can accept.
+               So we allocate a new iov that contains just enough. */
+
+            /* +1 --- for the tail record */
+            cur_numiov = i + 1;
+
+            /* +1 --- just in case we need the head record */
+            if ((cur_numiov + 1) > allocated) {
+                struct iovec *new_invec;
+
+                allocated = cur_numiov + 1;
+                new_invec = sasl_REALLOC (cur_invec, sizeof(struct iovec) * allocated);
+                if (new_invec == NULL) {
+                    if (cur_invec != NULL) {
+                        sasl_FREE(cur_invec);
+                    }
+                    MEMERROR(conn);
+                }
+                cur_invec = new_invec;
+            }
+
+            if (next_buf != NULL) {
+                cur_invec[0].iov_base = next_buf;
+                cur_invec[0].iov_len = remainder_len;
+                cur_numiov++;
+                index_offset = 1;
+            } else {
+                index_offset = 0;
+            }
+
+            if (i > 0) {
+                /* Copy all previous chunks */
+                /* NOTE - The starting index in invec is always 0 */
+                for (j = 0; j < i; j++) {
+                    cur_invec[j + index_offset] = invec[j];
+                }
+            }
+
+            /* Initialize the last record */
+            cur_invec[i + index_offset] = last_invec;
+
+            result = _sasl_encodev (conn,
+                                   cur_invec,
+                                    cur_numiov,
+                                    &num_packets,
+                                   output,
+                                    outputlen);
+
+            if (result != SASL_OK) {
+                goto cleanup;
+            }
+
+            /* Point to the first byte that wouldn't fit into
+               the conn->oparams.maxoutbuf buffer. */
+            /* Note, if next_buf points to the very end of the IOV record,
+               it will be reset to NULL below */
+            next_buf = last_invec.iov_base + last_invec.iov_len;
+            /* Note - remainder_len is how many bytes left to be encoded in
+               the current IOV slot. */
+            remainder_len = (total_size + invec[i].iov_len) - conn->oparams.maxoutbuf;
+
+            /* Skip all consumed IOV records */
+            invec += i + 1;
+            numiov = numiov - (i + 1);
+            i = 0;
+
+            while (remainder_len > conn->oparams.maxoutbuf) {
+                last_invec.iov_base = next_buf;
+                last_invec.iov_len = conn->oparams.maxoutbuf;
+
+                /* Note, if next_buf points to the very end of the IOV record,
+                   it will be reset to NULL below */
+                next_buf = last_invec.iov_base + last_invec.iov_len;
+                remainder_len = remainder_len - conn->oparams.maxoutbuf;
+
+                result = _sasl_encodev (conn,
+                                       &last_invec,
+                                        1,
+                                        &num_packets,
+                                       output,
+                                        outputlen);
+                if (result != SASL_OK) {
+                    goto cleanup;
+                }
+            }
+
+           total_size = remainder_len;
+
+            if (remainder_len == 0) {
+                /* Just clear next_buf */
+                next_buf = NULL;
+            }
+        } else {
+           total_size += invec[i].iov_len;
+            i++;
+        }
+    }
+
+    /* CLAIM - The remaining data is shorter then conn->oparams.maxoutbuf. */
+
+    /* Force encoding of any partial buffer. Might not be optimal on the wire. */
+    if (next_buf != NULL) {
+        last_invec.iov_base = next_buf;
+        last_invec.iov_len = remainder_len;
+
+        result = _sasl_encodev (conn,
+                               &last_invec,
+                                1,
+                                &num_packets,
+                               output,
+                                outputlen);
+
+        if (result != SASL_OK) {
+            goto cleanup;
+        }
+    }
+
+    if (numiov > 0) {
+        result = _sasl_encodev (conn,
+                               invec,
+                                numiov,
+                                &num_packets,
+                               output,
+                                outputlen);
+    }
+
+cleanup:
+    if (cur_invec != NULL) {
+        sasl_FREE(cur_invec);
+    }
+
+    RETURN(conn, result);
+}
+/* output is only valid until next call to sasl_decode */
+int sasl_decode(sasl_conn_t *conn,
+               const char *input, unsigned inputlen,
+               const char **output, unsigned *outputlen)
+{
+    int result;
+
+    if(!conn) return SASL_BADPARAM;
+    if(!input || !output || !outputlen)
+       PARAMERROR(conn);
+
+    if(!conn->props.maxbufsize) {
+       sasl_seterror(conn, 0,
+                     "called sasl_decode with application that does not support security layers");
+       RETURN(conn, SASL_TOOWEAK);
+    }
+
+    if(conn->oparams.decode == NULL)
+    {
+       /* Since we know how long the output is maximally, we can
+        * just allocate it to begin with, and never need another
+         * allocation! */
+
+       /* However, if they pass us more than they actually can take,
+        * we cannot help them... */
+       if(inputlen > conn->props.maxbufsize) {
+           sasl_seterror(conn, 0,
+                         "input too large for default sasl_decode");
+           RETURN(conn,SASL_BUFOVER);
+       }
+
+       if(!conn->decode_buf)
+           conn->decode_buf = sasl_ALLOC(conn->props.maxbufsize + 1);
+       if(!conn->decode_buf)   
+           MEMERROR(conn);
+       
+       memcpy(conn->decode_buf, input, inputlen);
+       conn->decode_buf[inputlen] = '\0';
+       *output = conn->decode_buf;
+       *outputlen = inputlen;
+       
+        return SASL_OK;
+    } else {
+        result = conn->oparams.decode(conn->context, input, inputlen,
+                                      output, outputlen);
+
+       /* NULL an empty buffer (for misbehaved applications) */
+       if (*outputlen == 0) *output = NULL;
+
+        RETURN(conn, result);
+    }
+
+    INTERROR(conn, SASL_FAIL);
+}
+
+
+void
+sasl_set_alloc(sasl_malloc_t *m,
+              sasl_calloc_t *c,
+              sasl_realloc_t *r,
+              sasl_free_t *f)
+{
+  _sasl_allocation_utils.malloc=m;
+  _sasl_allocation_utils.calloc=c;
+  _sasl_allocation_utils.realloc=r;
+  _sasl_allocation_utils.free=f;
+}
+
+void sasl_done(void)
+{
+    if (_sasl_server_cleanup_hook && _sasl_server_cleanup_hook() == SASL_OK) {
+       _sasl_server_idle_hook = NULL;
+       _sasl_server_cleanup_hook = NULL;
+    }
+    
+    if (_sasl_client_cleanup_hook && _sasl_client_cleanup_hook() == SASL_OK) {
+       _sasl_client_idle_hook = NULL;  
+       _sasl_client_cleanup_hook = NULL;
+    }
+    
+    if (_sasl_server_cleanup_hook || _sasl_client_cleanup_hook) {
+       return;
+    }
+
+    /* NOTE - the caller will need to reinitialize the values,
+       if it is going to call sasl_client_init/sasl_server_init again. */
+    if (default_plugin_path != NULL) {
+       sasl_FREE (default_plugin_path);
+       default_plugin_path = NULL;
+    }
+    if (default_conf_path != NULL) {
+       sasl_FREE (default_conf_path);
+       default_conf_path = NULL;
+    }
+
+    _sasl_canonuser_free();
+    _sasl_done_with_plugins();
+    
+    sasl_MUTEX_FREE(free_mutex);
+    free_mutex = NULL;
+    
+    _sasl_free_utils(&sasl_global_utils);
+    
+    if(global_mech_list) sasl_FREE(global_mech_list);
+    global_mech_list = NULL;
+}
+
+/* fills in the base sasl_conn_t info */
+int _sasl_conn_init(sasl_conn_t *conn,
+                   const char *service,
+                   unsigned int flags,
+                   enum Sasl_conn_type type,
+                   int (*idle_hook)(sasl_conn_t *conn),
+                   const char *serverFQDN,
+                   const char *iplocalport,
+                   const char *ipremoteport,
+                   const sasl_callback_t *callbacks,
+                   const sasl_global_callbacks_t *global_callbacks) {
+  int result = SASL_OK;
+
+  conn->type = type;
+
+  result = _sasl_strdup(service, &conn->service, NULL);
+  if (result != SASL_OK) 
+      MEMERROR(conn);
+
+  memset(&conn->oparams, 0, sizeof(sasl_out_params_t));
+  memset(&conn->external, 0, sizeof(_sasl_external_properties_t));
+
+  conn->flags = flags;
+
+  result = sasl_setprop(conn, SASL_IPLOCALPORT, iplocalport);
+  if(result != SASL_OK)
+      RETURN(conn, result);
+  
+  result = sasl_setprop(conn, SASL_IPREMOTEPORT, ipremoteport);
+  if(result != SASL_OK)
+      RETURN(conn, result);
+  
+  conn->encode_buf = NULL;
+  conn->context = NULL;
+  conn->secret = NULL;
+  conn->idle_hook = idle_hook;
+  conn->callbacks = callbacks;
+  conn->global_callbacks = global_callbacks;
+
+  memset(&conn->props, 0, sizeof(conn->props));
+
+  /* Start this buffer out as an empty string */
+  conn->error_code = SASL_OK;
+  conn->errdetail_buf = conn->error_buf = NULL;
+  conn->errdetail_buf_len = conn->error_buf_len = 150;
+
+  result = _buf_alloc(&conn->error_buf, &conn->error_buf_len, 150);     
+  if(result != SASL_OK) MEMERROR(conn);
+  result = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, 150);
+  if(result != SASL_OK) MEMERROR(conn);
+  
+  conn->error_buf[0] = '\0';
+  conn->errdetail_buf[0] = '\0';
+  
+  conn->decode_buf = NULL;
+
+  if(serverFQDN) {
+      result = _sasl_strdup(serverFQDN, &conn->serverFQDN, NULL);
+  } else if (conn->type == SASL_CONN_SERVER) {
+      /* We can fake it because we *are* the server */
+      char name[MAXHOSTNAMELEN];
+      memset(name, 0, sizeof(name));
+      gethostname(name, MAXHOSTNAMELEN);
+      
+      result = _sasl_strdup(name, &conn->serverFQDN, NULL);
+  } else {
+      conn->serverFQDN = NULL;
+  }
+  
+
+  if(result != SASL_OK) MEMERROR( conn );
+
+  RETURN(conn, SASL_OK);
+}
+
+int _sasl_common_init(sasl_global_callbacks_t *global_callbacks)
+{
+    int result;
+    
+    /* Setup the global utilities */
+    if(!sasl_global_utils) {
+       sasl_global_utils = _sasl_alloc_utils(NULL, global_callbacks);
+       if(sasl_global_utils == NULL) return SASL_NOMEM;
+    }
+
+    /* Init the canon_user plugin */
+    result = sasl_canonuser_add_plugin("INTERNAL", internal_canonuser_init);
+    if(result != SASL_OK) return result;    
+
+    if (!free_mutex)
+       free_mutex = sasl_MUTEX_ALLOC();
+    if (!free_mutex) return SASL_FAIL;
+
+    return SASL_OK;
+}
+
+/* dispose connection state, sets it to NULL
+ *  checks for pointer to NULL
+ */
+void sasl_dispose(sasl_conn_t **pconn)
+{
+  int result;
+
+  if (! pconn) return;
+  if (! *pconn) return;
+
+  /* serialize disposes. this is necessary because we can't
+     dispose of conn->mutex if someone else is locked on it */
+  result = sasl_MUTEX_LOCK(free_mutex);
+  if (result!=SASL_OK) return;
+  
+  /* *pconn might have become NULL by now */
+  if (! (*pconn)) return;
+
+  (*pconn)->destroy_conn(*pconn);
+  sasl_FREE(*pconn);
+  *pconn=NULL;
+
+  sasl_MUTEX_UNLOCK(free_mutex);
+}
+
+void _sasl_conn_dispose(sasl_conn_t *conn) {
+  if (conn->serverFQDN)
+      sasl_FREE(conn->serverFQDN);
+
+  if (conn->external.auth_id)
+      sasl_FREE(conn->external.auth_id);
+
+  if(conn->encode_buf) {
+      if(conn->encode_buf->data) sasl_FREE(conn->encode_buf->data);
+      sasl_FREE(conn->encode_buf);
+  }
+
+  if(conn->error_buf)
+      sasl_FREE(conn->error_buf);
+  
+  if(conn->errdetail_buf)
+      sasl_FREE(conn->errdetail_buf);
+
+  if(conn->decode_buf)
+      sasl_FREE(conn->decode_buf);
+
+  if(conn->mechlist_buf)
+      sasl_FREE(conn->mechlist_buf);
+
+  if(conn->service)
+      sasl_FREE(conn->service);
+
+  if (conn->multipacket_encoded_data.data) {
+      sasl_FREE(conn->multipacket_encoded_data.data);
+  }
+
+  /* oparams sub-members should be freed by the plugin, in so much
+   * as they were allocated by the plugin */
+}
+
+
+/* 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
+ */
+int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
+{
+  int result = SASL_OK;
+  sasl_getopt_t *getopt;
+  void *context;
+  
+  if (! conn) return SASL_BADPARAM;
+  if (! pvalue) PARAMERROR(conn);
+
+  switch(propnum)
+  {
+  case SASL_SSF:
+      *(sasl_ssf_t **)pvalue= &conn->oparams.mech_ssf;
+      break;      
+  case SASL_MAXOUTBUF:
+      *(unsigned **)pvalue = &conn->oparams.maxoutbuf;
+      break;
+  case SASL_GETOPTCTX:
+      result = _sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context);
+      if(result != SASL_OK) break;
+      
+      *(void **)pvalue = context;
+      break;
+  case SASL_CALLBACK:
+      *(const sasl_callback_t **)pvalue = conn->callbacks;
+      break;
+  case SASL_IPLOCALPORT:
+      if(conn->got_ip_local)
+         *(const char **)pvalue = conn->iplocalport;
+      else {
+         *(const char **)pvalue = NULL;
+         result = SASL_NOTDONE;
+      }
+      break;
+  case SASL_IPREMOTEPORT:
+      if(conn->got_ip_remote)
+         *(const char **)pvalue = conn->ipremoteport;
+      else {
+         *(const char **)pvalue = NULL;
+         result = SASL_NOTDONE;
+      }          
+      break;
+  case SASL_USERNAME:
+      if(! conn->oparams.user)
+         result = SASL_NOTDONE;
+      else
+         *((const char **)pvalue) = conn->oparams.user;
+      break;
+  case SASL_AUTHUSER:
+      if(! conn->oparams.authid)
+         result = SASL_NOTDONE;
+      else
+         *((const char **)pvalue) = conn->oparams.authid;
+      break;
+  case SASL_APPNAME:
+      /* Currently we only support server side contexts, but we should
+         be able to extend this to support client side contexts as well */
+      if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT;
+      else
+         *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->sparams->appname;
+      break;
+  case SASL_SERVERFQDN:
+      *((const char **)pvalue) = conn->serverFQDN;
+      break;
+  case SASL_DEFUSERREALM:
+      if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT;
+      else
+         *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->user_realm;
+      break;
+  case SASL_SERVICE:
+      *((const char **)pvalue) = conn->service;
+      break;
+  case SASL_AUTHSOURCE: /* name of plugin (not name of mech) */
+      if(conn->type == SASL_CONN_CLIENT) {
+         if(!((sasl_client_conn_t *)conn)->mech) {
+             result = SASL_NOTDONE;
+             break;
+         }
+         *((const char **)pvalue) =
+             ((sasl_client_conn_t *)conn)->mech->m.plugname;
+      } else if (conn->type == SASL_CONN_SERVER) {
+         if(!((sasl_server_conn_t *)conn)->mech) {
+             result = SASL_NOTDONE;
+             break;
+         }
+         *((const char **)pvalue) =
+             ((sasl_server_conn_t *)conn)->mech->m.plugname;
+      } else {
+         result = SASL_BADPARAM;
+      }
+      break;
+  case SASL_MECHNAME: /* name of mech */
+      if(conn->type == SASL_CONN_CLIENT) {
+         if(!((sasl_client_conn_t *)conn)->mech) {
+             result = SASL_NOTDONE;
+             break;
+         }
+         *((const char **)pvalue) =
+             ((sasl_client_conn_t *)conn)->mech->m.plug->mech_name;
+      } else if (conn->type == SASL_CONN_SERVER) {
+         if(!((sasl_server_conn_t *)conn)->mech) {
+             result = SASL_NOTDONE;
+             break;
+         }
+         *((const char **)pvalue) =
+             ((sasl_server_conn_t *)conn)->mech->m.plug->mech_name;
+      } else {
+         result = SASL_BADPARAM;
+      }
+      
+      if(!(*pvalue) && result == SASL_OK) result = SASL_NOTDONE;
+      break;
+  case SASL_PLUGERR:
+      *((const char **)pvalue) = conn->error_buf;
+      break;
+  case SASL_DELEGATEDCREDS:
+      /* We can't really distinguish between "no delegated credentials"
+         and "authentication not finished" */
+      if(! conn->oparams.client_creds)
+         result = SASL_NOTDONE;
+      else
+         *((const char **)pvalue) = conn->oparams.client_creds;
+      break;
+  case SASL_SSF_EXTERNAL:
+      *((const sasl_ssf_t **)pvalue) = &conn->external.ssf;
+      break;
+  case SASL_AUTH_EXTERNAL:
+      *((const char **)pvalue) = conn->external.auth_id;
+      break;
+  case SASL_SEC_PROPS:
+      *((const sasl_security_properties_t **)pvalue) = &conn->props;
+      break;
+  default: 
+      result = SASL_BADPARAM;
+  }
+
+  if(result == SASL_BADPARAM) {
+      PARAMERROR(conn);
+  } else if(result == SASL_NOTDONE) {
+      sasl_seterror(conn, SASL_NOLOG,
+                   "Information that was requested is not yet available.");
+      RETURN(conn, result);
+  } else if(result != SASL_OK) {
+      INTERROR(conn, result);
+  } else
+      RETURN(conn, result); 
+}
+
+/* set property in SASL connection state
+ * returns:
+ *  SASL_OK       -- value set
+ *  SASL_BADPARAM -- invalid property or value
+ */
+int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value)
+{
+  int result = SASL_OK;
+  char *str;
+
+  /* make sure the sasl context is valid */
+  if (!conn)
+    return SASL_BADPARAM;
+
+  switch(propnum)
+  {
+  case SASL_SSF_EXTERNAL:
+      conn->external.ssf = *((sasl_ssf_t *)value);
+      if(conn->type == SASL_CONN_SERVER) {
+       ((sasl_server_conn_t*)conn)->sparams->external_ssf =
+         conn->external.ssf;
+      } else {
+       ((sasl_client_conn_t*)conn)->cparams->external_ssf =
+         conn->external.ssf;
+      }
+      break;
+
+  case SASL_AUTH_EXTERNAL:
+      if(value && strlen(value)) {
+         result = _sasl_strdup(value, &str, NULL);
+         if(result != SASL_OK) MEMERROR(conn);
+      } else {
+         str = NULL;
+      }
+
+      if(conn->external.auth_id)
+         sasl_FREE(conn->external.auth_id);
+
+      conn->external.auth_id = str;
+
+      break;
+
+  case SASL_DEFUSERREALM:
+      if(conn->type != SASL_CONN_SERVER) {
+       sasl_seterror(conn, 0, "Tried to set realm on non-server connection");
+       result = SASL_BADPROT;
+       break;
+      }
+
+      if(value && strlen(value)) {
+         result = _sasl_strdup(value, &str, NULL);
+         if(result != SASL_OK) MEMERROR(conn);
+      } else {
+         PARAMERROR(conn);
+      }
+
+      if(((sasl_server_conn_t *)conn)->user_realm)
+         sasl_FREE(((sasl_server_conn_t *)conn)->user_realm);
+
+      ((sasl_server_conn_t *)conn)->user_realm = str;
+      ((sasl_server_conn_t *)conn)->sparams->user_realm = str;
+
+      break;
+
+  case SASL_SEC_PROPS:
+  {
+      sasl_security_properties_t *props = (sasl_security_properties_t *)value;
+
+      if(props->maxbufsize == 0 && props->min_ssf != 0) {
+         sasl_seterror(conn, 0,
+                       "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0");
+         RETURN(conn, SASL_TOOWEAK);
+      }
+
+      conn->props = *props;
+
+      if(conn->type == SASL_CONN_SERVER) {
+       ((sasl_server_conn_t*)conn)->sparams->props = *props;
+      } else {
+       ((sasl_client_conn_t*)conn)->cparams->props = *props;
+      }
+
+      break;
+  }
+      
+  case SASL_IPREMOTEPORT:
+  {
+      const char *ipremoteport = (const char *)value;
+      if(!value) {
+         conn->got_ip_remote = 0; 
+      } else if (_sasl_ipfromstring(ipremoteport, NULL, 0)
+                != SASL_OK) {
+         sasl_seterror(conn, 0, "Bad IPREMOTEPORT value");
+         RETURN(conn, SASL_BADPARAM);
+      } else {
+         strcpy(conn->ipremoteport, ipremoteport);
+         conn->got_ip_remote = 1;
+      }
+      
+      if(conn->got_ip_remote) {
+         if(conn->type == SASL_CONN_CLIENT) {
+             ((sasl_client_conn_t *)conn)->cparams->ipremoteport
+                 = conn->ipremoteport;
+             ((sasl_client_conn_t *)conn)->cparams->ipremlen =
+                 (unsigned) strlen(conn->ipremoteport);
+         } else if (conn->type == SASL_CONN_SERVER) {
+             ((sasl_server_conn_t *)conn)->sparams->ipremoteport
+                 = conn->ipremoteport;
+             ((sasl_server_conn_t *)conn)->sparams->ipremlen =
+                 (unsigned) strlen(conn->ipremoteport);
+         }
+      } else {
+         if(conn->type == SASL_CONN_CLIENT) {
+             ((sasl_client_conn_t *)conn)->cparams->ipremoteport
+                 = NULL;
+             ((sasl_client_conn_t *)conn)->cparams->ipremlen = 0;
+         } else if (conn->type == SASL_CONN_SERVER) {
+             ((sasl_server_conn_t *)conn)->sparams->ipremoteport
+                 = NULL;             
+             ((sasl_server_conn_t *)conn)->sparams->ipremlen = 0;
+         }
+      }
+
+      break;
+  }
+
+  case SASL_IPLOCALPORT:
+  {
+      const char *iplocalport = (const char *)value;
+      if(!value) {
+         conn->got_ip_local = 0;         
+      } else if (_sasl_ipfromstring(iplocalport, NULL, 0)
+                != SASL_OK) {
+         sasl_seterror(conn, 0, "Bad IPLOCALPORT value");
+         RETURN(conn, SASL_BADPARAM);
+      } else {
+         strcpy(conn->iplocalport, iplocalport);
+         conn->got_ip_local = 1;
+      }
+
+      if(conn->got_ip_local) {
+         if(conn->type == SASL_CONN_CLIENT) {
+             ((sasl_client_conn_t *)conn)->cparams->iplocalport
+                 = conn->iplocalport;
+             ((sasl_client_conn_t *)conn)->cparams->iploclen
+                 = (unsigned) strlen(conn->iplocalport);
+         } else if (conn->type == SASL_CONN_SERVER) {
+             ((sasl_server_conn_t *)conn)->sparams->iplocalport
+                 = conn->iplocalport;
+             ((sasl_server_conn_t *)conn)->sparams->iploclen
+                 = (unsigned) strlen(conn->iplocalport);
+         }
+      } else {
+         if(conn->type == SASL_CONN_CLIENT) {
+             ((sasl_client_conn_t *)conn)->cparams->iplocalport
+                 = NULL;
+             ((sasl_client_conn_t *)conn)->cparams->iploclen = 0;
+         } else if (conn->type == SASL_CONN_SERVER) {
+             ((sasl_server_conn_t *)conn)->sparams->iplocalport
+                 = NULL;
+             ((sasl_server_conn_t *)conn)->sparams->iploclen = 0;
+         }
+      }
+      break;
+  }
+
+  case SASL_APPNAME:
+      /* Currently we only support server side contexts, but we should
+         be able to extend this to support client side contexts as well */
+      if(conn->type != SASL_CONN_SERVER) {
+       sasl_seterror(conn, 0, "Tried to set application name on non-server connection");
+       result = SASL_BADPROT;
+       break;
+      }
+
+      if(((sasl_server_conn_t *)conn)->appname) {
+         sasl_FREE(((sasl_server_conn_t *)conn)->appname);
+         ((sasl_server_conn_t *)conn)->appname = NULL;
+      }
+
+      if(value && strlen(value)) {
+         result = _sasl_strdup(value,
+                               &(((sasl_server_conn_t *)conn)->appname),
+                               NULL);
+         if(result != SASL_OK) MEMERROR(conn);
+         ((sasl_server_conn_t *)conn)->sparams->appname =
+              ((sasl_server_conn_t *)conn)->appname;
+         ((sasl_server_conn_t *)conn)->sparams->applen =
+             (unsigned) strlen(((sasl_server_conn_t *)conn)->appname);
+      } else {
+         ((sasl_server_conn_t *)conn)->sparams->appname = NULL;
+         ((sasl_server_conn_t *)conn)->sparams->applen = 0;
+      }
+      break;
+
+  default:
+      sasl_seterror(conn, 0, "Unknown parameter type");
+      result = SASL_BADPARAM;
+  }
+  
+  RETURN(conn, result);
+}
+
+/* this is apparently no longer a user function */
+static int sasl_usererr(int saslerr)
+{
+    /* Hide the difference in a username failure and a password failure */
+    if (saslerr == SASL_NOUSER)
+       return SASL_BADAUTH;
+
+    /* otherwise return the error given; no transform necessary */
+    return saslerr;
+}
+
+const char *sasl_errstring(int saslerr,
+                          const char *langlist __attribute__((unused)),
+                          const char **outlang)
+{
+  if (outlang) *outlang="en-us";
+
+  switch(saslerr)
+    {
+    case SASL_CONTINUE: return "another step is needed in authentication";
+    case SASL_OK:       return "successful result";
+    case SASL_FAIL:     return "generic failure";
+    case SASL_NOMEM:    return "no memory available";
+    case SASL_BUFOVER:  return "overflowed buffer";
+    case SASL_NOMECH:   return "no mechanism available";
+    case SASL_BADPROT:  return "bad protocol / cancel";
+    case SASL_NOTDONE:  return "can't request info until later in exchange";
+    case SASL_BADPARAM: return "invalid parameter supplied";
+    case SASL_TRYAGAIN: return "transient failure (e.g., weak key)";
+    case SASL_BADMAC:   return "integrity check failed";
+    case SASL_NOTINIT:  return "SASL library not initialized";
+                             /* -- client only codes -- */
+    case SASL_INTERACT:   return "needs user interaction";
+    case SASL_BADSERV:    return "server failed mutual authentication step";
+    case SASL_WRONGMECH:  return "mechanism doesn't support requested feature";
+                             /* -- server only codes -- */
+    case SASL_BADAUTH:    return "authentication failure";
+    case SASL_NOAUTHZ:    return "authorization failure";
+    case SASL_TOOWEAK:    return "mechanism too weak for this user";
+    case SASL_ENCRYPT:    return "encryption needed to use mechanism";
+    case SASL_TRANS:      return "One time use of a plaintext password will enable requested mechanism for user";
+    case SASL_EXPIRED:    return "passphrase expired, has to be reset";
+    case SASL_DISABLED:   return "account disabled";
+    case SASL_NOUSER:     return "user not found";
+    case SASL_BADVERS:    return "version mismatch with plug-in";
+    case SASL_UNAVAIL:    return "remote authentication server unavailable";
+    case SASL_NOVERIFY:   return "user exists, but no verifier for user";
+    case SASL_PWLOCK:     return "passphrase locked";
+    case SASL_NOCHANGE:   return "requested change was not needed";
+    case SASL_WEAKPASS:   return "passphrase is too weak for security policy";
+    case SASL_NOUSERPASS: return "user supplied passwords are not permitted";
+
+    default:   return "undefined error!";
+    }
+
+}
+
+/* Return the sanitized error detail about the last error that occured for 
+ * a connection */
+const char *sasl_errdetail(sasl_conn_t *conn) 
+{
+    unsigned need_len;
+    const char *errstr;
+    char leader[128];
+
+    if(!conn) return NULL;
+    
+    errstr = sasl_errstring(conn->error_code, NULL, NULL);
+    snprintf(leader,128,"SASL(%d): %s: ",
+            sasl_usererr(conn->error_code), errstr);
+    
+    need_len = (unsigned) (strlen(leader) + strlen(conn->error_buf) + 12);
+    _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len);
+
+    snprintf(conn->errdetail_buf, need_len, "%s%s", leader, conn->error_buf);
+   
+    return conn->errdetail_buf;
+}
+
+
+/* Note that this needs the global callbacks, so if you don't give getcallbacks
+ * a sasl_conn_t, you're going to need to pass it yourself (or else we couldn't
+ * have client and server at the same time */
+static int _sasl_global_getopt(void *context,
+                              const char *plugin_name,
+                              const char *option,
+                              const char ** result,
+                              unsigned *len)
+{
+  const sasl_global_callbacks_t * global_callbacks;
+  const sasl_callback_t *callback;
+
+  global_callbacks = (const sasl_global_callbacks_t *) context;
+
+  if (global_callbacks && global_callbacks->callbacks) {
+      for (callback = global_callbacks->callbacks;
+          callback->id != SASL_CB_LIST_END;
+          callback++) {
+       if (callback->id == SASL_CB_GETOPT) {
+         if (!callback->proc) return SASL_FAIL;
+         if (((sasl_getopt_t *)(callback->proc))(callback->context,
+                                                 plugin_name,
+                                                 option,
+                                                 result,
+                                                 len)
+             == SASL_OK)
+           return SASL_OK;
+       }
+      }
+  }
+  
+  /* look it up in our configuration file */
+  *result = sasl_config_getstring(option, NULL);
+  if (*result != NULL) {
+      if (len) { *len = (unsigned) strlen(*result); }
+      return SASL_OK;
+  }
+
+  return SASL_FAIL;
+}
+
+static int
+_sasl_conn_getopt(void *context,
+                 const char *plugin_name,
+                 const char *option,
+                 const char ** result,
+                 unsigned *len)
+{
+  sasl_conn_t * conn;
+  const sasl_callback_t *callback;
+
+  if (! context)
+    return SASL_BADPARAM;
+
+  conn = (sasl_conn_t *) context;
+
+  if (conn->callbacks)
+    for (callback = conn->callbacks;
+        callback->id != SASL_CB_LIST_END;
+        callback++)
+      if (callback->id == SASL_CB_GETOPT
+         && (((sasl_getopt_t *)(callback->proc))(callback->context,
+                                                 plugin_name,
+                                                 option,
+                                                 result,
+                                                 len)
+             == SASL_OK))
+       return SASL_OK;
+
+  /* If we made it here, we didn't find an appropriate callback
+   * in the connection's callback list, or the callback we did
+   * find didn't return SASL_OK.  So we attempt to use the
+   * global callback for this connection... */
+  return _sasl_global_getopt((void *)conn->global_callbacks,
+                            plugin_name,
+                            option,
+                            result,
+                            len);
+}
+
+#ifdef HAVE_SYSLOG
+/* this is the default logging */
+static int _sasl_syslog(void *context,
+                       int priority,
+                       const char *message)
+{
+    int syslog_priority;
+    sasl_server_conn_t *sconn;
+
+    if (context) {
+       if (((sasl_conn_t *)context)->type == SASL_CONN_SERVER) {
+           sconn = (sasl_server_conn_t *)context;
+           if (sconn->sparams->log_level < priority) 
+               return SASL_OK;
+       }
+    }
+
+    /* set syslog priority */
+    switch(priority) {
+    case SASL_LOG_NONE:
+       return SASL_OK;
+       break;
+    case SASL_LOG_ERR:
+       syslog_priority = LOG_ERR;
+       break;
+    case SASL_LOG_WARN:
+       syslog_priority = LOG_WARNING;
+       break;
+    case SASL_LOG_NOTE:
+    case SASL_LOG_FAIL:
+       syslog_priority = LOG_NOTICE;
+       break;
+    case SASL_LOG_PASS:
+    case SASL_LOG_TRACE:
+    case SASL_LOG_DEBUG:
+    default:
+       syslog_priority = LOG_DEBUG;
+       break;
+    }
+    
+    /* do the syslog call. Do not need to call openlog? */
+    syslog(syslog_priority | LOG_AUTH, "%s", message);
+    
+    return SASL_OK;
+}
+#endif                         /* HAVE_SYSLOG */
+
+static int
+_sasl_getsimple(void *context,
+               int id,
+               const char ** result,
+               size_t *len)
+{
+  const char *userid;
+  sasl_conn_t *conn;
+
+  if (! context || ! result) return SASL_BADPARAM;
+
+  conn = (sasl_conn_t *)context;
+
+  switch(id) {
+  case SASL_CB_AUTHNAME:
+    userid = getenv("USER");
+    if (userid != NULL) {
+       *result = userid;
+       if (len) *len = strlen(userid);
+       return SASL_OK;
+    }
+    userid = getenv("USERNAME");
+    if (userid != NULL) {
+       *result = userid;
+       if (len) *len = strlen(userid);
+       return SASL_OK;
+    }
+#ifdef WIN32
+    /* for win32, try using the GetUserName standard call */
+    {
+       DWORD i;
+       BOOL rval;
+       static char sender[128];
+       
+       i = sizeof(sender);
+       rval = GetUserName(sender, &i);
+       if ( rval) { /* got a userid */
+               *result = sender;
+               if (len) *len = strlen(sender);
+               return SASL_OK;
+       }
+    }
+#endif /* WIN32 */
+    return SASL_FAIL;
+  default:
+    return SASL_BADPARAM;
+  }
+}
+
+static int
+_sasl_getpath(void *context __attribute__((unused)),
+              const char ** path_dest)
+{
+#if !defined(WIN32)
+    char *path;
+#endif
+    int res = SASL_OK;
+
+    if (! path_dest) {
+        return SASL_BADPARAM;
+    }
+
+    /* Only calculate the path once. */
+    if (default_plugin_path == NULL) {
+
+#if defined(WIN32)
+        /* NB: On Windows platforms this value is always allocated */
+        default_plugin_path = _sasl_get_default_win_path(context,
+                                                         SASL_PLUGIN_PATH_ATTR,
+                                                         PLUGINDIR);
+#else
+        /* NB: On Unix platforms this value is never allocated */
+        path = _sasl_get_default_unix_path(context,
+                                           SASL_PATH_ENV_VAR,
+                                           PLUGINDIR);
+
+        res = _sasl_strdup(path, &default_plugin_path, NULL);
+#endif
+    }
+
+    if (res == SASL_OK) {
+        *path_dest = default_plugin_path;
+    }
+
+    return res;
+}
+
+static int
+_sasl_getpath_simple(void *context __attribute__((unused)),
+                     const char **path)
+{
+    if (! path) {
+        return SASL_BADPARAM;
+    }
+
+    if (default_plugin_path == NULL) {
+        return SASL_FAIL;
+    }
+
+    *path = default_plugin_path;
+
+    return SASL_OK;
+}
+
+static int
+_sasl_getconfpath(void *context __attribute__((unused)),
+                  char ** path_dest)
+{
+#if !defined(WIN32)
+    char *path;
+#endif
+    int res = SASL_OK;
+
+    if (! path_dest) {
+        return SASL_BADPARAM;
+    }
+
+  /* Only calculate the path once. */
+    if (default_conf_path == NULL) {
+
+#if defined(WIN32)
+        /* NB: On Windows platforms this value is always allocated */
+        default_conf_path = _sasl_get_default_win_path(context,
+                                                       SASL_CONF_PATH_ATTR,
+                                                       CONFIGDIR);
+#else
+        /* NB: On Unix platforms this value is never allocated */
+        path = _sasl_get_default_unix_path(context,
+                                           SASL_CONF_PATH_ENV_VAR,
+                                           CONFIGDIR);
+
+        res = _sasl_strdup(path, &default_conf_path, NULL);
+#endif
+    }
+
+    if (res == SASL_OK) {
+        *path_dest = default_conf_path;
+    }
+
+    return res;
+}
+
+static int
+_sasl_getconfpath_simple(void *context __attribute__((unused)),
+                         const char **path)
+{
+    if (! path) {
+        return SASL_BADPARAM;
+    }
+
+    if (default_conf_path == NULL) {
+        return SASL_FAIL;
+    }
+
+    *path = default_conf_path;
+
+    return SASL_OK;
+}
+
+static int
+_sasl_verifyfile(void *context __attribute__((unused)),
+                char *file  __attribute__((unused)),
+                int type  __attribute__((unused)))
+{
+  /* always say ok */
+  return SASL_OK;
+}
+
+
+static int
+_sasl_proxy_policy(sasl_conn_t *conn,
+                  void *context __attribute__((unused)),
+                  const char *requested_user, unsigned rlen,
+                  const char *auth_identity, unsigned alen,
+                  const char *def_realm __attribute__((unused)),
+                  unsigned urlen __attribute__((unused)),
+                  struct propctx *propctx __attribute__((unused)))
+{
+    if (!conn)
+       return SASL_BADPARAM;
+
+    if (!requested_user || *requested_user == '\0')
+       return SASL_OK;
+
+    if (!auth_identity || !requested_user || rlen != alen ||
+       (memcmp(auth_identity, requested_user, rlen) != 0)) {
+       sasl_seterror(conn, 0,
+                     "Requested identity not authenticated identity");
+       RETURN(conn, SASL_BADAUTH);
+    }
+
+    return SASL_OK;
+}
+
+int _sasl_getcallback(sasl_conn_t * conn,
+                     unsigned long callbackid,
+                     int (**pproc)(),
+                     void **pcontext)
+{
+  const sasl_callback_t *callback;
+
+  if (!pproc || !pcontext)
+      PARAMERROR(conn);
+
+  /* Some callbacks are always provided by the library */
+  switch (callbackid) {
+  case SASL_CB_LIST_END:
+    /* Nothing ever gets to provide this */
+      INTERROR(conn, SASL_FAIL);
+  case SASL_CB_GETOPT:
+      if (conn) {
+         *pproc = &_sasl_conn_getopt;
+         *pcontext = conn;
+      } else {
+         *pproc = &_sasl_global_getopt;
+         *pcontext = NULL;
+      }
+      return SASL_OK;
+  }
+
+  /* If it's not always provided by the library, see if there's
+   * a version provided by the application for this connection... */
+  if (conn && conn->callbacks) {
+    for (callback = conn->callbacks; callback->id != SASL_CB_LIST_END;
+        callback++) {
+       if (callback->id == callbackid) {
+           *pproc = callback->proc;
+           *pcontext = callback->context;
+           if (callback->proc) {
+               return SASL_OK;
+           } else {
+               return SASL_INTERACT;
+           }
+       }
+    }
+  }
+
+  /* And, if not for this connection, see if there's one
+   * for all {server,client} connections... */
+  if (conn && conn->global_callbacks && conn->global_callbacks->callbacks) {
+      for (callback = conn->global_callbacks->callbacks;
+          callback->id != SASL_CB_LIST_END;
+          callback++) {
+         if (callback->id == callbackid) {
+             *pproc = callback->proc;
+             *pcontext = callback->context;
+             if (callback->proc) {
+                 return SASL_OK;
+             } else {
+                 return SASL_INTERACT;
+             }
+         }
+      }
+  }
+
+  /* Otherwise, see if the library provides a default callback. */
+  switch (callbackid) {
+#ifdef HAVE_SYSLOG
+  case SASL_CB_LOG:
+    *pproc = (int (*)()) &_sasl_syslog;
+    *pcontext = conn;
+    return SASL_OK;
+#endif /* HAVE_SYSLOG */
+  case SASL_CB_GETPATH:
+    *pproc = default_getpath_cb.proc;
+    *pcontext = default_getpath_cb.context;
+    return SASL_OK;
+  case SASL_CB_GETCONFPATH:
+    *pproc = default_getconfpath_cb.proc;
+    *pcontext = default_getconfpath_cb.context;
+    return SASL_OK;
+  case SASL_CB_AUTHNAME:
+    *pproc = (int (*)()) &_sasl_getsimple;
+    *pcontext = conn;
+    return SASL_OK;
+  case SASL_CB_VERIFYFILE:
+    *pproc = & _sasl_verifyfile;
+    *pcontext = NULL;
+    return SASL_OK;
+  case SASL_CB_PROXY_POLICY:
+    *pproc = (int (*)()) &_sasl_proxy_policy;
+    *pcontext = NULL;
+    return SASL_OK;
+  }
+
+  /* Unable to find a callback... */
+  *pproc = NULL;
+  *pcontext = NULL;
+  sasl_seterror(conn, SASL_NOLOG, "Unable to find a callback: %d", callbackid);
+  RETURN(conn,SASL_FAIL);
+}
+
+
+/*
+ * This function is typically called from a plugin.
+ * It creates a string from the formatting and varargs given
+ * and calls the logging callback (syslog by default)
+ *
+ * %m will parse the value in the next argument as an errno string
+ * %z will parse the next argument as a SASL error code.
+ */
+
+void
+_sasl_log (sasl_conn_t *conn,
+          int level,
+          const char *fmt,
+          ...)
+{
+  char *out=(char *) sasl_ALLOC(250);
+  size_t alloclen=100; /* current allocated length */
+  size_t outlen=0; /* current length of output buffer */
+  size_t formatlen;
+  size_t pos=0; /* current position in format string */
+  int result;
+  sasl_log_t *log_cb;
+  void *log_ctx;
+  
+  int ival;
+  unsigned int uval;
+  char *cval;
+  va_list ap; /* varargs thing */
+
+  if(!fmt) goto done;
+  if(!out) return;
+  
+  formatlen = strlen(fmt);
+
+  /* See if we have a logging callback... */
+  result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
+  if (result == SASL_OK && ! log_cb)
+    result = SASL_FAIL;
+  if (result != SASL_OK) goto done;
+  
+  va_start(ap, fmt); /* start varargs */
+
+  while(pos<formatlen)
+  {
+    if (fmt[pos]!='%') /* regular character */
+    {
+      result = _buf_alloc(&out, &alloclen, outlen+1);
+      if (result != SASL_OK) goto done;
+      out[outlen]=fmt[pos];
+      outlen++;
+      pos++;
+
+    } else { /* formating thing */
+      int done=0;
+      char frmt[10];
+      int frmtpos=1;
+      char tempbuf[21];
+      frmt[0]='%';
+      pos++;
+
+      while (done==0)
+      {
+       switch(fmt[pos])
+         {
+         case 's': /* need to handle this */
+           cval = va_arg(ap, char *); /* get the next arg */
+           result = _sasl_add_string(&out, &alloclen,
+                               &outlen, cval);
+             
+           if (result != SASL_OK) /* add the string */
+               goto done;
+
+           done=1;
+           break;
+
+         case '%': /* double % output the '%' character */
+           result = _buf_alloc(&out,&alloclen,outlen+1);
+           if (result != SASL_OK)
+               goto done;
+           
+           out[outlen]='%';
+           outlen++;
+           done=1;
+           break;
+
+         case 'm': /* insert the errno string */
+           result = _sasl_add_string(&out, &alloclen, &outlen,
+                               strerror(va_arg(ap, int)));
+           if (result != SASL_OK)
+               goto done;
+           
+           done=1;
+           break;
+
+         case 'z': /* insert the sasl error string */
+           result = _sasl_add_string(&out, &alloclen, &outlen,
+                               (char *) sasl_errstring(va_arg(ap, int),NULL,NULL));
+           if (result != SASL_OK)
+               goto done;
+           
+           done=1;
+           break;
+
+         case 'c':
+           frmt[frmtpos++]=fmt[pos];
+           frmt[frmtpos]=0;
+           tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
+           tempbuf[1]='\0';
+           
+           /* now add the character */
+           result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
+           if (result != SASL_OK)
+               goto done;
+               
+           done=1;
+           break;
+
+         case 'd':
+         case 'i':
+           frmt[frmtpos++]=fmt[pos];
+           frmt[frmtpos]=0;
+           ival = va_arg(ap, int); /* get the next arg */
+
+           snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
+           /* now add the string */
+           result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
+           if (result != SASL_OK)
+               goto done;
+
+           done=1;
+           break;
+
+         case 'o':
+         case 'u':
+         case 'x':
+         case 'X':
+           frmt[frmtpos++]=fmt[pos];
+           frmt[frmtpos]=0;
+           uval = va_arg(ap, unsigned int); /* get the next arg */
+
+           snprintf(tempbuf,20,frmt,uval); /* have snprintf do the work */
+           /* now add the string */
+           result = _sasl_add_string(&out, &alloclen, &outlen, tempbuf);
+           if (result != SASL_OK)
+               goto done;
+
+           done=1;
+           break;
+
+         default: 
+           frmt[frmtpos++]=fmt[pos]; /* add to the formating */
+           frmt[frmtpos]=0;        
+           if (frmtpos>9) 
+             done=1;
+         }
+       pos++;
+       if (pos>formatlen)
+         done=1;
+      }
+
+    }
+  }
+
+  /* put 0 at end */
+  result = _buf_alloc(&out, &alloclen, outlen+1);
+  if (result != SASL_OK) goto done;
+  out[outlen]=0;
+
+  va_end(ap);    
+
+  /* send log message */
+  result = log_cb(log_ctx, level, out);
+
+ done:
+  if(out) sasl_FREE(out);
+}
+
+
+
+/* Allocate and Init a sasl_utils_t structure */
+sasl_utils_t *
+_sasl_alloc_utils(sasl_conn_t *conn,
+                 sasl_global_callbacks_t *global_callbacks)
+{
+  sasl_utils_t *utils;
+  /* set util functions - need to do rest*/
+  utils=sasl_ALLOC(sizeof(sasl_utils_t));
+  if (utils==NULL)
+    return NULL;
+
+  utils->conn = conn;
+
+  sasl_randcreate(&utils->rpool);
+
+  if (conn) {
+    utils->getopt = &_sasl_conn_getopt;
+    utils->getopt_context = conn;
+  } else {
+    utils->getopt = &_sasl_global_getopt;
+    utils->getopt_context = global_callbacks;
+  }
+
+  utils->malloc=_sasl_allocation_utils.malloc;
+  utils->calloc=_sasl_allocation_utils.calloc;
+  utils->realloc=_sasl_allocation_utils.realloc;
+  utils->free=_sasl_allocation_utils.free;
+
+  utils->mutex_alloc = _sasl_mutex_utils.alloc;
+  utils->mutex_lock = _sasl_mutex_utils.lock;
+  utils->mutex_unlock = _sasl_mutex_utils.unlock;
+  utils->mutex_free = _sasl_mutex_utils.free;
+  
+  utils->MD5Init  = &_sasl_MD5Init;
+  utils->MD5Update= &_sasl_MD5Update;
+  utils->MD5Final = &_sasl_MD5Final;
+  utils->hmac_md5 = &_sasl_hmac_md5;
+  utils->hmac_md5_init = &_sasl_hmac_md5_init;
+  utils->hmac_md5_final = &_sasl_hmac_md5_final;
+  utils->hmac_md5_precalc = &_sasl_hmac_md5_precalc;
+  utils->hmac_md5_import = &_sasl_hmac_md5_import;
+  utils->mkchal = &sasl_mkchal;
+  utils->utf8verify = &sasl_utf8verify;
+  utils->rand=&sasl_rand;
+  utils->churn=&sasl_churn;  
+  utils->checkpass=NULL;
+  
+  utils->encode64=&sasl_encode64;
+  utils->decode64=&sasl_decode64;
+  
+  utils->erasebuffer=&sasl_erasebuffer;
+
+  utils->getprop=&sasl_getprop;
+  utils->setprop=&sasl_setprop;
+
+  utils->getcallback=&_sasl_getcallback;
+
+  utils->log=&_sasl_log;
+
+  utils->seterror=&sasl_seterror;
+
+#ifndef macintosh
+  /* Aux Property Utilities */
+  utils->prop_new=&prop_new;
+  utils->prop_dup=&prop_dup;
+  utils->prop_request=&prop_request;
+  utils->prop_get=&prop_get;
+  utils->prop_getnames=&prop_getnames;
+  utils->prop_clear=&prop_clear;
+  utils->prop_dispose=&prop_dispose;
+  utils->prop_format=&prop_format;
+  utils->prop_set=&prop_set;
+  utils->prop_setvals=&prop_setvals;
+  utils->prop_erase=&prop_erase;
+  utils->auxprop_store=&sasl_auxprop_store;
+#endif
+
+  /* Spares */
+  utils->spare_fptr = NULL;
+  utils->spare_fptr1 = utils->spare_fptr2 = NULL;
+  
+  return utils;
+}
+
+int
+_sasl_free_utils(const sasl_utils_t ** utils)
+{
+    sasl_utils_t *nonconst;
+
+    if(!utils) return SASL_BADPARAM;
+    if(!*utils) return SASL_OK;
+
+    /* I wish we could avoid this cast, it's pretty gratuitous but it
+     * does make life easier to have it const everywhere else. */
+    nonconst = (sasl_utils_t *)(*utils);
+
+    sasl_randfree(&(nonconst->rpool));
+    sasl_FREE(nonconst);
+
+    *utils = NULL;
+    return SASL_OK;
+}
+
+int sasl_idle(sasl_conn_t *conn)
+{
+  if (! conn) {
+    if (_sasl_server_idle_hook
+       && _sasl_server_idle_hook(NULL))
+      return 1;
+    if (_sasl_client_idle_hook
+       && _sasl_client_idle_hook(NULL))
+      return 1;
+    return 0;
+  }
+
+  if (conn->idle_hook)
+    return conn->idle_hook(conn);
+
+  return 0;
+}
+
+static const sasl_callback_t *
+_sasl_find_callback_by_type (const sasl_callback_t *callbacks,
+                             unsigned long id)
+{
+    if (callbacks) {
+        while (callbacks->id != SASL_CB_LIST_END) {
+            if (callbacks->id == id) {
+               return callbacks;
+            } else {
+               ++callbacks;
+            }
+        }
+    }
+    return NULL;
+}
+
+const sasl_callback_t *
+_sasl_find_getpath_callback(const sasl_callback_t *callbacks)
+{
+  callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_GETPATH);
+  if (callbacks != NULL) {
+    return callbacks;
+  } else {
+    return &default_getpath_cb;
+  }
+}
+
+const sasl_callback_t *
+_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks)
+{
+  callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_GETCONFPATH);
+  if (callbacks != NULL) {
+    return callbacks;
+  } else {
+    return &default_getconfpath_cb;
+  }
+}
+
+const sasl_callback_t *
+_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks)
+{
+  static const sasl_callback_t default_verifyfile_cb = {
+    SASL_CB_VERIFYFILE,
+    &_sasl_verifyfile,
+    NULL
+  };
+
+  callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_VERIFYFILE);
+  if (callbacks != NULL) {
+    return callbacks;
+  } else {
+    return &default_verifyfile_cb;
+  }
+}
+
+/* Basically a conditional call to realloc(), if we need more */
+int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen) 
+{
+    if(!(*rwbuf)) {
+       *rwbuf = sasl_ALLOC((unsigned)newlen);
+       if (*rwbuf == NULL) {
+           *curlen = 0;
+           return SASL_NOMEM;
+       }
+       *curlen = newlen;
+    } else if(*rwbuf && *curlen < newlen) {
+       size_t needed = 2*(*curlen);
+
+       while(needed < newlen)
+           needed *= 2;
+
+        /* WARN - We will leak the old buffer on failure */
+       *rwbuf = sasl_REALLOC(*rwbuf, (unsigned)needed);
+       
+       if (*rwbuf == NULL) {
+           *curlen = 0;
+           return SASL_NOMEM;
+       }
+       *curlen = needed;
+    } 
+
+    return SASL_OK;
+}
+
+/* for the mac os x cfm glue: this lets the calling function
+   get pointers to the error buffer without having to touch the sasl_conn_t struct */
+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl)
+{
+       *bufhdl = &conn->error_buf;
+       *lenhdl = &conn->error_buf_len;
+}
+
+/* convert an iovec to a single buffer */
+int _iovec_to_buf(const struct iovec *vec,
+                 unsigned numiov, buffer_info_t **output) 
+{
+    unsigned i;
+    int ret;
+    buffer_info_t *out;
+    char *pos;
+
+    if (!vec || !output) return SASL_BADPARAM;
+
+    if (!(*output)) {
+       *output = sasl_ALLOC(sizeof(buffer_info_t));
+       if (!*output) return SASL_NOMEM;
+       memset(*output,0,sizeof(buffer_info_t));
+    }
+
+    out = *output;
+    
+    out->curlen = 0;
+    for (i = 0; i < numiov; i++) {
+       out->curlen += vec[i].iov_len;
+    }
+
+    ret = _buf_alloc(&out->data, &out->reallen, out->curlen);
+
+    if (ret != SASL_OK) return SASL_NOMEM;
+    
+    memset(out->data, 0, out->reallen);
+    pos = out->data;
+    
+    for (i = 0; i < numiov; i++) {
+       memcpy(pos, vec[i].iov_base, vec[i].iov_len);
+       pos += vec[i].iov_len;
+    }
+
+    return SASL_OK;
+}
+
+/* This code might be useful in the future, but it isn't now, so.... */
+#if 0
+int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
+                    char *out, unsigned outlen) {
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    int niflags;
+
+    if(!addr || !out) return SASL_BADPARAM;
+
+    niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+    if (addr->sa_family == AF_INET6)
+       niflags |= NI_WITHSCOPEID;
+#endif
+    if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
+                   niflags) != 0)
+       return SASL_BADPARAM;
+
+    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
+       return SASL_BUFOVER;
+
+    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
+
+    return SASL_OK;
+}
+#endif
+
+int _sasl_ipfromstring(const char *addr,
+                      struct sockaddr *out, socklen_t outlen) 
+{
+    int i, j;
+    struct addrinfo hints, *ai = NULL;
+    char hbuf[NI_MAXHOST];
+    
+    /* A NULL out pointer just implies we don't do a copy, just verify it */
+
+    if(!addr) return SASL_BADPARAM;
+
+    /* Parse the address */
+    for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
+       if (i >= NI_MAXHOST)
+           return SASL_BADPARAM;
+       hbuf[i] = addr[i];
+    }
+    hbuf[i] = '\0';
+
+    if (addr[i] == ';')
+       i++;
+    /* XXX: Do we need this check? */
+    for (j = i; addr[j] != '\0'; j++)
+       if (!isdigit((int)(addr[j])))
+           return SASL_BADPARAM;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+    if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0)
+       return SASL_BADPARAM;
+
+    if (out) {
+       if (outlen < (socklen_t)ai->ai_addrlen) {
+           freeaddrinfo(ai);
+           return SASL_BUFOVER;
+       }
+       memcpy(out, ai->ai_addr, ai->ai_addrlen);
+    }
+
+    freeaddrinfo(ai);
+
+    return SASL_OK;
+}
+
+int _sasl_build_mechlist(void) 
+{
+    int count = 0;
+    sasl_string_list_t *clist = NULL, *slist = NULL, *olist = NULL;
+    sasl_string_list_t *p, *q, **last, *p_next;
+
+    clist = _sasl_client_mechs();
+    slist = _sasl_server_mechs();
+
+    if(!clist) {
+       olist = slist;
+    } else {
+       int flag;
+       
+       /* append slist to clist, and set olist to clist */
+       for(p = slist; p; p = p_next) {
+           flag = 0;
+           p_next = p->next;
+
+           last = &clist;
+           for(q = clist; q; q = q->next) {
+               if(!strcmp(q->d, p->d)) {
+                   /* They match, set the flag */
+                   flag = 1;
+                   break;
+               }
+               last = &(q->next);
+           }
+
+           if(!flag) {
+               *last = p;
+               p->next = NULL;
+           } else {
+               sasl_FREE(p);
+           }
+       }
+
+       olist = clist;
+    }
+
+    if(!olist) {
+       printf ("no olist");
+       return SASL_FAIL;
+    }
+
+    for (p = olist; p; p = p->next) count++;
+    
+    if(global_mech_list) {
+       sasl_FREE(global_mech_list);
+       global_mech_list = NULL;
+    }
+    
+    global_mech_list = sasl_ALLOC((count + 1) * sizeof(char *));
+    if(!global_mech_list) return SASL_NOMEM;
+    
+    memset(global_mech_list, 0, (count + 1) * sizeof(char *));
+    
+    count = 0;
+    for (p = olist; p; p = p_next) {
+       p_next = p->next;
+
+       global_mech_list[count++] = (char *) p->d;
+
+       sasl_FREE(p);
+    }
+
+    return SASL_OK;
+}
+
+const char ** sasl_global_listmech(void) 
+{
+    return (const char **)global_mech_list;
+}
+
+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)
+{
+    if(!conn) {
+       return SASL_BADPARAM;
+    } else if(conn->type == SASL_CONN_SERVER) {
+       RETURN(conn, _sasl_server_listmech(conn, user, prefix, sep, suffix,
+                                          result, plen, pcount));
+    } else if (conn->type == SASL_CONN_CLIENT) {
+       RETURN(conn, _sasl_client_listmech(conn, prefix, sep, suffix,
+                                          result, plen, pcount));
+    }
+    
+    PARAMERROR(conn);
+}
+
+
+#ifndef WIN32
+static char *
+_sasl_get_default_unix_path(void *context __attribute__((unused)),
+                            char * env_var_name,
+                            char * default_value)
+{
+    char *path = NULL;
+
+    /* Honor external variable only in a safe environment */
+    if (getuid() == geteuid() && getgid() == getegid()) {
+        path = getenv(env_var_name);
+    }
+    if (! path) {
+        path = default_value;
+    }
+
+    return path;
+}
+
+#else
+/* Return NULL on failure */
+static char *
+_sasl_get_default_win_path(void *context __attribute__((unused)),
+                           char * reg_attr_name,
+                           char * default_value)
+{
+    /* Open registry entry, and find all registered SASL libraries.
+     *
+     * Registry location:
+     *
+     *     SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library
+     *
+     * Key - value:
+     *
+     *     "SearchPath" - value: PATH like (';' delimited) list
+     *                    of directories where to search for plugins
+     *                    The list may contain references to environment
+     *                    variables (e.g. %PATH%).
+     *
+     */
+    HKEY  hKey;
+    DWORD ret;
+    DWORD ValueType;               /* value type */
+    DWORD cbData;                  /* value size */
+    BYTE * ValueData;              /* value */
+    DWORD cbExpandedData;          /* "expanded" value size */
+    BYTE * ExpandedValueData;      /* "expanded" value */
+    char * return_value;           /* function return value */
+    char * tmp;
+
+    /* Initialization */
+    ExpandedValueData = NULL;
+    ValueData = NULL;
+    return_value = NULL;
+
+    /* Open the registry */
+    ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                      SASL_ROOT_KEY,
+                      0,
+                      KEY_READ,
+                      &hKey);
+
+    if (ret != ERROR_SUCCESS) { 
+        /* no registry entry */
+        (void) _sasl_strdup (default_value, &return_value, NULL);
+        return return_value;
+    }
+
+    /* figure out value type and required buffer size */
+    /* the size will include space for terminating NUL if required */
+    RegQueryValueEx (hKey,
+                    reg_attr_name,
+                    NULL,          /* reserved */
+                    &ValueType,
+                    NULL,
+                    &cbData);
+    /* Only accept string related types */
+    if (ValueType != REG_EXPAND_SZ &&
+       ValueType != REG_MULTI_SZ &&
+       ValueType != REG_SZ) {
+       return_value = NULL;
+       goto CLEANUP;
+    }
+
+    /* Any high water mark? */
+    ValueData = sasl_ALLOC(cbData);
+    if (ValueData == NULL) {
+       return_value = NULL;
+       goto CLEANUP;
+    };
+
+    RegQueryValueEx (hKey,
+                    reg_attr_name,
+                    NULL,          /* reserved */
+                    &ValueType,
+                    ValueData,
+                    &cbData);
+
+    switch (ValueType) {
+    case REG_EXPAND_SZ:
+        /* : A random starting guess */
+        cbExpandedData = cbData + 1024;
+        ExpandedValueData = sasl_ALLOC(cbExpandedData);
+        if (ExpandedValueData == NULL) {
+            return_value = NULL;
+            goto CLEANUP;
+        };
+
+        cbExpandedData = ExpandEnvironmentStrings(
+                                                  ValueData,
+                                                  ExpandedValueData,
+                                                  cbExpandedData);
+
+        if (cbExpandedData == 0) {
+            /* : GetLastError() contains the reason for failure */
+            return_value = NULL;
+            goto CLEANUP;
+        }
+
+        /* : Must retry expansion with the bigger buffer */
+        if (cbExpandedData > cbData + 1024) {
+            /* : Memory leak here if can't realloc */
+            ExpandedValueData = sasl_REALLOC(ExpandedValueData, cbExpandedData);
+            if (ExpandedValueData == NULL) {
+                return_value = NULL;
+                goto CLEANUP;
+            };
+
+            cbExpandedData = ExpandEnvironmentStrings(
+                                                      ValueData,
+                                                      ExpandedValueData,
+                                                      cbExpandedData);
+
+            /* : This should not happen */
+            if (cbExpandedData == 0) {
+                /* : GetLastError() contains the reason for failure */
+                return_value = NULL;
+                goto CLEANUP;
+            }
+        }
+
+        sasl_FREE(ValueData);
+        ValueData = ExpandedValueData;
+        /* : This is to prevent automatical freeing of this block on cleanup */
+        ExpandedValueData = NULL;
+
+        break;
+
+    case REG_MULTI_SZ:
+        tmp = ValueData;
+
+        /* : We shouldn't overflow here, as the buffer is guarantied
+           : to contain at least two consequent NULs */
+        while (1) {
+            if (tmp[0] == '\0') {
+                /* : Stop the process if we found the end of the string (two consequent NULs) */
+                if (tmp[1] == '\0') {
+                    break;
+                }
+
+                /* : Replace delimiting NUL with our delimiter characted */
+                tmp[0] = PATHS_DELIMITER;
+            }
+            tmp += strlen(tmp);
+        }
+        break;
+
+    case REG_SZ:
+        /* Do nothing, it is good as is */
+        break;
+
+    default:
+        return_value = NULL;
+        goto CLEANUP;
+    }
+
+    return_value = ValueData;
+
+CLEANUP:
+    RegCloseKey(hKey);
+    if (ExpandedValueData != NULL) sasl_FREE(ExpandedValueData);
+    if (return_value == NULL) {
+       if (ValueData != NULL) sasl_FREE(ValueData);
+    }
+
+    return (return_value);
+}
+#endif
diff --git a/lib/config.c b/lib/config.c
new file mode 100644 (file)
index 0000000..ed6cac8
--- /dev/null
@@ -0,0 +1,149 @@
+/* SASL Config file API
+ * Rob Siemborski
+ * Tim Martin (originally in Cyrus distribution)
+ * $Id: config.c,v 1.15 2006/04/10 13:28:06 mel 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.
+ */
+
+/*
+ * Current Valid keys:
+ *
+ * canon_user_plugin: <string>
+ * pwcheck_method: <string>
+ * auto_transition: <boolean>
+ * plugin_list: <string>
+ *
+ * srvtab: <string>
+ */
+
+
+#include "sasl.h"
+#include "saslint.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+struct configlist {
+    char *key;
+    char *value;
+};
+
+static struct configlist *configlist;
+static int nconfiglist;
+
+#define CONFIGLISTGROWSIZE 100
+
+int sasl_config_init(const char *filename)
+{
+    FILE *infile;
+    int lineno = 0;
+    int alloced = 0;
+    char buf[4096];
+    char *p, *key;
+    int result;
+
+    nconfiglist=0;
+
+    infile = fopen(filename, "r");
+    if (!infile) {
+        return SASL_CONTINUE;
+    }
+    
+    while (fgets(buf, sizeof(buf), infile)) {
+       lineno++;
+
+       if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
+       for (p = buf; *p && isspace((int) *p); p++);
+       if (!*p || *p == '#') continue;
+
+       key = p;
+       while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
+           if (isupper((int) *p)) *p = tolower(*p);
+           p++;
+       }
+       if (*p != ':') {
+           return SASL_FAIL;
+       }
+       *p++ = '\0';
+
+       while (*p && isspace((int) *p)) p++;
+       
+       if (!*p) {
+           return SASL_FAIL;
+       }
+
+       if (nconfiglist == alloced) {
+           alloced += CONFIGLISTGROWSIZE;
+           configlist=sasl_REALLOC((char *)configlist, 
+                                   alloced * sizeof(struct configlist));
+           if (configlist==NULL) return SASL_NOMEM;
+       }
+
+
+
+       result = _sasl_strdup(key,
+                             &(configlist[nconfiglist].key),
+                             NULL);
+       if (result!=SASL_OK) return result;
+       result = _sasl_strdup(p,
+                             &(configlist[nconfiglist].value),
+                             NULL);
+       if (result!=SASL_OK) return result;
+
+       nconfiglist++;
+    }
+    fclose(infile);
+
+    return SASL_OK;
+}
+
+const char *sasl_config_getstring(const char *key,const char *def)
+{
+    int opt;
+
+    for (opt = 0; opt < nconfiglist; opt++) {
+       if (*key == configlist[opt].key[0] &&
+           !strcmp(key, configlist[opt].key))
+         return configlist[opt].value;
+    }
+    return def;
+}
diff --git a/lib/dlopen.c b/lib/dlopen.c
new file mode 100644 (file)
index 0000000..58a2872
--- /dev/null
@@ -0,0 +1,548 @@
+/* dlopen.c--Unix dlopen() dynamic loader interface
+ * Rob Siemborski
+ * Rob Earhart
+ * $Id: dlopen.c,v 1.49 2005/03/15 13:33:30 mel 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.
+ */
+
+#include <config.h>
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <limits.h>
+
+#include <sasl.h>
+#include "saslint.h"
+
+#ifndef PIC
+#include <saslplug.h>
+#include "staticopen.h"
+#endif
+
+#ifdef DO_DLOPEN
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else /* HAVE_DIRENT_H */
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# if HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif /* ! HAVE_DIRENT_H */
+
+#ifndef NAME_MAX
+# ifdef _POSIX_NAME_MAX
+#  define NAME_MAX _POSIX_NAME_MAX
+# else
+#  define NAME_MAX 16
+# endif
+#endif
+#if NAME_MAX < 8
+#  define NAME_MAX 8
+#endif
+
+#ifdef __hpux
+#ifndef HAVE_DLFCN_H
+#include <dl.h>
+
+typedef shl_t dll_handle;
+typedef void * dll_func;
+
+dll_handle
+dlopen(char *fname, int mode)
+{
+    shl_t h = shl_load(fname, BIND_DEFERRED, 0L);
+    shl_t *hp = NULL;
+    
+    if (h) {
+       hp = (shl_t *)malloc(sizeof (shl_t));
+       if (!hp) {
+           shl_unload(h);
+       } else {
+           *hp = h;
+       }
+    }
+
+    return (dll_handle)hp;
+}
+
+int
+dlclose(dll_handle h)
+{
+    shl_t hp = *((shl_t *)h);
+    if (hp != NULL) free(hp);
+    return shl_unload(h);
+}
+
+dll_func
+dlsym(dll_handle h, char *n)
+{
+    dll_func handle;
+    
+    if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle))
+       return NULL;
+    
+    return (dll_func)handle;
+}
+
+char *dlerror()
+{
+    if (errno != 0) {
+       return strerror(errno);
+    }
+    return "Generic shared library error";
+}
+
+#endif /* HAVE_DLFCN_H */
+#define SO_SUFFIX      ".sl"
+#else /* __hpux */
+#define SO_SUFFIX      ".so"
+#endif /* __hpux */
+
+#define LA_SUFFIX       ".la"
+
+typedef struct lib_list 
+{
+    struct lib_list *next;
+    void *library;
+} lib_list_t;
+
+static lib_list_t *lib_list_head = NULL;
+
+#endif /* DO_DLOPEN */
+
+int _sasl_locate_entry(void *library, const char *entryname,
+                      void **entry_point) 
+{
+#ifdef DO_DLOPEN
+/* note that we still check for known problem systems in
+ * case we are cross-compiling */
+#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
+    char adj_entryname[1024];
+#else
+#define adj_entryname entryname
+#endif
+
+    if(!entryname) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no entryname in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+    if(!library) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no library in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+    if(!entry_point) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no entrypoint output pointer in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
+    snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
+#endif
+
+    *entry_point = NULL;
+    *entry_point = dlsym(library, adj_entryname);
+    if (*entry_point == NULL) {
+#if 0 /* This message appears to confuse people */
+       _sasl_log(NULL, SASL_LOG_DEBUG,
+                 "unable to get entry point %s: %s", adj_entryname,
+                 dlerror());
+#endif
+       return SASL_FAIL;
+    }
+
+    return SASL_OK;
+#else
+    return SASL_FAIL;
+#endif /* DO_DLOPEN */
+}
+
+#ifdef DO_DLOPEN
+
+static int _sasl_plugin_load(char *plugin, void *library,
+                            const char *entryname,
+                            int (*add_plugin)(const char *, void *)) 
+{
+    void *entry_point;
+    int result;
+    
+    result = _sasl_locate_entry(library, entryname, &entry_point);
+    if(result == SASL_OK) {
+       result = add_plugin(plugin, entry_point);
+       if(result != SASL_OK)
+           _sasl_log(NULL, SASL_LOG_DEBUG,
+                     "_sasl_plugin_load failed on %s for plugin: %s\n",
+                     entryname, plugin);
+    }
+
+    return result;
+}
+
+/* this returns the file to actually open.
+ *  out should be a buffer of size PATH_MAX
+ *  and may be the same as in. */
+
+/* We'll use a static buffer for speed unless someone complains */
+#define MAX_LINE 2048
+
+static int _parse_la(const char *prefix, const char *in, char *out) 
+{
+    FILE *file;
+    size_t length;
+    char line[MAX_LINE];
+    char *ntmp = NULL;
+
+    if(!in || !out || !prefix || out == in) return SASL_BADPARAM;
+
+    /* Set this so we can detect failure */
+    *out = '\0';
+
+    length = strlen(in);
+
+    if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) {
+       if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) {
+           /* check for a .la file */
+           strcpy(line, prefix);
+           strcat(line, in);
+           length = strlen(line);
+           *(line + (length - strlen(SO_SUFFIX))) = '\0';
+           strcat(line, LA_SUFFIX);
+           file = fopen(line, "r");
+           if(file) {
+               /* We'll get it on the .la open */
+               fclose(file);
+               return SASL_FAIL;
+           }
+       }
+       strcpy(out, prefix);
+       strcat(out, in);
+       return SASL_OK;
+    }
+
+    strcpy(line, prefix);
+    strcat(line, in);
+
+    file = fopen(line, "r");
+    if(!file) {
+       _sasl_log(NULL, SASL_LOG_WARN,
+                 "unable to open LA file: %s", line);
+       return SASL_FAIL;
+    }
+    
+    while(!feof(file)) {
+       if(!fgets(line, MAX_LINE, file)) break;
+       if(line[strlen(line) - 1] != '\n') {
+           _sasl_log(NULL, SASL_LOG_WARN,
+                     "LA file has too long of a line: %s", in);
+           return SASL_BUFOVER;
+       }
+       if(line[0] == '\n' || line[0] == '#') continue;
+       if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) {
+           /* We found the line with the name in it */
+           char *end;
+           char *start;
+           size_t len;
+           end = strrchr(line, '\'');
+           if(!end) continue;
+           start = &line[sizeof("dlname=")-1];
+           len = strlen(start);
+           if(len > 3 && start[0] == '\'') {
+               ntmp=&start[1];
+               *end='\0';
+               /* Do we have dlname="" ? */
+               if(ntmp == end) {
+                   _sasl_log(NULL, SASL_LOG_DEBUG,
+                             "dlname is empty in .la file: %s", in);
+                   return SASL_FAIL;
+               }
+               strcpy(out, prefix);
+               strcat(out, ntmp);
+           }
+           break;
+       }
+    }
+    if(ferror(file) || feof(file)) {
+       _sasl_log(NULL, SASL_LOG_WARN,
+                 "Error reading .la: %s\n", in);
+       fclose(file);
+       return SASL_FAIL;
+    }
+    fclose(file);
+
+    if(!(*out)) {
+       _sasl_log(NULL, SASL_LOG_WARN,
+                 "Could not find a dlname line in .la file: %s", in);
+       return SASL_FAIL;
+    }
+
+    return SASL_OK;
+}
+#endif /* DO_DLOPEN */
+
+/* loads a plugin library */
+int _sasl_get_plugin(const char *file,
+                    const sasl_callback_t *verifyfile_cb,
+                    void **libraryptr)
+{
+#ifdef DO_DLOPEN
+    int r = 0;
+    int flag;
+    void *library;
+    lib_list_t *newhead;
+    
+    r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
+                   (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
+    if (r != SASL_OK) return r;
+
+#ifdef RTLD_NOW
+    flag = RTLD_NOW;
+#else
+    flag = 0;
+#endif
+
+    newhead = sasl_ALLOC(sizeof(lib_list_t));
+    if(!newhead) return SASL_NOMEM;
+
+    if (!(library = dlopen(file, flag))) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "unable to dlopen %s: %s", file, dlerror());
+       sasl_FREE(newhead);
+       return SASL_FAIL;
+    }
+
+    newhead->library = library;
+    newhead->next = lib_list_head;
+    lib_list_head = newhead;
+
+    *libraryptr = library;
+    return SASL_OK;
+#else
+    return SASL_FAIL;
+#endif /* DO_DLOPEN */
+}
+
+/* gets the list of mechanisms */
+int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
+                      const sasl_callback_t *getpath_cb,
+                      const sasl_callback_t *verifyfile_cb)
+{
+    int result;
+    const add_plugin_list_t *cur_ep;
+#ifdef DO_DLOPEN
+    char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
+                               /* 1 for '/' 1 for trailing '\0' */
+    char c;
+    int pos;
+    const char *path=NULL;
+    int position;
+    DIR *dp;
+    struct dirent *dir;
+#endif
+#ifndef PIC
+    add_plugin_t *add_plugin;
+    _sasl_plug_type type;
+    _sasl_plug_rec *p;
+#endif
+
+    if (! entrypoints
+       || ! getpath_cb
+       || getpath_cb->id != SASL_CB_GETPATH
+       || ! getpath_cb->proc
+       || ! verifyfile_cb
+       || verifyfile_cb->id != SASL_CB_VERIFYFILE
+       || ! verifyfile_cb->proc)
+       return SASL_BADPARAM;
+
+#ifndef PIC
+    /* do all the static plugins first */
+
+    for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
+
+       /* What type of plugin are we looking for? */
+       if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
+           type = SERVER;
+           add_plugin = (add_plugin_t *)sasl_server_add_plugin;
+       } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
+           type = CLIENT;
+           add_plugin = (add_plugin_t *)sasl_client_add_plugin;
+       } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
+           type = AUXPROP;
+           add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
+       } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
+           type = CANONUSER;
+           add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
+       } else {
+           /* What are we looking for then? */
+           return SASL_FAIL;
+       }
+       for (p=_sasl_static_plugins; p->type; p++) {
+           if(type == p->type)
+               result = add_plugin(p->name, p->plug);
+       }
+    }
+#endif /* !PIC */
+
+/* only do the following if:
+ * 
+ * we support dlopen()
+ *  AND we are not staticly compiled
+ *      OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
+ */
+#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
+    /* get the path to the plugins */
+    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
+                                                   &path);
+    if (result != SASL_OK) return result;
+    if (! path) return SASL_FAIL;
+
+    if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
+       return SASL_FAIL;
+    }
+
+    position=0;
+    do {
+       pos=0;
+       do {
+           c=path[position];
+           position++;
+           str[pos]=c;
+           pos++;
+       } while ((c!=':') && (c!='=') && (c!=0));
+       str[pos-1]='\0';
+
+       strcpy(prefix,str);
+       strcat(prefix,"/");
+
+       if ((dp=opendir(str)) !=NULL) /* ignore errors */    
+       {
+           while ((dir=readdir(dp)) != NULL)
+           {
+               size_t length;
+               void *library;
+               char *c;
+               char plugname[PATH_MAX];
+               char name[PATH_MAX];
+
+               length = NAMLEN(dir);
+               if (length < 4) 
+                   continue; /* can not possibly be what we're looking for */
+
+               if (length + pos>=PATH_MAX) continue; /* too big */
+
+               if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
+                          SO_SUFFIX)
+                   && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
+                          LA_SUFFIX))
+                   continue;
+
+               memcpy(name,dir->d_name,length);
+               name[length]='\0';
+
+               result = _parse_la(prefix, name, tmp);
+               if(result != SASL_OK)
+                   continue;
+               
+               /* skip "lib" and cut off suffix --
+                  this only need be approximate */
+               strcpy(plugname, name + 3);
+               c = strchr(plugname, (int)'.');
+               if(c) *c = '\0';
+
+               result = _sasl_get_plugin(tmp, verifyfile_cb, &library);
+
+               if(result != SASL_OK)
+                   continue;
+
+               for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
+                       _sasl_plugin_load(plugname, library, cur_ep->entryname,
+                                         cur_ep->add_plugin);
+                       /* If this fails, it's not the end of the world */
+               }
+           }
+
+           closedir(dp);
+       } else {
+           _sasl_log(NULL, SASL_LOG_DEBUG,
+                     "looking for plugins in '%s', failed to open directory, error: %s",
+                     str,
+                     strerror(errno));
+       }
+
+    } while ((c!='=') && (c!=0));
+#endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */
+
+    return SASL_OK;
+}
+
+int
+_sasl_done_with_plugins(void)
+{
+#ifdef DO_DLOPEN
+    lib_list_t *libptr, *libptr_next;
+    
+    for(libptr = lib_list_head; libptr; libptr = libptr_next) {
+       libptr_next = libptr->next;
+       if(libptr->library)
+           dlclose(libptr->library);
+       sasl_FREE(libptr);
+    }
+
+    lib_list_head = NULL;
+#endif /* DO_DLOPEN */
+    return SASL_OK;
+}
diff --git a/lib/external.c b/lib/external.c
new file mode 100644 (file)
index 0000000..2a1ee95
--- /dev/null
@@ -0,0 +1,410 @@
+/* SASL server API implementation
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: external.c,v 1.22 2004/02/20 17:23:58 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+#include <string.h>
+#include <sasl.h>
+#include <saslplug.h>
+#include "saslint.h"
+
+#include "../plugins/plugin_common.h"
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: external.c,v 1.22 2004/02/20 17:23:58 rjs3 Exp $";
+
+/*****************************  Server Section  *****************************/
+
+static int
+external_server_mech_new(void *glob_context __attribute__((unused)),
+                        sasl_server_params_t *sparams,
+                        const char *challenge __attribute__((unused)),
+                        unsigned challen __attribute__((unused)),
+                        void **conn_context)
+{
+    if (!conn_context
+       || !sparams
+       || !sparams->utils
+       || !sparams->utils->conn)
+       return SASL_BADPARAM;
+    
+    if (!sparams->utils->conn->external.auth_id)
+       return SASL_NOMECH;
+    
+    *conn_context = NULL;
+
+    return SASL_OK;
+}
+
+static int
+external_server_mech_step(void *conn_context __attribute__((unused)),
+                         sasl_server_params_t *sparams,
+                         const char *clientin,
+                         unsigned clientinlen,
+                         const char **serverout,
+                         unsigned *serveroutlen,
+                         sasl_out_params_t *oparams)
+{
+    int result;
+    
+    if (!sparams
+       || !sparams->utils
+       || !sparams->utils->conn
+       || !sparams->utils->getcallback
+       || !serverout
+       || !serveroutlen
+       || !oparams)
+       return SASL_BADPARAM;
+    
+    if (!sparams->utils->conn->external.auth_id)
+       return SASL_BADPROT;
+    
+    /* xxx arbitrary limit here */
+    if (clientinlen > 16384) return SASL_BADPROT;
+
+    if ((sparams->props.security_flags & SASL_SEC_NOANONYMOUS) &&
+       (!strcmp(sparams->utils->conn->external.auth_id, "anonymous"))) {
+       sasl_seterror(sparams->utils->conn,0,"anonymous login not allowed");
+       return SASL_NOAUTHZ;
+    }
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    if (!clientin) {
+       /* No initial data; we're in a protocol which doesn't support it.
+        * So we let the server app know that we need some... */
+       return SASL_CONTINUE;
+    }
+    
+    if (clientinlen) {         /* if we have a non-zero authorization id */
+       /* The user's trying to authorize as someone they didn't
+        * authenticate as */
+       result = sparams->canon_user(sparams->utils->conn,
+                                    clientin, 0,
+                                    SASL_CU_AUTHZID, oparams);
+       if(result != SASL_OK) return result;
+       
+       result = sparams->canon_user(sparams->utils->conn,
+                                    sparams->utils->conn->external.auth_id, 0,
+                                    SASL_CU_AUTHID, oparams);
+    } else {
+       result = sparams->canon_user(sparams->utils->conn,
+                                    sparams->utils->conn->external.auth_id, 0,
+                                    SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    }
+    
+    if (result != SASL_OK) return result;
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+
+    return SASL_OK;
+}
+
+static int
+external_server_mech_avail(void *glob_context __attribute__((unused)),
+                          sasl_server_params_t *sparams,
+                          void **conn_context __attribute__((unused)))
+{
+    if (!sparams->utils->conn->external.auth_id) {
+       /* Return Temporary Failure */
+       return SASL_NOTDONE;
+    }
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t external_server_plugins[] =
+{
+    {
+       "EXTERNAL",                     /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NODICTIONARY,        /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &external_server_mech_new,      /* mech_new */
+       &external_server_mech_step,     /* mech_step */
+       NULL,                           /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       &external_server_mech_avail,    /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int external_server_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_server_plug_t **pluglist,
+                             int *plugcount)
+{
+    if (!out_version || !pluglist || !plugcount)
+       return SASL_BADPARAM;
+    
+    if (max_version != SASL_SERVER_PLUG_VERSION) {
+       SETERROR( utils, "EXTERNAL version mismatch" );
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = external_server_plugins;
+    *plugcount = 1;
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context 
+{
+    char *out_buf;
+    size_t out_buf_len;
+} client_context_t;
+
+static int external_client_mech_new(void *glob_context __attribute__((unused)),
+                                   sasl_client_params_t *params,
+                                   void **conn_context)
+{
+    client_context_t *text;
+    
+    if (!params
+       || !params->utils
+       || !params->utils->conn
+       || !conn_context)
+       return SASL_BADPARAM;
+    
+    if (!params->utils->conn->external.auth_id)
+       return SASL_NOMECH;
+    
+    text = sasl_ALLOC(sizeof(client_context_t));
+    if(!text) return SASL_NOMEM;
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    *conn_context = text;
+
+    return SASL_OK;
+}
+
+static int
+external_client_mech_step(void *conn_context,
+                         sasl_client_params_t *params,
+                         const char *serverin __attribute__((unused)),
+                         unsigned serverinlen,
+                         sasl_interact_t **prompt_need,
+                         const char **clientout,
+                         unsigned *clientoutlen,
+                         sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *)conn_context;
+    const char *user = NULL;
+    int user_result = SASL_OK;
+    int result;
+    
+    if (!params
+       || !params->utils
+       || !params->utils->conn
+       || !params->utils->getcallback
+       || !clientout
+       || !clientoutlen
+       || !oparams)
+       return SASL_BADPARAM;
+    
+    if (!params->utils->conn->external.auth_id)
+       return SASL_BADPROT;
+    
+    if (serverinlen != 0)
+       return SASL_BADPROT;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    /* try to get the userid */
+    if (user == NULL) {
+       user_result = _plug_get_userid(params->utils, &user, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
+           return user_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if (user_result == SASL_INTERACT) {
+       /* make the prompt list */
+       int result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              "",
+                              NULL, NULL,
+                              NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) return result;
+       
+       return SASL_INTERACT;
+    }
+    
+    *clientoutlen = user ? (unsigned) strlen(user) : 0;
+    
+    result = _buf_alloc(&text->out_buf, &text->out_buf_len, *clientoutlen + 1);
+    
+    if (result != SASL_OK) return result;
+    
+    if (user && *user) {
+       result = params->canon_user(params->utils->conn,
+                                   user, 0, SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+       
+       result = params->canon_user(params->utils->conn,
+                                   params->utils->conn->external.auth_id, 0,
+                                   SASL_CU_AUTHID, oparams);
+       if (result != SASL_OK) return result;
+       
+       memcpy(text->out_buf, user, *clientoutlen);
+    } else {
+       result = params->canon_user(params->utils->conn,
+                                   params->utils->conn->external.auth_id, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+    }
+    
+    text->out_buf[*clientoutlen] = '\0';
+    
+    *clientout = text->out_buf;
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return SASL_OK;
+}
+
+static void
+external_client_mech_dispose(void *conn_context,
+                            const sasl_utils_t *utils __attribute__((unused))) 
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if(text->out_buf) sasl_FREE(text->out_buf);
+    
+    sasl_FREE(text);
+}
+
+static const long external_required_prompts[] = {
+    SASL_CB_LIST_END
+};
+
+static sasl_client_plug_t external_client_plugins[] =
+{
+    {
+       "EXTERNAL",                     /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NODICTIONARY,        /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       external_required_prompts,      /* required_prompts */
+       NULL,                           /* glob_context */
+       &external_client_mech_new,      /* mech_new */
+       &external_client_mech_step,     /* mech_step */
+       &external_client_mech_dispose,  /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int external_client_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_client_plug_t **pluglist,
+                             int *plugcount)
+{
+    if (!utils || !out_version || !pluglist || !plugcount)
+       return SASL_BADPARAM;
+    
+    if (max_version != SASL_CLIENT_PLUG_VERSION) {
+       SETERROR( utils, "EXTERNAL version mismatch" );
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = external_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c
new file mode 100644 (file)
index 0000000..9b5452b
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: getaddrinfo.c,v 1.8 2003/03/19 18:25:28 rjs3 Exp $
+ *
+ * This module is based on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ * 
+ * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
+ * will be used if you have broken getaddrinfo or no getaddrinfo.
+ */
+
+#include "config.h"
+#ifndef WIN32
+#include <sys/param.h>
+# ifndef macintosh\r
+#  include <arpa/inet.h>
+# endif /* macintosh */\r
+#endif /* WIN32 */
+#include <ctype.h>
+
+#ifdef WIN32
+/* : Windows socket library is missing inet_aton, emulate it with
+   : inet_addr. inet_aton return 0 if the address is uncorrect, a non zero
+   : value otherwise */
+int
+inet_aton (const char *cp, struct in_addr *inp)
+{
+    if (cp == NULL || inp == NULL) {
+       return (0);
+    }
+
+    /* : handle special case */
+    if (strcmp (cp, "255.255.255.255") == 0) {
+       inp->s_addr = (unsigned int) 0xFFFFFFFF;
+       return (1);
+    }
+
+    inp->s_addr = inet_addr (cp);
+    return (1);
+}
+#endif /* WIN32 */
+
+static struct addrinfo *
+malloc_ai(int port, unsigned long addr, int socktype, int proto)
+{
+    struct addrinfo *ai;
+
+    ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
+                                  sizeof(struct sockaddr_in));
+    if (ai) {
+       memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
+       ai->ai_addr = (struct sockaddr *)(ai + 1);
+       /* XXX -- ssh doesn't use sa_len */
+       ai->ai_addrlen = sizeof(struct sockaddr_in);
+#ifdef HAVE_SOCKADDR_SA_LEN
+       ai->ai_addr->sa_len = sizeof(struct sockaddr_in);
+#endif
+       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+       ai->ai_socktype = socktype;
+       ai->ai_protocol = proto;
+       return ai;
+    } else {
+       return NULL;
+    }
+}
+
+char *
+gai_strerror(int ecode)
+{
+    switch (ecode) {
+    case EAI_NODATA:
+       return "no address associated with hostname.";
+    case EAI_MEMORY:
+       return "memory allocation failure.";
+    case EAI_FAMILY:
+       return "ai_family not supported.";
+    case EAI_SERVICE:
+       return "servname not supported for ai_socktype.";
+    default:
+       return "unknown error.";
+    }
+}
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+    struct addrinfo *next;
+
+    if (ai->ai_canonname)
+       free(ai->ai_canonname);
+    do {
+       next = ai->ai_next;
+       free(ai);
+    } while ((ai = next) != NULL);
+}
+
+int
+getaddrinfo(const char *hostname, const char *servname,
+           const struct addrinfo *hints, struct addrinfo **res)
+{
+    struct addrinfo *cur, *prev = NULL;
+    struct hostent *hp;
+    struct in_addr in;
+    int i, port = 0, socktype, proto;
+
+    if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC)
+       return EAI_FAMILY;
+
+    socktype = (hints && hints->ai_socktype) ? hints->ai_socktype
+                                            : SOCK_STREAM;
+    if (hints && hints->ai_protocol)
+       proto = hints->ai_protocol;
+    else {
+       switch (socktype) {
+       case SOCK_DGRAM:
+           proto = IPPROTO_UDP;
+           break;
+       case SOCK_STREAM:
+           proto = IPPROTO_TCP;
+           break;
+       default:
+           proto = 0;
+           break;
+       }
+    }
+    if (servname) {
+       if (isdigit((int)*servname))
+           port = htons((short) atoi(servname));
+       else {
+           struct servent *se;
+           char *pe_proto;
+
+           switch (socktype) {
+           case SOCK_DGRAM:
+               pe_proto = "udp";
+               break;
+           case SOCK_STREAM:
+               pe_proto = "tcp";
+               break;
+           default:
+               pe_proto = NULL;
+               break;
+           }
+           /* xxx thread safety ? */
+           if ((se = getservbyname(servname, pe_proto)) == NULL)
+               return EAI_SERVICE;
+           port = se->s_port;
+       }
+    }
+    if (!hostname) {
+        if (hints && hints->ai_flags & AI_PASSIVE)
+            *res = malloc_ai(port, htonl(0x00000000), socktype, proto);
+        else
+            *res = malloc_ai(port, htonl(0x7f000001), socktype, proto);
+        if (*res)
+           return 0;
+        else
+           return EAI_MEMORY;
+    }
+#if HAVE_INET_ATON
+    if (inet_aton(hostname, &in))
+#else
+    if ((in.s_addr = inet_addr(hostname)) != -1)
+#endif
+    {
+       *res = malloc_ai(port, in.s_addr, socktype, proto);
+       if (*res)
+           return 0;
+       else
+           return EAI_MEMORY;
+    }
+    if (hints && hints->ai_flags & AI_NUMERICHOST)
+       return EAI_NODATA;
+#ifndef macintosh
+    /* xxx thread safety? / gethostbyname_r */
+    if ((hp = gethostbyname(hostname)) &&
+       hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+       for (i = 0; hp->h_addr_list[i]; i++) {
+           if ((cur = malloc_ai(port,
+                               ((struct in_addr *)hp->h_addr_list[i])->s_addr,
+                               socktype, proto)) == NULL) {
+               if (*res)
+                   freeaddrinfo(*res);
+               return EAI_MEMORY;
+           }
+           if (prev)
+               prev->ai_next = cur;
+           else
+               *res = cur;
+           prev = cur;
+       }
+       if (hints && hints->ai_flags & AI_CANONNAME && *res) {
+           /* NOT sasl_strdup for compatibility */
+           if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) {
+               freeaddrinfo(*res);
+               return EAI_MEMORY;
+           }
+       }
+       return 0;
+    }
+#endif
+    return EAI_NODATA;
+}
diff --git a/lib/getnameinfo.c b/lib/getnameinfo.c
new file mode 100644 (file)
index 0000000..177d1cb
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: getnameinfo.c,v 1.5 2003/02/13 19:55:54 rjs3 Exp $
+ *
+ * This module is besed on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file includes getnameinfo().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ * 
+ * In the case not using 'configure --enable-ipv6', this getnameinfo.c
+ * will be used if you have broken getnameinfo or no getnameinfo.
+ */
+
+#include "config.h"
+#ifndef WIN32\r
+# include <arpa/inet.h>\r
+#endif /* WIN32 */
+#include <stdio.h>
+#include <string.h>
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen __attribute__((unused)),
+           char *host, size_t hostlen, char *serv, size_t servlen, int flags)
+{
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct hostent *hp;
+    char tmpserv[16];
+  
+    if (serv) {
+       sprintf(tmpserv, "%d", ntohs(sin->sin_port));
+       if (strlen(tmpserv) > servlen)
+           return EAI_MEMORY;
+       else
+           strcpy(serv, tmpserv);
+    }
+    if (host) {
+       if (flags & NI_NUMERICHOST) {
+           if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
+               return EAI_MEMORY;
+           else {
+               strcpy(host, inet_ntoa(sin->sin_addr));
+               return 0;
+           }
+       } else {
+           hp = gethostbyaddr((char *)&sin->sin_addr,
+                              sizeof(struct in_addr), AF_INET);
+           if (hp) {
+               if (strlen(hp->h_name) >= hostlen)
+                   return EAI_MEMORY;
+               else {
+                   strcpy(host, hp->h_name);
+                   return 0;
+               }
+           }
+           else
+               return EAI_NODATA;
+       }
+    }
+    
+    return 0;
+}
diff --git a/lib/getsubopt.c b/lib/getsubopt.c
new file mode 100644 (file)
index 0000000..38fdbcf
--- /dev/null
@@ -0,0 +1,114 @@
+/*     $NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $      */
+
+/*-
+ * Copyright (c) 1990, 1993
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if ((!defined(WIN32))&&(!defined(macintosh)))
+#include <sys/cdefs.h>
+#endif /* WIN32 */
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char sccsid[] = "@(#)getsubopt.c        8.1 (Berkeley) 6/4/93";
+#else
+__RCSID("$NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $");
+#endif
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if (defined(WIN32)||(defined(macintosh)))
+#include "sasl.h"
+LIBSASL_API int getsubopt(char **optionp, char * const *tokens, char **valuep);
+#endif /* WIN32 */
+/*
+ * The SVID interface to getsubopt provides no way of figuring out which
+ * part of the suboptions list wasn't matched.  This makes error messages
+ * tricky...  The extern variable suboptarg is a pointer to the token
+ * which didn't match.
+ */
+char *suboptarg;
+
+int
+getsubopt(optionp, tokens, valuep)
+       char **optionp, **valuep;
+       char * const *tokens;
+{
+       int cnt;
+       char *p;
+
+       suboptarg = *valuep = NULL;
+
+       if (!optionp || !*optionp)
+               return(-1);
+
+       /* skip leading white-space, commas */
+       for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
+
+       if (!*p) {
+               *optionp = p;
+               return(-1);
+       }
+
+       /* save the start of the token, and skip the rest of the token. */
+       for (suboptarg = p;
+           *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
+
+       if (*p) {
+               /*
+                * If there's an equals sign, set the value pointer, and
+                * skip over the value part of the token.  Terminate the
+                * token.
+                */
+               if (*p == '=') {
+                       *p = '\0';
+                       for (*valuep = ++p;
+                           *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
+                       if (*p) 
+                               *p++ = '\0';
+               } else
+                       *p++ = '\0';
+               /* Skip any whitespace or commas after this token. */
+               for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
+       }
+
+       /* set optionp for next round. */
+       *optionp = p;
+
+       for (cnt = 0; *tokens; ++tokens, ++cnt)
+               if (!strcmp(suboptarg, *tokens))
+                       return(cnt);
+       return(-1);
+}
diff --git a/lib/md5.c b/lib/md5.c
new file mode 100644 (file)
index 0000000..fbe7ae8
--- /dev/null
+++ b/lib/md5.c
@@ -0,0 +1,527 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Function names changed to avoid namespace collisions: Rob Siemborski */
+
+/* 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.
+*/
+
+#include <config.h>
+#include "md5global.h"
+#include "md5.h"
+#include "hmac-md5.h"
+
+#ifndef WIN32
+# include <arpa/inet.h>
+#endif
+
+/* Constants for MD5Transform routine.
+*/
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
+static void Encode PROTO_LIST
+       ((unsigned char *, UINT4 *, unsigned int)); 
+static void Decode PROTO_LIST
+       ((UINT4 *, const unsigned char *, unsigned int)); 
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
+};
+
+/* F, G, H and I are basic MD5 functions.
+
+        */
+#ifdef I
+/* This might be defined via NANA */
+#undef I
+#endif
+
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+
+        */
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+*/
+
+#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+#define GG(a, b, c, d, x, s, ac) {        (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);         } 
+#define HH(a, b, c, d, x, s, ac) {        (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+#define II(a, b, c, d, x, s, ac) {        (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+*/
+
+void _sasl_MD5Init (context)
+MD5_CTX *context; /* context */
+{
+       context->count[0] = context->count[1] = 0; 
+
+       /* Load magic initialization constants. */
+       context->state[0] = 0x67452301; 
+       context->state[1] = 0xefcdab89; 
+       context->state[2] = 0x98badcfe; 
+       context->state[3] = 0x10325476; 
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+       operation, processing another message block, and updating the context. 
+*/
+
+void _sasl_MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+const unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+       unsigned int i, index, partLen; 
+
+         /* Compute number of bytes mod 64 */
+         index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+         /* Update number of bits */
+         if ((context->count[0] += ((UINT4)inputLen << 3))
+          < ((UINT4)inputLen << 3))
+        context->count[1]++;
+         context->count[1] += ((UINT4)inputLen >> 29);
+
+       partLen = 64 - index; 
+
+         /* Transform as many times as possible.
+
+*/
+       if (inputLen >= partLen) { 
+       MD5_memcpy 
+       ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform
+       (context->state, context->buffer); 
+
+       for (i = partLen; i + 63 < inputLen; i += 64) 
+       MD5Transform (context->state, &input[i]); 
+
+       index = 0; 
+       } 
+       else 
+       i = 0; 
+
+         /* Buffer remaining input */
+         MD5_memcpy
+        ((POINTER)&context->buffer[index], (POINTER)&input[i],
+         inputLen-i);
+
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+       the message digest and zeroizing the context. 
+*/
+
+void _sasl_MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+       unsigned char bits[8]; 
+       unsigned int index, padLen; 
+
+         /* Save number of bits */
+         Encode (bits, context->count, 8);
+
+         /* Pad out to 56 mod 64. */
+        index = (unsigned int)((context->count[0] >> 3) & 0x3f); 
+        padLen = (index < 56) ? (56 - index) : (120 - index); 
+        _sasl_MD5Update (context, PADDING, padLen); 
+
+         /* Append length (before padding) */
+         _sasl_MD5Update (context, bits, 8);
+
+         /* Store state in digest */
+         Encode (digest, context->state, 16);
+
+         /* Zeroize sensitive information. */
+       MD5_memset ((POINTER)context, 0, sizeof (*context)); 
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static void MD5Transform (state, block)
+UINT4 state[4];
+const unsigned char block[64];
+{
+       UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 
+
+       Decode (x, block, 64); 
+
+         /* Round 1 */
+         FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+         FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+         FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+         FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+         FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+         FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+         FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+         FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+         FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+         FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+         FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+         FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+         FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+         FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+         FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+         FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+        /* Round 2 */
+         GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+         GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+         GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+         GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+         GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+         GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+         GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+         GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+         GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+         GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+         GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+        GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 
+        GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 
+        GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 
+        GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 
+        GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 
+
+         /* Round 3 */
+         HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+         HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+         HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+         HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+         HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+         HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+         HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+         HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+         HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+         HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+         HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+         HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+         HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+         HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+         HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+         HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+         /* Round 4 */
+         II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+         II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+         II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+         II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+         II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+         II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+         II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+         II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+         II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+         II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+         II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+         II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+         II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+         II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+         II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+         II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+       state[0] += a; 
+       state[1] += b; 
+       state[2] += c; 
+       state[3] += d; 
+
+         /* Zeroize sensitive information.
+        */
+       MD5_memset ((POINTER)x, 0, sizeof (x)); 
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+       a multiple of 4. 
+
+        */
+
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+       unsigned int i, j; 
+
+       for (i = 0, j = 0; j < len; i++, j += 4) { 
+       output[j] = (unsigned char)(input[i] & 0xff); 
+       output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 
+       output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 
+       output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 
+       } 
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+       a multiple of 4. 
+
+        */
+
+static void Decode (output, input, len)
+UINT4 *output;
+const unsigned char *input;
+unsigned int len;
+{
+       unsigned int i, j; 
+
+       for (i = 0, j = 0; j < len; i++, j += 4) 
+       output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16)
+       | (((UINT4)input[j+3]) << 24); 
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+
+        */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+       unsigned int i; 
+
+       for (i = 0; i < len; i++) 
+             output[i] = input[i]; 
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+*/
+
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+       unsigned int i; 
+
+       for (i = 0; i < len; i++) 
+       ((char *)output)[i] = (char)value; 
+}
+
+void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac,
+                        const unsigned char *key,
+                        int key_len)
+{
+  unsigned char k_ipad[65];    /* inner padding -
+                               * key XORd with ipad
+                               */
+  unsigned char k_opad[65];    /* outer padding -
+                               * key XORd with opad
+                               */
+  unsigned char tk[16];
+  int i;
+  /* if key is longer than 64 bytes reset it to key=MD5(key) */
+  if (key_len > 64) {
+    
+    MD5_CTX      tctx;
+
+    _sasl_MD5Init(&tctx); 
+    _sasl_MD5Update(&tctx, key, key_len); 
+    _sasl_MD5Final(tk, &tctx); 
+
+    key = tk; 
+    key_len = 16; 
+  } 
+
+  /*
+   * the HMAC_MD5 transform looks like:
+   *
+   * MD5(K XOR opad, MD5(K XOR ipad, text))
+   *
+   * where K is an n byte key
+   * ipad is the byte 0x36 repeated 64 times
+   * opad is the byte 0x5c repeated 64 times
+   * and text is the data being protected
+   */
+
+  /* start out by storing key in pads */
+  MD5_memset((POINTER)k_ipad, '\0', sizeof k_ipad);
+  MD5_memset((POINTER)k_opad, '\0', sizeof k_opad);
+  MD5_memcpy( k_ipad, (POINTER)key, key_len);
+  MD5_memcpy( k_opad, (POINTER)key, key_len);
+
+  /* XOR key with ipad and opad values */
+  for (i=0; i<64; i++) {
+    k_ipad[i] ^= 0x36;
+    k_opad[i] ^= 0x5c;
+  }
+
+  _sasl_MD5Init(&hmac->ictx);                   /* init inner context */
+  _sasl_MD5Update(&hmac->ictx, k_ipad, 64);     /* apply inner pad */
+
+  _sasl_MD5Init(&hmac->octx);                   /* init outer context */
+  _sasl_MD5Update(&hmac->octx, k_opad, 64);     /* apply outer pad */
+
+  /* scrub the pads and key context (if used) */
+  MD5_memset((POINTER)&k_ipad, 0, sizeof(k_ipad));
+  MD5_memset((POINTER)&k_opad, 0, sizeof(k_opad));
+  MD5_memset((POINTER)&tk, 0, sizeof(tk));
+
+  /* and we're done. */
+}
+
+/* The precalc and import routines here rely on the fact that we pad
+ * the key out to 64 bytes and use that to initialize the md5
+ * contexts, and that updating an md5 context with 64 bytes of data
+ * leaves nothing left over; all of the interesting state is contained
+ * in the state field, and none of it is left over in the count and
+ * buffer fields.  So all we have to do is save the state field; we
+ * can zero the others when we reload it.  Which is why the decision
+ * was made to pad the key out to 64 bytes in the first place. */
+void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *state,
+                           const unsigned char *key,
+                           int key_len)
+{
+  HMAC_MD5_CTX hmac;
+  unsigned lupe;
+
+  _sasl_hmac_md5_init(&hmac, key, key_len);
+  for (lupe = 0; lupe < 4; lupe++) {
+    state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
+    state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
+  }
+  MD5_memset((POINTER)&hmac, 0, sizeof(hmac));
+}
+
+
+void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac,
+                    HMAC_MD5_STATE *state)
+{
+  unsigned lupe;
+  MD5_memset((POINTER)hmac, 0, sizeof(HMAC_MD5_CTX));
+  for (lupe = 0; lupe < 4; lupe++) {
+    hmac->ictx.state[lupe] = ntohl(state->istate[lupe]);
+    hmac->octx.state[lupe] = ntohl(state->ostate[lupe]);
+  }
+  /* Init the counts to account for our having applied
+   * 64 bytes of key; this works out to 0x200 (64 << 3; see
+   * MD5Update above...) */
+  hmac->ictx.count[0] = hmac->octx.count[0] = 0x200;
+}
+
+void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
+                         HMAC_MD5_CTX *hmac)
+{
+  _sasl_MD5Final(digest, &hmac->ictx);  /* Finalize inner md5 */
+  _sasl_MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */
+  _sasl_MD5Final(digest, &hmac->octx); /* Finalize outer md5 */
+}
+
+
+void _sasl_hmac_md5(text, text_len, key, key_len, digest)
+const unsigned char* text; /* pointer to data stream */
+int text_len; /* length of data stream */
+const unsigned char* key; /* pointer to authentication key */
+int key_len; /* length of authentication key */
+unsigned char *digest; /* caller digest to be filled in */
+{
+  MD5_CTX context; 
+
+  unsigned char k_ipad[65];    /* inner padding -
+                               * key XORd with ipad
+                               */
+  unsigned char k_opad[65];    /* outer padding -
+                               * key XORd with opad
+                               */
+  unsigned char tk[16];
+  int i;
+  /* if key is longer than 64 bytes reset it to key=MD5(key) */
+  if (key_len > 64) {
+    
+    MD5_CTX      tctx;
+
+    _sasl_MD5Init(&tctx); 
+    _sasl_MD5Update(&tctx, key, key_len); 
+    _sasl_MD5Final(tk, &tctx); 
+
+    key = tk; 
+    key_len = 16; 
+  } 
+
+  /*
+   * the HMAC_MD5 transform looks like:
+   *
+   * MD5(K XOR opad, MD5(K XOR ipad, text))
+   *
+   * where K is an n byte key
+   * ipad is the byte 0x36 repeated 64 times
+   * opad is the byte 0x5c repeated 64 times
+   * and text is the data being protected
+   */
+
+  /* start out by storing key in pads */
+  MD5_memset(k_ipad, '\0', sizeof k_ipad);
+  MD5_memset(k_opad, '\0', sizeof k_opad);
+  MD5_memcpy( k_ipad, (POINTER)key, key_len);
+  MD5_memcpy( k_opad, (POINTER)key, key_len);
+
+  /* XOR key with ipad and opad values */
+  for (i=0; i<64; i++) {
+    k_ipad[i] ^= 0x36;
+    k_opad[i] ^= 0x5c;
+  }
+  /*
+   * perform inner MD5
+   */
+
+  _sasl_MD5Init(&context);                   /* init context for 1st
+                                              * pass */
+  _sasl_MD5Update(&context, k_ipad, 64);      /* start with inner pad */
+  _sasl_MD5Update(&context, text, text_len); /* then text of datagram */
+  _sasl_MD5Final(digest, &context);          /* finish up 1st pass */
+
+  /*
+   * perform outer MD5
+   */
+  _sasl_MD5Init(&context);                   /* init context for 2nd
+                                       * pass */
+  _sasl_MD5Update(&context, k_opad, 64);     /* start with outer pad */
+  _sasl_MD5Update(&context, digest, 16);     /* then results of 1st
+                                       * hash */
+  _sasl_MD5Final(digest, &context);          /* finish up 2nd pass */
+
+}
diff --git a/lib/saslint.h b/lib/saslint.h
new file mode 100644 (file)
index 0000000..b1c20ef
--- /dev/null
@@ -0,0 +1,496 @@
+/* saslint.h - internal SASL library definitions
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: saslint.h,v 1.60 2006/04/18 20:25:45 mel 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 SASLINT_H
+#define SASLINT_H
+
+#include <config.h>
+#include "sasl.h"
+#include "saslplug.h"
+#include "saslutil.h"
+#include "prop.h"
+
+/* #define'd constants */
+#define CANON_BUF_SIZE 1024
+
+/* Error Handling Foo */
+/* Helpful Hints:
+ *  -Error strings are set as soon as possible (first function in stack trace
+ *   with a pointer to the sasl_conn_t.
+ *  -Error codes are set as late as possible (only in the sasl api functions),
+ *   though "as often as possible" also comes to mind to ensure correctness
+ *  -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be
+ *   memory errors.
+ *  -Only errors (error codes < SASL_OK) should be remembered
+ */
+#define RETURN(conn, val) { if(conn && (val) < SASL_OK) \
+                               (conn)->error_code = (val); \
+                            return (val); }
+#define MEMERROR(conn) {\
+    if(conn) sasl_seterror( (conn), 0, \
+                   "Out of Memory in " __FILE__ " near line %d", __LINE__ ); \
+    RETURN(conn, SASL_NOMEM) }
+#define PARAMERROR(conn) {\
+    if(conn) sasl_seterror( (conn), SASL_NOLOG, \
+                  "Parameter error in " __FILE__ " near line %d", __LINE__ ); \
+    RETURN(conn, SASL_BADPARAM) }
+#define INTERROR(conn, val) {\
+    if(conn) sasl_seterror( (conn), 0, \
+                   "Internal Error %d in " __FILE__ " near line %d", (val),\
+                  __LINE__ ); \
+    RETURN(conn, (val)) }
+
+#ifndef PATH_MAX
+# ifdef WIN32
+#  define PATH_MAX MAX_PATH
+# else
+#  ifdef _POSIX_PATH_MAX
+#   define PATH_MAX _POSIX_PATH_MAX
+#  else
+#   define PATH_MAX 1024         /* arbitrary; probably big enough.
+                                  * will probably only be 256+64 on
+                                  * pre-posix machines */
+#  endif /* _POSIX_PATH_MAX */
+# endif /* WIN32 */
+#endif
+
+/* : Define directory delimiter in SASL_PATH/SASL_CONF_PATH variables */
+#ifdef WIN32
+#define PATHS_DELIMITER        ';'
+#else
+#define PATHS_DELIMITER        ':'
+#endif
+
+/* Datatype Definitions */
+typedef struct {
+  const sasl_callback_t *callbacks;
+  const char *appname;
+} sasl_global_callbacks_t;
+
+extern sasl_global_callbacks_t global_callbacks;
+
+typedef struct _sasl_external_properties 
+{
+    sasl_ssf_t ssf;
+    char *auth_id;
+} _sasl_external_properties_t;
+
+typedef struct sasl_string_list
+{
+    const char *d;
+    struct sasl_string_list *next;
+} sasl_string_list_t;
+
+typedef struct buffer_info
+{ 
+    char *data;
+    size_t curlen;
+    size_t reallen;
+} buffer_info_t;
+
+typedef int add_plugin_t(const char *, void *);
+
+typedef struct add_plugin_list 
+{
+    const char *entryname;
+    add_plugin_t *add_plugin;
+} add_plugin_list_t;
+
+enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0,
+                     SASL_CONN_SERVER = 1,
+                      SASL_CONN_CLIENT = 2 };
+
+struct sasl_conn {
+  enum Sasl_conn_type type;
+
+  void (*destroy_conn)(sasl_conn_t *); /* destroy function */
+
+  char *service;
+
+  unsigned int flags;  /* flags passed to sasl_*_new */
+
+  /* IP information.  A buffer of size 52 is adequate for this in its
+     longest format (see sasl.h) */
+  int got_ip_local, got_ip_remote;
+  char iplocalport[NI_MAXHOST + NI_MAXSERV];
+  char ipremoteport[NI_MAXHOST + NI_MAXSERV];
+
+  void *context;
+  sasl_out_params_t oparams;
+
+  sasl_security_properties_t props;
+  _sasl_external_properties_t external;
+
+  sasl_secret_t *secret;
+
+  int (*idle_hook)(sasl_conn_t *conn);
+  const sasl_callback_t *callbacks;
+  const sasl_global_callbacks_t *global_callbacks; /* global callbacks
+                                                   * connection */
+  char *serverFQDN;
+
+  /* Pointers to memory that we are responsible for */
+  buffer_info_t *encode_buf;
+
+  int error_code;
+  char *error_buf, *errdetail_buf;
+  size_t error_buf_len, errdetail_buf_len;
+  char *mechlist_buf;
+  size_t mechlist_buf_len;
+
+  char *decode_buf;
+
+  char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1];
+
+  /* Allocated by sasl_encodev if the output contains multiple SASL packet. */
+  buffer_info_t multipacket_encoded_data;
+};
+
+/* Server Conn Type Information */
+
+typedef struct mechanism
+{
+    server_sasl_mechanism_t m;
+    struct mechanism *next;
+} mechanism_t;
+
+typedef struct mech_list {
+  const sasl_utils_t *utils;  /* gotten from plug_init */
+
+  void *mutex;            /* mutex for this data */ 
+  mechanism_t *mech_list; /* list of mechanisms */
+  int mech_length;       /* number of mechanisms */
+} mech_list_t;
+
+typedef struct context_list 
+{
+    mechanism_t *mech;
+    void *context;     /* if NULL, this mech is disabled for this connection
+                       * otherwise, use this context instead of a call
+                       * to mech_new */
+    struct context_list *next;
+} context_list_t;
+
+typedef struct sasl_server_conn {
+    sasl_conn_t base; /* parts common to server + client */
+
+    char *appname; /* application name buffer (for sparams) */
+    char *user_realm; /* domain the user authenticating is in */
+    int sent_last; /* Have we already done the last send? */
+    int authenticated;
+    mechanism_t *mech; /* mechanism trying to use */
+    sasl_server_params_t *sparams;
+    context_list_t *mech_contexts;
+} sasl_server_conn_t;
+
+/* Client Conn Type Information */
+
+typedef struct cmechanism
+{
+    client_sasl_mechanism_t m;
+    struct cmechanism *next;  
+} cmechanism_t;
+
+typedef struct cmech_list {
+  const sasl_utils_t *utils; 
+
+  void *mutex;            /* mutex for this data */ 
+  cmechanism_t *mech_list; /* list of mechanisms */
+  int mech_length;       /* number of mechanisms */
+
+} cmech_list_t;
+
+typedef struct sasl_client_conn {
+  sasl_conn_t base; /* parts common to server + client */
+
+  cmechanism_t *mech;
+  sasl_client_params_t *cparams;
+
+  char *clientFQDN;
+
+} sasl_client_conn_t;
+
+typedef struct sasl_allocation_utils {
+  sasl_malloc_t *malloc;
+  sasl_calloc_t *calloc;
+  sasl_realloc_t *realloc;
+  sasl_free_t *free;
+} sasl_allocation_utils_t;
+
+typedef struct sasl_mutex_utils {
+  sasl_mutex_alloc_t *alloc;
+  sasl_mutex_lock_t *lock;
+  sasl_mutex_unlock_t *unlock;
+  sasl_mutex_free_t *free;
+} sasl_mutex_utils_t;
+
+typedef struct sasl_log_utils_s {
+  sasl_log_t *log;
+} sasl_log_utils_t;
+
+typedef int sasl_plaintext_verifier(sasl_conn_t *conn,
+                                   const char *userid,
+                                   const char *passwd,
+                                   const char *service,
+                                   const char *user_realm);
+
+struct sasl_verify_password_s {
+    char *name;
+    sasl_plaintext_verifier *verify;
+};
+
+/*
+ * globals & constants
+ */
+/*
+ * common.c
+ */
+LIBSASL_API const sasl_utils_t *sasl_global_utils;
+
+extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn);
+extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn);
+
+/* These return SASL_OK if we've actually finished cleanup, 
+ * SASL_NOTINIT if that part of the library isn't initialized, and
+ * SASL_CONTINUE if we need to call them again */
+extern int (*_sasl_client_cleanup_hook)(void);
+extern int (*_sasl_server_cleanup_hook)(void);
+
+extern sasl_allocation_utils_t _sasl_allocation_utils;
+extern sasl_mutex_utils_t _sasl_mutex_utils;
+
+/*
+ * checkpw.c
+ */
+extern struct sasl_verify_password_s _sasl_verify_password[];
+
+/*
+ * server.c
+ */
+/* (this is a function call to ensure this is read-only to the outside) */
+extern int _is_sasl_server_active(void);
+
+/*
+ * Allocation and Mutex utility macros
+ */
+#define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__)))
+#define sasl_CALLOC(__nelem__, __size__) \
+       (_sasl_allocation_utils.calloc((__nelem__), (__size__)))
+#define sasl_REALLOC(__ptr__, __size__) \
+       (_sasl_allocation_utils.realloc((__ptr__), (__size__)))
+#define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__)))
+
+#define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc())
+#define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__)))
+#define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__)))
+#define sasl_MUTEX_FREE(__mutex__) \
+       (_sasl_mutex_utils.free((__mutex__)))
+
+/* function prototypes */
+/*
+ * dlopen.c and staticopen.c
+ */
+/*
+ * The differences here are:
+ * _sasl_load_plugins loads all plugins from all files
+ * _sasl_get_plugin loads the LIBRARY for an individual file
+ * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2
+ * _sasl_locate_entry locates an entrypoint in a given library
+ */
+extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
+                              const sasl_callback_t *getpath_callback,
+                              const sasl_callback_t *verifyfile_callback);
+extern int _sasl_get_plugin(const char *file,
+                           const sasl_callback_t *verifyfile_cb,
+                           void **libraryptr);
+extern int _sasl_locate_entry(void *library, const char *entryname,
+                              void **entry_point);
+extern int _sasl_done_with_plugins();
+
+
+/*
+ * common.c
+ */
+extern const sasl_callback_t *
+_sasl_find_getpath_callback(const sasl_callback_t *callbacks);
+
+extern const sasl_callback_t *
+_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks);
+
+extern const sasl_callback_t *
+_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks);
+
+extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks);
+
+extern int _sasl_conn_init(sasl_conn_t *conn,
+                          const char *service,
+                          unsigned int flags,
+                          enum Sasl_conn_type type,
+                          int (*idle_hook)(sasl_conn_t *conn),
+                          const char *serverFQDN,
+                          const char *iplocalport,
+                          const char *ipremoteport,
+                          const sasl_callback_t *callbacks,
+                          const sasl_global_callbacks_t *global_callbacks);
+extern void _sasl_conn_dispose(sasl_conn_t *conn);
+
+extern sasl_utils_t *
+_sasl_alloc_utils(sasl_conn_t *conn,
+                 sasl_global_callbacks_t *global_callbacks);
+extern int _sasl_free_utils(const sasl_utils_t ** utils);
+
+extern int
+_sasl_getcallback(sasl_conn_t * conn,
+                 unsigned long callbackid,
+                 int (**pproc)(),
+                 void **pcontext);
+
+extern void
+_sasl_log(sasl_conn_t *conn,
+         int level,
+         const char *fmt,
+         ...);
+
+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl);
+int _sasl_add_string(char **out, size_t *alloclen,
+                    size_t *outlen, const char *add);
+
+/* More Generic Utilities in common.c */
+extern int _sasl_strdup(const char *in, char **out, size_t *outlen);
+
+/* Basically a conditional call to realloc(), if we need more */
+int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen);
+
+/* convert an iovec to a single buffer */
+int _iovec_to_buf(const struct iovec *vec,
+                 unsigned numiov, buffer_info_t **output);
+
+/* Convert between string formats and sockaddr formats */
+int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen,
+                    char *out, unsigned outlen);
+int _sasl_ipfromstring(const char *addr, struct sockaddr *out,
+                      socklen_t outlen);
+
+/*
+ * external plugin (external.c)
+ */
+int external_client_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_client_plug_t **pluglist,
+                             int *plugcount);
+int external_server_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_server_plug_t **pluglist,
+                             int *plugcount);
+
+/* Mech Listing Functions */
+int _sasl_build_mechlist(void);
+int _sasl_server_listmech(sasl_conn_t *conn,
+                         const char *user,
+                         const char *prefix,
+                         const char *sep,
+                         const char *suffix,
+                         const char **result,
+                         unsigned *plen,
+                         int *pcount);
+int _sasl_client_listmech(sasl_conn_t *conn,
+                         const char *prefix,
+                         const char *sep,
+                         const char *suffix,
+                         const char **result,
+                         unsigned *plen,
+                         int *pcount);
+/* Just create a straight list of them */
+sasl_string_list_t *_sasl_client_mechs(void);
+sasl_string_list_t *_sasl_server_mechs(void);
+
+/*
+ * config file declarations (config.c)
+ */
+extern int sasl_config_init(const char *filename);
+extern const char *sasl_config_getstring(const char *key,const char *def);
+
+/* checkpw.c */
+#ifdef DO_SASL_CHECKAPOP
+extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn,
+                                    const char *userstr,
+                                    const char *challenge,
+                                    const char *response,
+                                    const char *user_realm);
+#endif /* DO_SASL_CHECKAPOP */
+
+/* Auxprop Plugin (checkpw.c) */
+extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
+                                   int max_version,
+                                   int *out_version,
+                                   sasl_auxprop_plug_t **plug,
+                                   const char *plugname);
+
+/*
+ * auxprop.c
+ */
+extern int _sasl_auxprop_add_plugin(void *p, void *library);
+extern void _sasl_auxprop_free(void);
+extern void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
+                                unsigned flags,
+                                const char *user, unsigned ulen);
+
+/*
+ * canonusr.c
+ */
+void _sasl_canonuser_free();
+extern int internal_canonuser_init(const sasl_utils_t *utils,
+                                  int max_version,
+                                  int *out_version,
+                                  sasl_canonuser_plug_t **plug,
+                                  const char *plugname);
+extern int _sasl_canon_user(sasl_conn_t *conn,
+                           const char *user, unsigned ulen,
+                           unsigned flags,
+                           sasl_out_params_t *oparams);
+
+#endif /* SASLINT_H */
diff --git a/lib/saslutil.c b/lib/saslutil.c
new file mode 100644 (file)
index 0000000..c4b61dd
--- /dev/null
@@ -0,0 +1,675 @@
+/* saslutil.c
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: saslutil.c,v 1.44.2.1 2009/04/27 17:47:17 murch 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#include "saslint.h"
+#include <saslutil.h>
+
+/*  Contains:
+ *
+ * sasl_decode64 
+ * sasl_encode64
+ * sasl_mkchal
+ * sasl_utf8verify
+ * sasl_randcreate
+ * sasl_randfree
+ * sasl_randseed
+ * sasl_rand
+ * sasl_churn
+*/
+
+char *encode_table;
+char *decode_table;
+
+#define RPOOL_SIZE 3
+struct sasl_rand_s {
+    unsigned short pool[RPOOL_SIZE];
+    /* since the init time might be really bad let's make this lazy */
+    int initialized; 
+};
+
+#define CHAR64(c)  (((c) < 0 || (c) > 127) ? -1 : index_64[(c)])
+
+static char basis_64[] =
+   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????";
+
+static char index_64[128] = {
+    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
+    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
+    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1,
+    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
+    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
+    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
+    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
+};
+
+/* 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
+ */
+
+int sasl_encode64(const char *_in, unsigned inlen,
+                 char *_out, unsigned outmax, unsigned *outlen)
+{
+    const unsigned char *in = (const unsigned char *)_in;
+    unsigned char *out = (unsigned char *)_out;
+    unsigned char oval;
+    char *blah;
+    unsigned olen;
+
+    /* check params */
+    if ((inlen >0) && (in == NULL)) return SASL_BADPARAM;
+    
+    /* Will it fit? */
+    olen = (inlen + 2) / 3 * 4;
+    if (outlen) {
+      *outlen = olen;
+    }
+    if (outmax <= olen) {
+      return SASL_BUFOVER;
+    }
+
+    /* Do the work... */
+    blah=(char *) out;
+    while (inlen >= 3) {
+      /* user provided max buffer size; make sure we don't go over it */
+        *out++ = basis_64[in[0] >> 2];
+        *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)];
+        *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
+        *out++ = basis_64[in[2] & 0x3f];
+        in += 3;
+        inlen -= 3;
+    }
+    if (inlen > 0) {
+      /* user provided max buffer size; make sure we don't go over it */
+        *out++ = basis_64[in[0] >> 2];
+        oval = (in[0] << 4) & 0x30;
+        if (inlen > 1) oval |= in[1] >> 4;
+        *out++ = basis_64[oval];
+        *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c];
+        *out++ = '=';
+    }
+
+    *out = '\0';
+    
+    return SASL_OK;
+}
+
+/* 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_CONTINUE on a partial block,
+ * SASL_OK on success
+ */
+
+int sasl_decode64(const char *in,
+                  unsigned inlen,
+                  char *out,
+                  unsigned outmax,  /* size of the buffer, not counting the NUL */
+                  unsigned *outlen)
+{
+    unsigned len = 0;
+    unsigned j;
+    int c[4];
+    int saw_equal = 0;
+
+    /* check parameters */
+    if (out == NULL) return SASL_FAIL;
+
+    if (inlen > 0 && *in == '\r') return SASL_FAIL;
+
+    while (inlen > 3) {
+        /* No data is valid after an '=' character */
+        if (saw_equal) {
+            return SASL_BADPROT;
+        }
+
+       for (j = 0; j < 4; j++) {
+           c[j] = in[0];
+           in++;
+           inlen--;
+       }
+
+        if (CHAR64(c[0]) == -1 || CHAR64(c[1]) == -1) return SASL_BADPROT;
+        if (c[2] != '=' && CHAR64(c[2]) == -1) return SASL_BADPROT;
+        if (c[3] != '=' && CHAR64(c[3]) == -1) return SASL_BADPROT;
+        /* No data is valid after a '=' character, unless it is another '=' */
+        if (c[2] == '=' && c[3] != '=') return SASL_BADPROT;
+        if (c[2] == '=' || c[3] == '=') {
+            saw_equal = 1;
+        }
+
+        *out++ = (CHAR64(c[0]) << 2) | (CHAR64(c[1]) >> 4);
+        if (++len >= outmax) return SASL_BUFOVER;
+        if (c[2] != '=') {
+            *out++ = ((CHAR64(c[1]) << 4) & 0xf0) | (CHAR64(c[2]) >> 2);
+            if (++len >= outmax) return SASL_BUFOVER;
+            if (c[3] != '=') {
+                *out++ = ((CHAR64(c[2]) << 6) & 0xc0) | CHAR64(c[3]);
+                if (++len >= outmax) return SASL_BUFOVER;
+            }
+        }
+    }
+
+    if (inlen != 0) {
+        if (saw_equal) {
+            /* Unless there is CRLF at the end? */
+            return SASL_BADPROT;
+        } else {
+           return (SASL_CONTINUE);
+        }
+    }
+
+    *out = '\0'; /* NUL terminate the output string */
+
+    if (outlen) *outlen = len;
+
+    return SASL_OK;
+}
+
+/* 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
+ */
+
+int sasl_mkchal(sasl_conn_t *conn,
+               char *buf,
+               unsigned maxlen,
+               unsigned hostflag)
+{
+  sasl_rand_t *pool = NULL;
+  unsigned long randnum;
+  int ret;
+  time_t now;
+  unsigned len;
+
+  len = 4                      /* <.>\0 */
+    + (2 * 20);                        /* 2 numbers, 20 => max size of 64bit
+                                * ulong in base 10 */
+  if (hostflag && conn->serverFQDN)
+    len += (unsigned) strlen(conn->serverFQDN) + 1 /* for the @ */;
+
+  if (maxlen < len)
+    return 0;
+
+  ret = sasl_randcreate(&pool);
+  if(ret != SASL_OK) return 0; /* xxx sasl return code? */
+
+  sasl_rand(pool, (char *)&randnum, sizeof(randnum));
+  sasl_randfree(&pool);
+
+  time(&now);
+
+  if (hostflag && conn->serverFQDN)
+    snprintf(buf,maxlen, "<%lu.%lu@%s>", randnum, now, conn->serverFQDN);
+  else
+    snprintf(buf,maxlen, "<%lu.%lu>", randnum, now);
+
+  return (int) strlen(buf);
+}
+
+  /* borrowed from larry. probably works :)
+   * probably is also in acap server somewhere
+   */
+int sasl_utf8verify(const char *str, unsigned len)
+{
+  unsigned i;
+  for (i = 0; i < len; i++) {
+    /* how many octets? */
+    int seqlen = 0;
+    while (str[i] & (0x80 >> seqlen)) ++seqlen;
+    if (seqlen == 0) continue; /* this is a valid US-ASCII char */
+    if (seqlen == 1) return SASL_BADPROT; /* this shouldn't happen here */
+    if (seqlen > 6) return SASL_BADPROT; /* illegal */
+    while (--seqlen)
+      if ((str[++i] & 0xC0) != 0xF0) return SASL_BADPROT; /* needed a 10 octet */
+  }
+  return SASL_OK;
+}      
+
+/* 
+ * To see why this is really bad see RFC 1750
+ *
+ * unfortunatly there currently is no way to make 
+ * cryptographically secure pseudo random numbers
+ * without specialized hardware etc...
+ * thus, this is for nonce use only
+ */
+void getranddata(unsigned short ret[RPOOL_SIZE])
+{
+    long curtime;
+    
+    memset(ret, 0, RPOOL_SIZE*sizeof(unsigned short));
+
+#ifdef DEV_RANDOM    
+    {
+       int fd;
+
+       fd = open(DEV_RANDOM, O_RDONLY);
+       if(fd != -1) {
+           unsigned char *buf = (unsigned char *)ret;
+           ssize_t bytesread = 0;
+           size_t bytesleft = RPOOL_SIZE*sizeof(unsigned short);
+           
+           do {
+               bytesread = read(fd, buf, bytesleft);
+               if(bytesread == -1 && errno == EINTR) continue;
+               else if(bytesread <= 0) break;
+               bytesleft -= bytesread;
+               buf += bytesread;
+           } while(bytesleft != 0);
+               
+           close(fd);
+       }
+    }
+#endif
+
+#ifdef HAVE_GETPID
+    ret[0] ^= (unsigned short) getpid();
+#endif
+
+#ifdef HAVE_GETTIMEOFDAY
+    {
+       struct timeval tv;
+       
+       /* xxx autoconf macro */
+#ifdef _SVID_GETTOD
+       if (!gettimeofday(&tv))
+#else
+       if (!gettimeofday(&tv, NULL))
+#endif
+       {
+           /* longs are guaranteed to be at least 32 bits; we need
+              16 bits in each short */
+           ret[0] ^= (unsigned short) (tv.tv_sec & 0xFFFF);
+           ret[1] ^= (unsigned short) (clock() & 0xFFFF);
+           ret[1] ^= (unsigned short) (tv.tv_usec >> 16);
+           ret[2] ^= (unsigned short) (tv.tv_usec & 0xFFFF);
+           return;
+       }
+    }
+#endif /* HAVE_GETTIMEOFDAY */
+    
+    /* if all else fails just use time() */
+    curtime = (long) time(NULL); /* better be at least 32 bits */
+    
+    ret[0] ^= (unsigned short) (curtime >> 16);
+    ret[1] ^= (unsigned short) (curtime & 0xFFFF);
+    ret[2] ^= (unsigned short) (clock() & 0xFFFF);
+    
+    return;
+}
+
+int sasl_randcreate(sasl_rand_t **rpool)
+{
+  (*rpool)=sasl_ALLOC(sizeof(sasl_rand_t));
+  if ((*rpool) == NULL) return SASL_NOMEM;
+
+  /* init is lazy */
+  (*rpool)->initialized = 0;
+
+  return SASL_OK;
+}
+
+void sasl_randfree(sasl_rand_t **rpool)
+{
+    sasl_FREE(*rpool);
+}
+
+void sasl_randseed (sasl_rand_t *rpool, const char *seed, unsigned len)
+{
+    /* is it acceptable to just use the 1st 3 char's given??? */
+    unsigned int lup;
+
+    /* check params */
+    if (seed == NULL) return;
+    if (rpool == NULL) return;
+
+    rpool->initialized = 1;
+
+    if (len > sizeof(unsigned short)*RPOOL_SIZE)
+      len = sizeof(unsigned short)*RPOOL_SIZE;
+
+    for (lup = 0; lup < len; lup += 2)
+       rpool->pool[lup/2] = (seed[lup] << 8) + seed[lup + 1];
+}
+
+static void randinit(sasl_rand_t *rpool)
+{
+    if (!rpool) return;
+    
+    if (!rpool->initialized) {
+       getranddata(rpool->pool);
+       rpool->initialized = 1;
+#if !(defined(WIN32)||defined(macintosh))
+#ifndef HAVE_JRAND48
+    {
+      /* xxx varies by platform */
+       unsigned int *foo = (unsigned int *)rpool->pool;
+       srandom(*foo);
+    }
+#endif /* HAVE_JRAND48 */
+#endif /* WIN32 */
+    }
+
+}
+
+void sasl_rand (sasl_rand_t *rpool, char *buf, unsigned len)
+{
+    unsigned int lup;
+    /* check params */
+    if (!rpool || !buf) return;
+    
+    /* init if necessary */
+    randinit(rpool);
+#if (defined(WIN32)||defined(macintosh))
+    for (lup=0;lup<len;lup++)
+       buf[lup] = (char) (rand() >> 8);
+#else /* WIN32 */
+#ifdef HAVE_JRAND48
+    for (lup=0; lup<len; lup++)
+       buf[lup] = (char) (jrand48(rpool->pool) >> 8);
+#else
+    for (lup=0;lup<len;lup++)
+       buf[lup] = (char) (random() >> 8);
+#endif /* HAVE_JRAND48 */
+#endif /* WIN32 */
+}
+
+/* this function is just a bad idea all around, since we're not trying to
+   implement a true random number generator */
+void sasl_churn (sasl_rand_t *rpool, const char *data, unsigned len)
+{
+    unsigned int lup;
+    
+    /* check params */
+    if (!rpool || !data) return;
+    
+    /* init if necessary */
+    randinit(rpool);
+    
+    for (lup=0; lup<len; lup++)
+       rpool->pool[lup % RPOOL_SIZE] ^= data[lup];
+}
+
+void sasl_erasebuffer(char *buf, unsigned len) {
+    memset(buf, 0, len);
+}
+
+#ifdef WIN32
+/***************************************************************************** 
+ * 
+ *  MODULE NAME : GETOPT.C 
+ * 
+ *  COPYRIGHTS: 
+ *             This module contains code made available by IBM 
+ *             Corporation on an AS IS basis.  Any one receiving the 
+ *             module is considered to be licensed under IBM copyrights 
+ *             to use the IBM-provided source code in any way he or she 
+ *             deems fit, including copying it, compiling it, modifying 
+ *             it, and redistributing it, with or without 
+ *             modifications.  No license under any IBM patents or 
+ *             patent applications is to be implied from this copyright 
+ *             license. 
+ * 
+ *             A user of the module should understand that IBM cannot 
+ *             provide technical support for the module and will not be 
+ *             responsible for any consequences of use of the program. 
+ * 
+ *             Any notices, including this one, are not to be removed 
+ *             from the module without the prior written consent of 
+ *             IBM. 
+ * 
+ *  AUTHOR:   Original author: 
+ *                 G. R. Blair (BOBBLAIR at AUSVM1) 
+ *                 Internet: bobblair@bobblair.austin.ibm.com 
+ * 
+ *            Extensively revised by: 
+ *                 John Q. Walker II, Ph.D. (JOHHQ at RALVM6) 
+ *                 Internet: johnq@ralvm6.vnet.ibm.com 
+ * 
+ *****************************************************************************/ 
+/****************************************************************************** 
+ * getopt() 
+ * 
+ * The getopt() function is a command line parser.  It returns the next 
+ * option character in argv that matches an option character in opstring. 
+ * 
+ * The argv argument points to an array of argc+1 elements containing argc 
+ * pointers to character strings followed by a null pointer. 
+ * 
+ * The opstring argument points to a string of option characters; if an 
+ * option character is followed by a colon, the option is expected to have 
+ * an argument that may or may not be separated from it by white space. 
+ * The external variable optarg is set to point to the start of the option 
+ * argument on return from getopt(). 
+ * 
+ * The getopt() function places in optind the argv index of the next argument 
+ * to be processed.  The system initializes the external variable optind to 
+ * 1 before the first call to getopt(). 
+ * 
+ * When all options have been processed (that is, up to the first nonoption 
+ * argument), getopt() returns EOF.  The special option "--" may be used to 
+ * delimit the end of the options; EOF will be returned, and "--" will be 
+ * skipped. 
+ * 
+ * The getopt() function returns a question mark (?) when it encounters an 
+ * option character not included in opstring.  This error message can be 
+ * disabled by setting opterr to zero.  Otherwise, it returns the option 
+ * character that was detected. 
+ * 
+ * If the special option "--" is detected, or all options have been 
+ * processed, EOF is returned. 
+ * 
+ * Options are marked by either a minus sign (-) or a slash (/). 
+ * 
+ * No errors are defined. 
+ *****************************************************************************/ 
+#include <string.h>                 /* for strchr() */ 
+/* static (global) variables that are specified as exported by getopt() */ 
+__declspec(dllexport) char *optarg = NULL;    /* pointer to the start of the option argument  */ 
+__declspec(dllexport) int   optind = 1;       /* number of the next argv[] to be evaluated    */ 
+__declspec(dllexport) int   opterr = 1;       /* non-zero if a question mark should be returned */
+
+/* handle possible future character set concerns by putting this in a macro */ 
+#define _next_char(string)  (char)(*(string+1)) 
+int getopt(int argc, char *argv[], char *opstring) 
+{ 
+    static char *pIndexPosition = NULL; /* place inside current argv string */ 
+    char *pArgString = NULL;        /* where to start from next */ 
+    char *pOptString;               /* the string in our program */ 
+    if (pIndexPosition != NULL) { 
+        /* we last left off inside an argv string */ 
+        if (*(++pIndexPosition)) { 
+            /* there is more to come in the most recent argv */ 
+            pArgString = pIndexPosition; 
+        } 
+    } 
+    if (pArgString == NULL) { 
+        /* we didn't leave off in the middle of an argv string */ 
+        if (optind >= argc) { 
+            /* more command-line arguments than the argument count */ 
+            pIndexPosition = NULL;  /* not in the middle of anything */ 
+            return EOF;             /* used up all command-line arguments */ 
+        } 
+        /*--------------------------------------------------------------------- 
+         * If the next argv[] is not an option, there can be no more options. 
+         *-------------------------------------------------------------------*/ 
+        pArgString = argv[optind++]; /* set this to the next argument ptr */ 
+        if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ 
+            ('-' != *pArgString)) { 
+            --optind;               /* point to current arg once we're done */ 
+            optarg = NULL;          /* no argument follows the option */ 
+            pIndexPosition = NULL;  /* not in the middle of anything */ 
+            return EOF;             /* used up all the command-line flags */ 
+        } 
+        /* check for special end-of-flags markers */ 
+        if ((strcmp(pArgString, "-") == 0) || 
+            (strcmp(pArgString, "--") == 0)) { 
+            optarg = NULL;          /* no argument follows the option */ 
+            pIndexPosition = NULL;  /* not in the middle of anything */ 
+            return EOF;             /* encountered the special flag */ 
+        } 
+        pArgString++;               /* look past the / or - */ 
+    } 
+    if (':' == *pArgString) {       /* is it a colon? */ 
+        /*--------------------------------------------------------------------- 
+         * Rare case: if opterr is non-zero, return a question mark; 
+         * otherwise, just return the colon we're on. 
+         *-------------------------------------------------------------------*/ 
+        return (opterr ? (int)'?' : (int)':'); 
+    } 
+    else if ((pOptString = strchr(opstring, *pArgString)) == 0) { 
+        /*--------------------------------------------------------------------- 
+         * The letter on the command-line wasn't any good. 
+         *-------------------------------------------------------------------*/ 
+        optarg = NULL;              /* no argument follows the option */ 
+        pIndexPosition = NULL;      /* not in the middle of anything */ 
+        return (opterr ? (int)'?' : (int)*pArgString); 
+    } 
+    else { 
+        /*--------------------------------------------------------------------- 
+         * The letter on the command-line matches one we expect to see 
+         *-------------------------------------------------------------------*/ 
+        if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ 
+            /* It is a colon.  Look for an argument string. */ 
+            if ('\0' != _next_char(pArgString)) {  /* argument in this argv? */ 
+                optarg = &pArgString[1];   /* Yes, it is */ 
+            } 
+            else { 
+                /*------------------------------------------------------------- 
+                 * The argument string must be in the next argv. 
+                 * But, what if there is none (bad input from the user)? 
+                 * In that case, return the letter, and optarg as NULL. 
+                 *-----------------------------------------------------------*/ 
+                if (optind < argc) 
+                    optarg = argv[optind++]; 
+                else { 
+                    optarg = NULL; 
+                    return (opterr ? (int)'?' : (int)*pArgString); 
+                } 
+            } 
+            pIndexPosition = NULL;  /* not in the middle of anything */ 
+        } 
+        else { 
+            /* it's not a colon, so just return the letter */ 
+            optarg = NULL;          /* no argument follows the option */ 
+            pIndexPosition = pArgString;    /* point to the letter we're on */ 
+        } 
+        return (int)*pArgString;    /* return the letter that matched */ 
+    } 
+} 
+
+#ifndef PASSWORD_MAX
+#  define PASSWORD_MAX 255
+#endif
+
+#include <conio.h>
+char *
+getpass(prompt)
+const char *prompt;
+{
+       register char *p;
+       register c;
+       static char pbuf[PASSWORD_MAX];
+
+       fprintf(stderr, "%s", prompt); (void) fflush(stderr);
+       for (p=pbuf; (c = _getch())!=13 && c!=EOF;) {
+               if (p < &pbuf[sizeof(pbuf)-1])
+                       *p++ = c;
+       }
+       *p = '\0';
+       fprintf(stderr, "\n"); (void) fflush(stderr);
+       return(pbuf);
+}
+
+
+
+#endif /* WIN32 */
diff --git a/lib/server.c b/lib/server.c
new file mode 100644 (file)
index 0000000..1533c10
--- /dev/null
@@ -0,0 +1,2125 @@
+/* SASL server API implementation
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: server.c,v 1.146 2006/04/26 17:45:53 murch 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.
+ */
+
+/* local functions/structs don't start with sasl
+ */
+#include <config.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#ifndef macintosh
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sasl.h"
+#include "saslint.h"
+#include "saslplug.h"
+#include "saslutil.h"
+
+#ifdef sun
+/* gotta define gethostname ourselves on suns */
+extern int gethostname(char *, int);
+#endif
+
+#define DEFAULT_CHECKPASS_MECH "auxprop"
+
+/* Contains functions:
+ * 
+ * sasl_server_init
+ * sasl_server_new
+ * sasl_listmech
+ * sasl_server_start
+ * sasl_server_step
+ * sasl_checkpass
+ * sasl_checkapop
+ * sasl_user_exists
+ * sasl_setpass
+ */
+
+/* if we've initialized the server sucessfully */
+static int _sasl_server_active = 0;
+
+/* For access by other modules */
+int _is_sasl_server_active(void) { return _sasl_server_active; }
+
+static int _sasl_checkpass(sasl_conn_t *conn, 
+                          const char *user, unsigned userlen,
+                          const char *pass, unsigned passlen);
+
+static mech_list_t *mechlist = NULL; /* global var which holds the list */
+
+sasl_global_callbacks_t global_callbacks;
+
+/* 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
+ */
+
+int sasl_setpass(sasl_conn_t *conn,
+                const char *user,
+                const char *pass, unsigned passlen,
+                const char *oldpass,
+                unsigned oldpasslen,
+                unsigned flags)
+{
+    int result = SASL_OK, tmpresult;
+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
+    const char *password_request[] = { SASL_AUX_PASSWORD_PROP, NULL };
+    sasl_server_userdb_setpass_t *setpass_cb = NULL;
+    void *context = NULL;
+    int tried_setpass = 0;
+    mechanism_t *sm;
+    server_sasl_mechanism_t *m;
+    char *current_mech;
+     
+    if (!_sasl_server_active || !mechlist) return SASL_NOTINIT;
+
+    /* check params */
+    if (!conn) return SASL_BADPARAM;
+    if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn);
+     
+    if ((!(flags & SASL_SET_DISABLE) && passlen == 0)
+        || ((flags & SASL_SET_CREATE) && (flags & SASL_SET_DISABLE)))
+       PARAMERROR(conn);
+
+    /* Check that we have an active SASL mechanism */
+    if (sasl_getprop (conn,
+                     SASL_MECHNAME,
+                     (const void **) &current_mech) != SASL_OK) {
+       current_mech = NULL;
+    }
+
+    if ( (flags & SASL_SET_CURMECH_ONLY) &&
+        (current_mech == NULL) ) {
+       sasl_seterror( conn, SASL_NOLOG,
+                  "No current SASL mechanism available");
+       RETURN(conn, SASL_BADPARAM);
+    }
+
+    /* Do we want to store SASL_AUX_PASSWORD_PROP (plain text)?  and
+     * Do we have an auxprop backend that can store properties?
+     */
+    if ((flags & SASL_SET_DISABLE || !(flags & SASL_SET_NOPLAIN)) &&
+       sasl_auxprop_store(NULL, NULL, NULL) == SASL_OK) {
+
+       tried_setpass++;
+
+       if (flags & SASL_SET_DISABLE) {
+           pass = NULL;
+           passlen = 0;
+       }
+
+       result = prop_request(s_conn->sparams->propctx, password_request);
+       if (result == SASL_OK) {
+           result = prop_set(s_conn->sparams->propctx, SASL_AUX_PASSWORD_PROP,
+                             pass, passlen);
+       }
+       if (result == SASL_OK) {
+           result = sasl_auxprop_store(conn, s_conn->sparams->propctx, user);
+       }
+       if (result != SASL_OK) {
+           _sasl_log(conn, SASL_LOG_ERR,
+                     "setpass failed for %s: %z",
+                     user, result);
+       } else {
+           _sasl_log(conn, SASL_LOG_NOTE,
+                     "setpass succeeded for %s", user);
+       }
+    }
+
+    /* We want to preserve the current value of result, so we use tmpresult below */
+
+    /* call userdb callback function */
+    tmpresult = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_SETPASS,
+                              &setpass_cb, &context);
+    if (tmpresult == SASL_OK && setpass_cb) {
+
+       tried_setpass++;
+
+       tmpresult = setpass_cb(conn, context, user, pass, passlen,
+                           s_conn->sparams->propctx, flags);
+       if(tmpresult != SASL_OK) {
+           result = tmpresult;
+           _sasl_log(conn, SASL_LOG_ERR,
+                     "setpass callback failed for %s: %z",
+                     user, tmpresult);
+       } else {
+           _sasl_log(conn, SASL_LOG_NOTE,
+                     "setpass callback succeeded for %s", user);
+       }
+    }
+
+    /* now we let the mechanisms set their secrets */
+    for (sm = mechlist->mech_list; sm; sm = sm->next) {
+       m = &sm->m;
+
+       if (!m->plug->setpass) {
+           /* can't set pass for this mech */
+           continue;
+       }
+
+       /* Invoke only one setpass for the currently selected mechanism,
+          if SASL_SET_CURMECH_ONLY is specified */
+       if ((flags & SASL_SET_CURMECH_ONLY) &&
+           (strcmp(current_mech, m->plug->mech_name) != 0)) {
+           continue;
+       }
+
+       tried_setpass++;
+
+       tmpresult = m->plug->setpass(m->plug->glob_context,
+                                    ((sasl_server_conn_t *)conn)->sparams,
+                                    user,
+                                    pass,
+                                    passlen,
+                                    oldpass, oldpasslen,
+                                    flags);
+       if (tmpresult == SASL_OK) {
+           _sasl_log(conn, SASL_LOG_NOTE,
+                     "%s: set secret for %s", m->plug->mech_name, user);
+
+           m->condition = SASL_OK; /* if we previously thought the
+                                      mechanism didn't have any user secrets 
+                                      we now think it does */
+
+       } else if (tmpresult == SASL_NOCHANGE) {
+           _sasl_log(conn, SASL_LOG_NOTE,
+                     "%s: secret not changed for %s", m->plug->mech_name, user);
+       } else {
+           result = tmpresult;
+           _sasl_log(conn, SASL_LOG_ERR,
+                     "%s: failed to set secret for %s: %z (%m)",
+                     m->plug->mech_name, user, tmpresult,
+#ifndef WIN32
+                     errno
+#else
+                     GetLastError()
+#endif
+                     );
+       }
+    }
+
+    if (!tried_setpass) {
+       _sasl_log(conn, SASL_LOG_WARN,
+                 "secret not changed for %s: "
+                 "no writable auxprop plugin or setpass callback found",
+                 user);
+    }
+
+    RETURN(conn, result);
+}
+
+/* local mechanism which disposes of server */
+static void server_dispose(sasl_conn_t *pconn)
+{
+  sasl_server_conn_t *s_conn=  (sasl_server_conn_t *) pconn;
+  context_list_t *cur, *cur_next;
+  
+  if (s_conn->mech
+      && s_conn->mech->m.plug->mech_dispose) {
+    s_conn->mech->m.plug->mech_dispose(pconn->context,
+                                    s_conn->sparams->utils);
+  }
+  pconn->context = NULL;
+
+  for(cur = s_conn->mech_contexts; cur; cur=cur_next) {
+      cur_next = cur->next;
+      if(cur->context)
+         cur->mech->m.plug->mech_dispose(cur->context, s_conn->sparams->utils);
+      sasl_FREE(cur);
+  }  
+  s_conn->mech_contexts = NULL;
+  
+  _sasl_free_utils(&s_conn->sparams->utils);
+
+  if (s_conn->sparams->propctx)
+      prop_dispose(&s_conn->sparams->propctx);
+
+  if (s_conn->appname)
+      sasl_FREE(s_conn->appname);
+
+  if (s_conn->user_realm)
+      sasl_FREE(s_conn->user_realm);
+
+  if (s_conn->sparams)
+      sasl_FREE(s_conn->sparams);
+
+  _sasl_conn_dispose(pconn);
+}
+
+static int init_mechlist(void)
+{
+    sasl_utils_t *newutils = NULL;
+
+    mechlist->mutex = sasl_MUTEX_ALLOC();
+    if(!mechlist->mutex) return SASL_FAIL;
+
+    /* set util functions - need to do rest */
+    newutils = _sasl_alloc_utils(NULL, &global_callbacks);
+    if (newutils == NULL)
+       return SASL_NOMEM;
+
+    newutils->checkpass = &_sasl_checkpass;
+
+    mechlist->utils = newutils;
+    mechlist->mech_list=NULL;
+    mechlist->mech_length=0;
+
+    return SASL_OK;
+}
+
+/*
+ * parameters:
+ *  p - entry point
+ */
+int sasl_server_add_plugin(const char *plugname,
+                          sasl_server_plug_init_t *p)
+{
+    int plugcount;
+    sasl_server_plug_t *pluglist;
+    mechanism_t *mech;
+    sasl_server_plug_init_t *entry_point;
+    int result;
+    int version;
+    int lupe;
+
+    if(!plugname || !p) return SASL_BADPARAM;
+
+    entry_point = (sasl_server_plug_init_t *)p;
+
+    /* call into the shared library asking for information about it */
+    /* version is filled in with the version of the plugin */
+    result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION, &version,
+                        &pluglist, &plugcount);
+
+    if ((result != SASL_OK) && (result != SASL_NOUSER)
+        && (result != SASL_CONTINUE)) {
+       _sasl_log(NULL, SASL_LOG_DEBUG,
+                 "server add_plugin entry_point error %z\n", result);
+       return result;
+    }
+
+    /* Make sure plugin is using the same SASL version as us */
+    if (version != SASL_SERVER_PLUG_VERSION)
+    {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "version mismatch on plugin");
+       return SASL_BADVERS;
+    }
+
+    for (lupe=0;lupe < plugcount ;lupe++)
+    {
+       mech = sasl_ALLOC(sizeof(mechanism_t));
+       if (! mech) return SASL_NOMEM;
+        memset (mech, 0, sizeof(mechanism_t));
+
+       mech->m.plug = pluglist++;
+       if(_sasl_strdup(plugname, &mech->m.plugname, NULL) != SASL_OK) {
+           sasl_FREE(mech);
+           return SASL_NOMEM;
+       }
+       mech->m.version = version;
+
+       /* wheather this mech actually has any users in it's db */
+       mech->m.condition = result; /* SASL_OK, SASL_CONTINUE or SASL_NOUSER */
+
+        /* mech->m.f = NULL; */
+
+       mech->next = mechlist->mech_list;
+       mechlist->mech_list = mech;
+       mechlist->mech_length++;
+    }
+
+    return SASL_OK;
+}
+
+static int server_done(void) {
+  mechanism_t *m;
+  mechanism_t *prevm;
+
+  if(_sasl_server_active == 0)
+      return SASL_NOTINIT;
+  else
+      _sasl_server_active--;
+  
+  if(_sasl_server_active) {
+      /* Don't de-init yet! Our refcount is nonzero. */
+      return SASL_CONTINUE;
+  }
+
+  if (mechlist != NULL)
+  {
+      m=mechlist->mech_list; /* m point to beginning of the list */
+
+      while (m!=NULL)
+      {
+         prevm=m;
+         m=m->next;
+    
+         if (prevm->m.plug->mech_free) {
+             prevm->m.plug->mech_free(prevm->m.plug->glob_context,
+                                    mechlist->utils);
+         }
+
+         sasl_FREE(prevm->m.plugname);           
+         sasl_FREE(prevm);    
+      }
+      _sasl_free_utils(&mechlist->utils);
+      sasl_MUTEX_FREE(mechlist->mutex);
+      sasl_FREE(mechlist);
+      mechlist = NULL;
+  }
+
+  /* Free the auxprop plugins */
+  _sasl_auxprop_free();
+
+  global_callbacks.callbacks = NULL;
+  global_callbacks.appname = NULL;
+
+  return SASL_OK;
+}
+
+static int server_idle(sasl_conn_t *conn)
+{
+    mechanism_t *m;
+    if (! mechlist)
+       return 0;
+    
+    for (m = mechlist->mech_list;
+        m != NULL;
+        m = m->next)
+       if (m->m.plug->idle
+           &&  m->m.plug->idle(m->m.plug->glob_context,
+                             conn,
+                             conn ? ((sasl_server_conn_t *)conn)->sparams : NULL))
+           return 1;
+
+    return 0;
+}
+
+static int load_config(const sasl_callback_t *verifyfile_cb)
+{
+    int result;
+    const char *path_to_config = NULL;
+    size_t path_len;
+    char *config_filename = NULL;
+    size_t len;
+    const sasl_callback_t *getconfpath_cb = NULL;
+    const char * next;
+
+    /* If appname was not provided, behave as if there is no config file 
+        (see also sasl_config_init() */
+    if (global_callbacks.appname == NULL) {
+        return SASL_CONTINUE;
+    }
+
+    /* get the path to the config file */
+    getconfpath_cb = _sasl_find_getconfpath_callback( global_callbacks.callbacks );
+    if (getconfpath_cb == NULL) return SASL_BADPARAM;
+
+    /* getconfpath_cb->proc MUST be a sasl_getconfpath_t; if only C had a type
+       system */
+    result = ((sasl_getconfpath_t *)(getconfpath_cb->proc))(getconfpath_cb->context,
+                                                   &path_to_config);
+    if (result != SASL_OK) goto done;
+    if (path_to_config == NULL) path_to_config = "";
+
+    next = path_to_config;
+
+    while (next != NULL) {
+        next = strchr(path_to_config, PATHS_DELIMITER);
+
+        /* length = length of path + '/' + length of appname + ".conf" + 1
+            for '\0' */
+
+        if (next != NULL) {
+            path_len = next - path_to_config;
+            next++; /* Skip to the next path */
+        } else {
+            path_len = strlen(path_to_config);
+        }
+
+        len = path_len + 2 + strlen(global_callbacks.appname) + 5 + 1;
+
+        if (len > PATH_MAX ) {
+            result = SASL_FAIL;
+            goto done;
+        }
+
+        /* construct the filename for the config file */
+        config_filename = sasl_ALLOC((unsigned)len);
+        if (! config_filename) {
+            result = SASL_NOMEM;
+            goto done;
+        }
+
+        snprintf(config_filename, len, "%.*s%c%s.conf", path_len, path_to_config, 
+               HIER_DELIMITER, global_callbacks.appname);
+
+        /* Ask the application if it's safe to use this file */
+        result = ((sasl_verifyfile_t *)(verifyfile_cb->proc))(verifyfile_cb->context,
+                                               config_filename, SASL_VRFY_CONF);
+
+        /* returns SASL_CONTINUE if the config file doesn't exist */
+        if (result == SASL_OK) {
+            result = sasl_config_init(config_filename);
+
+            if (result != SASL_CONTINUE) {
+                /* We are done */
+                break;
+            }
+        }
+
+        if (config_filename) {
+            sasl_FREE(config_filename);
+            config_filename = NULL;
+        }
+
+        path_to_config = next;
+    }
+
+ done:
+    if (config_filename) sasl_FREE(config_filename);
+
+    return result;
+}
+
+/*
+ * Verify that all the callbacks are valid
+ */
+static int verify_server_callbacks(const sasl_callback_t *callbacks)
+{
+    if (callbacks == NULL) return SASL_OK;
+
+    while (callbacks->id != SASL_CB_LIST_END) {
+       if (callbacks->proc==NULL) return SASL_FAIL;
+
+       callbacks++;
+    }
+
+    return SASL_OK;
+}
+
+static char *grab_field(char *line, char **eofield)
+{
+    int d = 0;
+    char *field;
+
+    while (isspace((int) *line)) line++;
+
+    /* find end of field */
+    while (line[d] && !isspace(((int) line[d]))) d++;
+    field = sasl_ALLOC(d + 1);
+    if (!field) { return NULL; }
+    memcpy(field, line, d);
+    field[d] = '\0';
+    *eofield = line + d;
+    
+    return field;
+}
+
+struct secflag_map_s {
+    char *name;
+    int value;
+};
+
+struct secflag_map_s secflag_map[] = {
+    { "noplaintext", SASL_SEC_NOPLAINTEXT },
+    { "noactive", SASL_SEC_NOACTIVE },
+    { "nodictionary", SASL_SEC_NODICTIONARY },
+    { "forward_secrecy", SASL_SEC_FORWARD_SECRECY },
+    { "noanonymous", SASL_SEC_NOANONYMOUS },
+    { "pass_credentials", SASL_SEC_PASS_CREDENTIALS },
+    { "mutual_auth", SASL_SEC_MUTUAL_AUTH },
+    { NULL, 0x0 }
+};
+
+static int parse_mechlist_file(const char *mechlistfile)
+{
+    FILE *f;
+    char buf[1024];
+    char *t, *ptr;
+    int r = 0;
+
+    f = fopen(mechlistfile, "r");
+    if (!f) return SASL_FAIL;
+
+    r = SASL_OK;
+    while (fgets(buf, sizeof(buf), f) != NULL) {
+       mechanism_t *n = sasl_ALLOC(sizeof(mechanism_t));
+       sasl_server_plug_t *nplug;
+
+       if (n == NULL) { r = SASL_NOMEM; break; }
+       n->m.version = SASL_SERVER_PLUG_VERSION;
+       n->m.condition = SASL_CONTINUE;
+       nplug = sasl_ALLOC(sizeof(sasl_server_plug_t));
+       if (nplug == NULL) { r = SASL_NOMEM; break; }
+       memset(nplug, 0, sizeof(sasl_server_plug_t));
+
+       /* each line is:
+          plugin-file WS mech_name WS max_ssf *(WS security_flag) RET
+       */
+       
+       /* grab file */
+       n->m.f = grab_field(buf, &ptr);
+
+       /* grab mech_name */
+       nplug->mech_name = grab_field(ptr, &ptr);
+
+       /* grab max_ssf */
+       nplug->max_ssf = strtol(ptr, &ptr, 10);
+
+       /* grab security flags */
+       while (*ptr != '\n') {
+           struct secflag_map_s *map;
+
+           /* read security flag */
+           t = grab_field(ptr, &ptr);
+           map = secflag_map;
+           while (map->name) {
+               if (!strcasecmp(t, map->name)) {
+                   nplug->security_flags |= map->value;
+                   break;
+               }
+               map++;
+           }
+           if (!map->name) {
+               _sasl_log(NULL, SASL_LOG_ERR,
+                         "%s: couldn't identify flag '%s'",
+                         nplug->mech_name, t);
+           }
+           free(t);
+       }
+
+       /* insert mechanism into mechlist */
+       n->m.plug = nplug;
+       n->next = mechlist->mech_list;
+       mechlist->mech_list = n;
+       mechlist->mech_length++;
+    }
+
+    fclose(f);
+    return r;
+}
+
+/* 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 and reading of the configuration file)
+ * results:
+ *  state          -- server state
+ * returns:
+ *  SASL_OK        -- success
+ *  SASL_BADPARAM  -- error in config file
+ *  SASL_NOMEM     -- memory failure
+ *  SASL_BADVERS   -- Mechanism version mismatch
+ */
+
+int sasl_server_init(const sasl_callback_t *callbacks,
+                    const char *appname)
+{
+    int ret;
+    const sasl_callback_t *vf;
+    const char *pluginfile = NULL;
+#ifdef PIC
+    sasl_getopt_t *getopt;
+    void *context;
+#endif
+
+    const add_plugin_list_t ep_list[] = {
+       { "sasl_server_plug_init", (add_plugin_t *)sasl_server_add_plugin },
+       { "sasl_auxprop_plug_init", (add_plugin_t *)sasl_auxprop_add_plugin },
+       { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin },
+       { NULL, NULL }
+    };
+
+    /* we require the appname (if present) to be short enough to be a path */
+    if (appname != NULL && strlen(appname) >= PATH_MAX)
+       return SASL_BADPARAM;
+
+    if (_sasl_server_active) {
+       /* We're already active, just increase our refcount */
+       /* xxx do something with the callback structure? */
+       _sasl_server_active++;
+       return SASL_OK;
+    }
+    
+    ret = _sasl_common_init(&global_callbacks);
+    if (ret != SASL_OK)
+       return ret;
+    /* verify that the callbacks look ok */
+    ret = verify_server_callbacks(callbacks);
+    if (ret != SASL_OK)
+       return ret;
+
+    global_callbacks.callbacks = callbacks;
+    
+    /* A shared library calling sasl_server_init will pass NULL as appname.
+       This should retain the original appname. */
+    if (appname != NULL) {
+        global_callbacks.appname = appname;
+    }
+
+    /* If we fail now, we have to call server_done */
+    _sasl_server_active = 1;
+
+    /* allocate mechlist and set it to empty */
+    mechlist = sasl_ALLOC(sizeof(mech_list_t));
+    if (mechlist == NULL) {
+       server_done();
+       return SASL_NOMEM;
+    }
+
+    ret = init_mechlist();
+    if (ret != SASL_OK) {
+       server_done();
+       return ret;
+    }
+
+    vf = _sasl_find_verifyfile_callback(callbacks);
+
+    /* load config file if applicable */
+    ret = load_config(vf);
+    if ((ret != SASL_OK) && (ret != SASL_CONTINUE)) {
+       server_done();
+       return ret;
+    }
+
+    /* load internal plugins */
+    sasl_server_add_plugin("EXTERNAL", &external_server_plug_init);
+
+#ifdef PIC
+    /* delayed loading of plugins? (DSO only, as it doesn't
+     * make much [any] sense to delay in the static library case) */
+    if (_sasl_getcallback(NULL, SASL_CB_GETOPT, &getopt, &context) 
+          == SASL_OK) {
+       /* No sasl_conn_t was given to getcallback, so we provide the
+        * global callbacks structure */
+       ret = getopt(&global_callbacks, NULL, "plugin_list", &pluginfile, NULL);
+    }
+#endif
+    
+    if (pluginfile != NULL) {
+       /* this file should contain a list of plugins available.
+          we'll load on demand. */
+
+       /* Ask the application if it's safe to use this file */
+       ret = ((sasl_verifyfile_t *)(vf->proc))(vf->context,
+                                               pluginfile,
+                                               SASL_VRFY_CONF);
+       if (ret != SASL_OK) {
+           _sasl_log(NULL, SASL_LOG_ERR,
+                     "unable to load plugin list %s: %z", pluginfile, ret);
+       }
+       
+       if (ret == SASL_OK) {
+           ret = parse_mechlist_file(pluginfile);
+       }
+    } else {
+       /* load all plugins now */
+       ret = _sasl_load_plugins(ep_list,
+                                _sasl_find_getpath_callback(callbacks),
+                                _sasl_find_verifyfile_callback(callbacks));
+    }
+
+    if (ret == SASL_OK) {
+       _sasl_server_cleanup_hook = &server_done;
+       _sasl_server_idle_hook = &server_idle;
+
+       ret = _sasl_build_mechlist();
+    } else {
+       server_done();
+    }
+
+    return ret;
+}
+
+/*
+ * Once we have the users plaintext password we 
+ * may want to transition them. That is put entries
+ * for them in the passwd database for other
+ * stronger mechanism
+ *
+ * for example PLAIN -> CRAM-MD5
+ */
+static int
+_sasl_transition(sasl_conn_t * conn,
+                const char * pass,
+                unsigned passlen)
+{
+    const char *dotrans = "n";
+    sasl_getopt_t *getopt;
+    int result = SASL_OK;
+    void *context;
+    unsigned flags = 0;
+
+    if (! conn)
+       return SASL_BADPARAM;
+
+    if (! conn->oparams.authid)
+       PARAMERROR(conn);
+
+    /* check if this is enabled: default to false */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK)
+    {
+       getopt(context, NULL, "auto_transition", &dotrans, NULL);
+       if (dotrans == NULL) dotrans = "n";
+    }
+
+
+    if (!strcmp(dotrans, "noplain")) flags |= SASL_SET_NOPLAIN;
+
+    if (flags || *dotrans == '1' || *dotrans == 'y' ||
+       (*dotrans == 'o' && dotrans[1] == 'n') || *dotrans == 't') {
+       /* ok, it's on! */
+       _sasl_log(conn, SASL_LOG_NOTE, 
+                 "transitioning user %s to auxprop database",
+                 conn->oparams.authid);
+       result = sasl_setpass(conn,
+                             conn->oparams.authid,
+                             pass,
+                             passlen,
+                             NULL, 0, SASL_SET_CREATE | flags);
+    }
+
+    RETURN(conn,result);
+}
+
+
+/* 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
+ */
+
+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)
+{
+  int result;
+  sasl_server_conn_t *serverconn;
+  sasl_utils_t *utils;
+  sasl_getopt_t *getopt;
+  void *context;
+  const char *log_level, *auto_trans;
+
+  if (_sasl_server_active==0) return SASL_NOTINIT;
+  if (! pconn) return SASL_FAIL;
+  if (! service) return SASL_FAIL;
+
+  *pconn=sasl_ALLOC(sizeof(sasl_server_conn_t));
+  if (*pconn==NULL) return SASL_NOMEM;
+
+  memset(*pconn, 0, sizeof(sasl_server_conn_t));
+
+  serverconn = (sasl_server_conn_t *)*pconn;
+
+  /* make sparams */
+  serverconn->sparams=sasl_ALLOC(sizeof(sasl_server_params_t));
+  if (serverconn->sparams==NULL)
+      MEMERROR(*pconn);
+
+  memset(serverconn->sparams, 0, sizeof(sasl_server_params_t));
+
+  (*pconn)->destroy_conn = &server_dispose;
+  result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_SERVER,
+                          &server_idle, serverFQDN,
+                          iplocalport, ipremoteport,
+                          callbacks, &global_callbacks);
+  if (result != SASL_OK)
+      goto done_error;
+
+
+  /* set util functions - need to do rest */
+  utils=_sasl_alloc_utils(*pconn, &global_callbacks);
+  if (!utils) {
+      result = SASL_NOMEM;
+      goto done_error;
+  }
+  
+  utils->checkpass = &_sasl_checkpass;
+
+  /* Setup the propctx -> We'll assume the default size */
+  serverconn->sparams->propctx=prop_new(0);
+  if(!serverconn->sparams->propctx) {
+      result = SASL_NOMEM;
+      goto done_error;
+  }
+
+  serverconn->sparams->service = (*pconn)->service;
+  serverconn->sparams->servicelen = (unsigned) strlen((*pconn)->service);
+
+  if (global_callbacks.appname && global_callbacks.appname[0] != '\0') {
+    result = _sasl_strdup (global_callbacks.appname,
+                          &serverconn->appname,
+                          NULL);
+    if (result != SASL_OK) {
+      result = SASL_NOMEM;
+      goto done_error;
+    }
+    serverconn->sparams->appname = serverconn->appname;
+    serverconn->sparams->applen = (unsigned) strlen(serverconn->sparams->appname);
+  } else {
+    serverconn->appname = NULL;
+    serverconn->sparams->appname = NULL;
+    serverconn->sparams->applen = 0;
+  }
+
+  serverconn->sparams->serverFQDN = (*pconn)->serverFQDN;
+  serverconn->sparams->slen = (unsigned) strlen((*pconn)->serverFQDN);
+
+  if (user_realm) {
+      result = _sasl_strdup(user_realm, &serverconn->user_realm, NULL);
+      serverconn->sparams->urlen = (unsigned) strlen(user_realm);
+      serverconn->sparams->user_realm = serverconn->user_realm;
+  } else {
+      serverconn->user_realm = NULL;
+      /* the sparams is already zeroed */
+  }
+
+  serverconn->sparams->callbacks = callbacks;
+
+  log_level = auto_trans = NULL;
+  if(_sasl_getcallback(*pconn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
+    getopt(context, NULL, "log_level", &log_level, NULL);
+    getopt(context, NULL, "auto_transition", &auto_trans, NULL);
+  }
+  serverconn->sparams->log_level = log_level ? atoi(log_level) : SASL_LOG_ERR;
+
+  serverconn->sparams->utils = utils;
+
+  if (auto_trans &&
+      (*auto_trans == '1' || *auto_trans == 'y' || *auto_trans == 't' ||
+       (*auto_trans == 'o' && auto_trans[1] == 'n') ||
+       !strcmp(auto_trans, "noplain")) &&
+      sasl_auxprop_store(NULL, NULL, NULL) == SASL_OK) {
+      serverconn->sparams->transition = &_sasl_transition;
+  }
+
+  serverconn->sparams->canon_user = &_sasl_canon_user;
+  serverconn->sparams->props = serverconn->base.props;
+  serverconn->sparams->flags = flags;
+
+  if(result == SASL_OK) return SASL_OK;
+
+ done_error:
+  _sasl_conn_dispose(*pconn);
+  sasl_FREE(*pconn);
+  *pconn = NULL;
+  return result;
+}
+
+/*
+ * The rule is:
+ * IF mech strength + external strength < min ssf THEN FAIL
+ * We also have to look at the security properties and make sure
+ * that this mechanism has everything we want
+ */
+static int mech_permitted(sasl_conn_t *conn,
+                         mechanism_t *mech)
+{
+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *)conn;
+    const sasl_server_plug_t *plug;
+    int ret;
+    int myflags;
+    context_list_t *cur;
+    sasl_getopt_t *getopt;
+    void *context;
+    sasl_ssf_t minssf = 0;
+
+    if(!conn) return SASL_NOMECH;
+
+    if(! mech || ! mech->m.plug) {
+       PARAMERROR(conn);
+       return SASL_NOMECH;
+    }
+    
+    plug = mech->m.plug;
+
+    /* get the list of allowed mechanisms (default = all) */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
+            == SASL_OK) {
+       const char *mlist = NULL;
+
+       getopt(context, NULL, "mech_list", &mlist, NULL);
+
+       /* if we have a list, check the plugin against it */
+       if (mlist) {
+           const char *cp;
+
+           while (*mlist) {
+               for (cp = mlist; *cp && !isspace((int) *cp); cp++);
+               if (((size_t) (cp - mlist) == strlen(plug->mech_name)) &&
+                   !strncasecmp(mlist, plug->mech_name,
+                                strlen(plug->mech_name))) {
+                   break;
+               }
+               mlist = cp;
+               while (*mlist && isspace((int) *mlist)) mlist++;
+           }
+
+           if (!*mlist) return SASL_NOMECH;  /* reached EOS -> not in our list */
+       }
+    }
+
+    /* setup parameters for the call to mech_avail */
+    s_conn->sparams->serverFQDN=conn->serverFQDN;
+    s_conn->sparams->service=conn->service;
+    s_conn->sparams->user_realm=s_conn->user_realm;
+    s_conn->sparams->props=conn->props;
+    s_conn->sparams->external_ssf=conn->external.ssf;
+
+    /* Check if we have banished this one already */
+    for(cur = s_conn->mech_contexts; cur; cur=cur->next) {
+       if(cur->mech == mech) {
+           /* If it's not mech_avail'd, then stop now */
+           if(!cur->context) return SASL_NOMECH;
+           break;
+       }
+    }
+    
+    if (conn->props.min_ssf < conn->external.ssf) {
+       minssf = 0;
+    } else {
+       minssf = conn->props.min_ssf - conn->external.ssf;
+    }
+    
+    /* Generic mechanism */
+    if (plug->max_ssf < minssf) {
+       sasl_seterror(conn, SASL_NOLOG,
+                     "mech %s is too weak", plug->mech_name);
+       return SASL_TOOWEAK; /* too weak */
+    }
+
+    context = NULL;
+    if(plug->mech_avail
+       && (ret = plug->mech_avail(plug->glob_context,
+                          s_conn->sparams, (void **)&context)) != SASL_OK ) {
+       if(ret == SASL_NOMECH) {
+           /* Mark this mech as no good for this connection */
+           cur = sasl_ALLOC(sizeof(context_list_t));
+           if(!cur) {
+               MEMERROR(conn);
+               return SASL_NOMECH;
+           }
+           cur->context = NULL;
+           cur->mech = mech;
+           cur->next = s_conn->mech_contexts;
+           s_conn->mech_contexts = cur;
+       }
+       
+       /* SASL_NOTDONE might also get us here */
+
+       /* Error should be set by mech_avail call */
+       return SASL_NOMECH;
+    } else if(context) {
+       /* Save this context */
+       cur = sasl_ALLOC(sizeof(context_list_t));
+       if(!cur) {
+           MEMERROR(conn);
+           return SASL_NOMECH;
+       }
+       cur->context = context;
+       cur->mech = mech;
+       cur->next = s_conn->mech_contexts;
+       s_conn->mech_contexts = cur;
+    }
+    
+    /* Generic mechanism */
+    if (plug->max_ssf < minssf) {
+       sasl_seterror(conn, SASL_NOLOG, "too weak");
+       return SASL_TOOWEAK; /* too weak */
+    }
+
+    /* if there are no users in the secrets database we can't use this 
+       mechanism */
+    if (mech->m.condition == SASL_NOUSER) {
+       sasl_seterror(conn, 0, "no users in secrets db");
+       return SASL_NOMECH;
+    }
+
+    /* Can it meet our features? */
+    if ((conn->flags & SASL_NEED_PROXY) &&
+       !(plug->features & SASL_FEAT_ALLOWS_PROXY)) {
+       return SASL_NOMECH;
+    }
+    
+    /* security properties---if there are any flags that differ and are
+       in what the connection are requesting, then fail */
+    
+    /* special case plaintext */
+    myflags = conn->props.security_flags;
+
+    /* if there's an external layer this is no longer plaintext */
+    if ((conn->props.min_ssf <= conn->external.ssf) && 
+       (conn->external.ssf > 1)) {
+       myflags &= ~SASL_SEC_NOPLAINTEXT;
+    }
+
+    /* do we want to special case SASL_SEC_PASS_CREDENTIALS? nah.. */
+    if ((myflags &= (myflags ^ plug->security_flags)) != 0) {
+       sasl_seterror(conn, SASL_NOLOG,
+                     "security flags do not match required");
+       return (myflags & SASL_SEC_NOPLAINTEXT) ? SASL_ENCRYPT : SASL_NOMECH;
+    }
+
+    /* Check Features */
+    if(plug->features & SASL_FEAT_GETSECRET) {
+       /* We no longer support sasl_server_{get,put}secret */
+       sasl_seterror(conn, 0,
+                     "mech %s requires unprovided secret facility",
+                     plug->mech_name);
+       return SASL_NOMECH;
+    }
+
+    return SASL_OK;
+}
+
+/*
+ * make the authorization 
+ *
+ */
+
+static int do_authorization(sasl_server_conn_t *s_conn)
+{
+    int ret;
+    sasl_authorize_t *authproc;
+    void *auth_context;
+    
+    /* now let's see if authname is allowed to proxy for username! */
+    
+    /* check the proxy callback */
+    if (_sasl_getcallback(&s_conn->base, SASL_CB_PROXY_POLICY,
+                         &authproc, &auth_context) != SASL_OK) {
+       INTERROR(&s_conn->base, SASL_NOAUTHZ);
+    }
+
+    ret = authproc(&(s_conn->base), auth_context,
+                  s_conn->base.oparams.user, s_conn->base.oparams.ulen,
+                  s_conn->base.oparams.authid, s_conn->base.oparams.alen,
+                  s_conn->user_realm,
+                  (s_conn->user_realm ? (unsigned) strlen(s_conn->user_realm) : 0),
+                  s_conn->sparams->propctx);
+
+    RETURN(&s_conn->base, ret);
+}
+
+
+/* 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.
+ */
+int sasl_server_start(sasl_conn_t *conn,
+                     const char *mech,
+                     const char *clientin,
+                     unsigned clientinlen,
+                     const char **serverout,
+                     unsigned *serveroutlen)
+{
+    sasl_server_conn_t *s_conn=(sasl_server_conn_t *) conn;
+    int result;
+    context_list_t *cur, **prev;
+    mechanism_t *m;
+
+    if (_sasl_server_active==0) return SASL_NOTINIT;
+
+    /* make sure mech is valid mechanism
+       if not return appropriate error */
+    m=mechlist->mech_list;
+
+    /* check parameters */
+    if(!conn) return SASL_BADPARAM;
+    
+    if (!mech || ((clientin==NULL) && (clientinlen>0)))
+       PARAMERROR(conn);
+
+    if(serverout) *serverout = NULL;
+    if(serveroutlen) *serveroutlen = 0;
+
+    while (m!=NULL)
+    {
+       if ( strcasecmp(mech, m->m.plug->mech_name)==0)
+       {
+           break;
+       }
+       m=m->next;
+    }
+  
+    if (m==NULL) {
+       sasl_seterror(conn, 0, "Couldn't find mech %s", mech);
+       result = SASL_NOMECH;
+       goto done;
+    }
+
+    /* Make sure that we're willing to use this mech */
+    if ((result = mech_permitted(conn, m)) != SASL_OK) {
+       goto done;
+    }
+
+    if (m->m.condition == SASL_CONTINUE) {
+       sasl_server_plug_init_t *entry_point;
+       void *library = NULL;
+       sasl_server_plug_t *pluglist;
+       int version, plugcount;
+       int l = 0;
+
+       /* need to load this plugin */
+       result = _sasl_get_plugin(m->m.f,
+                   _sasl_find_verifyfile_callback(global_callbacks.callbacks),
+                                 &library);
+
+       if (result == SASL_OK) {
+           result = _sasl_locate_entry(library, "sasl_server_plug_init",
+                                       (void **)&entry_point);
+       }
+
+       if (result == SASL_OK) {
+           result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION,
+                                &version, &pluglist, &plugcount);
+       }
+
+       if (result == SASL_OK) {
+           /* find the correct mechanism in this plugin */
+           for (l = 0; l < plugcount; l++) {
+               if (!strcasecmp(pluglist[l].mech_name, 
+                               m->m.plug->mech_name)) break;
+           }
+           if (l == plugcount) {
+               result = SASL_NOMECH;
+           }
+       }
+       if (result == SASL_OK) {
+           /* check that the parameters are the same */
+           if ((pluglist[l].max_ssf != m->m.plug->max_ssf) ||
+               (pluglist[l].security_flags != m->m.plug->security_flags)) {
+               _sasl_log(conn, SASL_LOG_ERR, 
+                         "%s: security parameters don't match mechlist file",
+                         pluglist[l].mech_name);
+               result = SASL_NOMECH;
+           }
+       }
+       if (result == SASL_OK) {
+           /* copy mechlist over */
+           sasl_FREE((sasl_server_plug_t *) m->m.plug);
+           m->m.plug = &pluglist[l];
+           m->m.condition = SASL_OK;
+       }
+
+       if (result != SASL_OK) {
+           /* The library will eventually be freed, don't sweat it */
+           RETURN(conn, result);
+       }
+    }
+
+    /* We used to setup sparams HERE, but now it's done
+       inside of mech_permitted (which is called above) */
+    prev = &s_conn->mech_contexts;
+    for(cur = *prev; cur; prev=&cur->next,cur=cur->next) {
+       if(cur->mech == m) {
+           if(!cur->context) {
+               sasl_seterror(conn, 0,
+                             "Got past mech_permitted with a disallowed mech!");
+               return SASL_NOMECH;
+           }
+           /* If we find it, we need to pull cur out of the
+              list so it won't be freed later! */
+           (*prev)->next = cur->next;
+           conn->context = cur->context;
+           sasl_FREE(cur);
+       }
+    }
+
+    s_conn->mech = m;
+    
+    if(!conn->context) {
+       /* Note that we don't hand over a new challenge */
+       result = s_conn->mech->m.plug->mech_new(s_conn->mech->m.plug->glob_context,
+                                             s_conn->sparams,
+                                             NULL,
+                                             0,
+                                             &(conn->context));
+    } else {
+       /* the work was already done by mech_avail! */
+       result = SASL_OK;
+    }
+    
+    if (result == SASL_OK) {
+         if(clientin) {
+            if(s_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) {
+                /* Remote sent first, but mechanism does not support it.
+                 * RFC 2222 says we fail at this point. */
+                sasl_seterror(conn, 0,
+                              "Remote sent first but mech does not allow it.");
+                result = SASL_BADPROT;
+            } else {
+                /* Mech wants client-first, so let them have it */
+                result = sasl_server_step(conn,
+                                          clientin, clientinlen,
+                                          serverout, serveroutlen);
+            }
+        } else {
+            if(s_conn->mech->m.plug->features & SASL_FEAT_WANT_CLIENT_FIRST) {
+                /* Mech wants client first anyway, so we should do that */
+                *serverout = "";
+                *serveroutlen = 0;
+                result = SASL_CONTINUE;
+            } else {
+                /* Mech wants server-first, so let them have it */
+                result = sasl_server_step(conn,
+                                          clientin, clientinlen,
+                                          serverout, serveroutlen);
+            }
+       }
+    }
+
+ done:
+    if(   result != SASL_OK
+       && result != SASL_CONTINUE
+       && result != SASL_INTERACT) {
+       if(conn->context) {
+           s_conn->mech->m.plug->mech_dispose(conn->context,
+                                            s_conn->sparams->utils);
+           conn->context = NULL;
+       }
+    }
+    
+    RETURN(conn,result);
+}
+
+
+/* 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
+ *  ...
+ */
+
+int sasl_server_step(sasl_conn_t *conn,
+                    const char *clientin,
+                    unsigned clientinlen,
+                    const char **serverout,
+                    unsigned *serveroutlen)
+{
+    int ret;
+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;  /* cast */
+
+    /* check parameters */
+    if (_sasl_server_active==0) return SASL_NOTINIT;
+    if (!conn) return SASL_BADPARAM;
+    if ((clientin==NULL) && (clientinlen>0))
+       PARAMERROR(conn);
+
+    /* If we've already done the last send, return! */
+    if(s_conn->sent_last == 1) {
+       return SASL_OK;
+    }
+
+    /* Don't do another step if the plugin told us that we're done */
+    if (conn->oparams.doneflag) {
+       _sasl_log(conn, SASL_LOG_ERR, "attempting server step after doneflag");
+       return SASL_FAIL;
+    }
+
+    if(serverout) *serverout = NULL;
+    if(serveroutlen) *serveroutlen = 0;
+
+    ret = s_conn->mech->m.plug->mech_step(conn->context,
+                                       s_conn->sparams,
+                                       clientin,
+                                       clientinlen,
+                                       serverout,
+                                       serveroutlen,
+                                       &conn->oparams);
+
+    if (ret == SASL_OK) {
+       ret = do_authorization(s_conn);
+    }
+
+    if (ret == SASL_OK) {
+       /* if we're done, we need to watch out for the following:
+        * 1. the mech does server-send-last
+        * 2. the protocol does not
+        *
+        * in this case, return SASL_CONTINUE and remember we are done.
+        */
+       if(*serverout && !(conn->flags & SASL_SUCCESS_DATA)) {
+           s_conn->sent_last = 1;
+           ret = SASL_CONTINUE;
+       }
+       if(!conn->oparams.maxoutbuf) {
+           conn->oparams.maxoutbuf = conn->props.maxbufsize;
+       }
+
+       if(conn->oparams.user == NULL || conn->oparams.authid == NULL) {
+           sasl_seterror(conn, 0,
+                         "mech did not call canon_user for both authzid " \
+                         "and authid");
+           ret = SASL_BADPROT;
+       }       
+    }
+    
+    if(   ret != SASL_OK
+       && ret != SASL_CONTINUE
+       && ret != SASL_INTERACT) {
+       if(conn->context) {
+           s_conn->mech->m.plug->mech_dispose(conn->context,
+                                            s_conn->sparams->utils);
+           conn->context = NULL;
+       }
+    }
+
+    RETURN(conn, ret);
+}
+
+/* returns the length of all the mechanisms
+ * added up 
+ */
+
+static unsigned mech_names_len()
+{
+  mechanism_t *listptr;
+  unsigned result = 0;
+
+  for (listptr = mechlist->mech_list;
+       listptr;
+       listptr = listptr->next)
+    result += (unsigned) strlen(listptr->m.plug->mech_name);
+
+  return result;
+}
+
+/* This returns a list of mechanisms in a NUL-terminated string
+ *
+ * The default behavior is to seperate with spaces if sep==NULL
+ */
+int _sasl_server_listmech(sasl_conn_t *conn,
+                         const char *user __attribute__((unused)),
+                         const char *prefix,
+                         const char *sep,
+                         const char *suffix,
+                         const char **result,
+                         unsigned *plen,
+                         int *pcount)
+{
+  int lup;
+  mechanism_t *listptr;
+  int ret;
+  size_t resultlen;
+  int flag;
+  const char *mysep;
+
+  /* if there hasn't been a sasl_sever_init() fail */
+  if (_sasl_server_active==0) return SASL_NOTINIT;
+  if (!conn) return SASL_BADPARAM;
+  if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn);
+  
+  if (! result)
+      PARAMERROR(conn);
+
+  if (plen != NULL)
+      *plen = 0;
+  if (pcount != NULL)
+      *pcount = 0;
+
+  if (sep) {
+      mysep = sep;
+  } else {
+      mysep = " ";
+  }
+
+  if (! mechlist || mechlist->mech_length <= 0)
+      INTERROR(conn, SASL_NOMECH);
+
+  resultlen = (prefix ? strlen(prefix) : 0)
+            + (strlen(mysep) * (mechlist->mech_length - 1))
+           + mech_names_len()
+            + (suffix ? strlen(suffix) : 0)
+           + 1;
+  ret = _buf_alloc(&conn->mechlist_buf,
+                  &conn->mechlist_buf_len, resultlen);
+  if(ret != SASL_OK) MEMERROR(conn);
+
+  if (prefix)
+    strcpy (conn->mechlist_buf,prefix);
+  else
+    *(conn->mechlist_buf) = '\0';
+
+  listptr = mechlist->mech_list;  
+   
+  flag = 0;
+  /* make list */
+  for (lup = 0; lup < mechlist->mech_length; lup++) {
+      /* currently, we don't use the "user" parameter for anything */
+      if (mech_permitted(conn, listptr) == SASL_OK) {
+         if (pcount != NULL)
+             (*pcount)++;
+
+         /* print separator */
+         if (flag) {
+             strcat(conn->mechlist_buf, mysep);
+         } else {
+             flag = 1;
+         }
+
+         /* now print the mechanism name */
+         strcat(conn->mechlist_buf, listptr->m.plug->mech_name);
+      }
+
+      listptr = listptr->next;
+  }
+
+  if (suffix)
+      strcat(conn->mechlist_buf,suffix);
+
+  if (plen!=NULL)
+      *plen = (unsigned) strlen(conn->mechlist_buf);
+
+  *result = conn->mechlist_buf;
+
+  return SASL_OK;  
+}
+
+sasl_string_list_t *_sasl_server_mechs(void) 
+{
+  mechanism_t *listptr;
+  sasl_string_list_t *retval = NULL, *next=NULL;
+
+  if(!_sasl_server_active) return NULL;
+
+  /* make list */
+  for (listptr = mechlist->mech_list; listptr; listptr = listptr->next) {
+      next = sasl_ALLOC(sizeof(sasl_string_list_t));
+
+      if(!next && !retval) return NULL;
+      else if(!next) {
+         next = retval->next;
+         do {
+             sasl_FREE(retval);
+             retval = next;
+             next = retval->next;
+         } while(next);
+         return NULL;
+      }
+      
+      next->d = listptr->m.plug->mech_name;
+
+      if(!retval) {
+         next->next = NULL;
+         retval = next;
+      } else {
+         next->next = retval;
+         retval = next;
+      }
+  }
+
+  return retval;
+}
+
+#define EOSTR(s,n) (((s)[n] == '\0') || ((s)[n] == ' ') || ((s)[n] == '\t'))
+static int is_mech(const char *t, const char *m)
+{
+    size_t sl = strlen(m);
+    return ((!strncasecmp(m, t, sl)) && EOSTR(t, sl));
+}
+
+/* returns OK if it's valid */
+static int _sasl_checkpass(sasl_conn_t *conn,
+                          const char *user,
+                          unsigned userlen,
+                          const char *pass,
+                          unsigned passlen)
+{
+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
+    int result;
+    sasl_getopt_t *getopt;
+    sasl_server_userdb_checkpass_t *checkpass_cb;
+    void *context;
+    const char *mlist = NULL, *mech = NULL;
+    struct sasl_verify_password_s *v;
+    const char *service = conn->service;
+
+    if (!userlen) userlen = (unsigned) strlen(user);
+    if (!passlen) passlen = (unsigned) strlen(pass);
+
+    /* call userdb callback function, if available */
+    result = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_CHECKPASS,
+                              &checkpass_cb, &context);
+    if(result == SASL_OK && checkpass_cb) {
+       result = checkpass_cb(conn, context, user, pass, passlen,
+                             s_conn->sparams->propctx);
+       if(result == SASL_OK)
+           return SASL_OK;
+    }
+
+    /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
+            == SASL_OK) {
+        getopt(context, NULL, "pwcheck_method", &mlist, NULL);
+    }
+
+    if(!mlist) mlist = DEFAULT_CHECKPASS_MECH;
+
+    result = SASL_NOMECH;
+
+    mech = mlist;
+    while (*mech && result != SASL_OK) {
+       for (v = _sasl_verify_password; v->name; v++) {
+           if(is_mech(mech, v->name)) {
+               result = v->verify(conn, user, pass, service,
+                                  s_conn->user_realm);
+               break;
+           }
+       }
+       if (result != SASL_OK) {
+           /* skip to next mech in list */
+           while (*mech && !isspace((int) *mech)) mech++;
+           while (*mech && isspace((int) *mech)) mech++;
+       }
+       else if (!is_mech(mech, "auxprop") && s_conn->sparams->transition) {
+           s_conn->sparams->transition(conn, pass, passlen);
+       }
+    }
+
+    if (result == SASL_NOMECH) {
+       /* no mechanism available ?!? */
+       _sasl_log(conn, SASL_LOG_ERR, "unknown password verifier %s", mech);
+    }
+
+    if (result != SASL_OK)
+       sasl_seterror(conn, SASL_NOLOG, "checkpass failed");
+
+    RETURN(conn, result);
+}
+
+/* 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
+ */
+int sasl_checkpass(sasl_conn_t *conn,
+                  const char *user,
+                  unsigned userlen,
+                  const char *pass,
+                  unsigned passlen)
+{
+    int result;
+    
+    if (_sasl_server_active==0) return SASL_NOTINIT;
+    
+    /* check if it's just a query if we are enabled */
+    if (!user)
+       return SASL_OK;
+
+    if (!conn) return SASL_BADPARAM;
+    
+    /* check params */
+    if (pass == NULL)
+       PARAMERROR(conn);
+
+    /* canonicalize the username */
+    result = _sasl_canon_user(conn, user, userlen,
+                             SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                             &(conn->oparams));
+    if(result != SASL_OK) RETURN(conn, result);
+    user = conn->oparams.user;
+
+    /* Check the password */
+    result = _sasl_checkpass(conn, user, userlen, pass, passlen);
+
+    /* Do authorization */
+    if(result == SASL_OK) {
+      result = do_authorization((sasl_server_conn_t *)conn);
+    }
+
+    RETURN(conn,result);
+}
+
+/* check if a user exists on server
+ *  conn          -- connection context (may be NULL, used to hold last error)
+ *  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 [FIXME: currently not detected]
+ *  SASL_NOUSER   -- user not found
+ *  SASL_NOVERIFY -- user found, but no usable mechanism [FIXME: not supported]
+ *  SASL_NOMECH   -- no mechanisms enabled
+ */
+int sasl_user_exists(sasl_conn_t *conn,
+                    const char *service,
+                    const char *user_realm,
+                    const char *user) 
+{
+    int result=SASL_NOMECH;
+    const char *mlist = NULL, *mech = NULL;
+    void *context;
+    sasl_getopt_t *getopt;
+    struct sasl_verify_password_s *v;
+    
+    /* check params */
+    if (_sasl_server_active==0) return SASL_NOTINIT;
+    if (!conn) return SASL_BADPARAM;
+    if (!user || conn->type != SASL_CONN_SERVER) 
+       PARAMERROR(conn);
+
+    if(!service) service = conn->service;
+    
+    /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */
+    if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context)
+            == SASL_OK) {
+        getopt(context, NULL, "pwcheck_method", &mlist, NULL);
+    }
+
+    if(!mlist) mlist = DEFAULT_CHECKPASS_MECH;
+
+    result = SASL_NOMECH;
+
+    mech = mlist;
+    while (*mech && result != SASL_OK) {
+       for (v = _sasl_verify_password; v->name; v++) {
+           if(is_mech(mech, v->name)) {
+               result = v->verify(conn, user, NULL, service, user_realm);
+               break;
+           }
+       }
+       if (result != SASL_OK) {
+           /* skip to next mech in list */
+           while (*mech && !isspace((int) *mech)) mech++;
+           while (*mech && isspace((int) *mech)) mech++;
+       }
+    }
+
+    /* Screen out the SASL_BADPARAM response
+     * we'll get from not giving a password */
+    if(result == SASL_BADPARAM) {
+       result = SASL_OK;
+    }
+
+    if (result == SASL_NOMECH) {
+       /* no mechanism available ?!? */
+       _sasl_log(conn, SASL_LOG_ERR, "no plaintext password verifier?");
+       sasl_seterror(conn, SASL_NOLOG, "no plaintext password verifier?");
+    }
+
+    RETURN(conn, result);
+}
+
+/* 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
+ */
+int sasl_checkapop(sasl_conn_t *conn,
+#ifdef DO_SASL_CHECKAPOP
+                  const char *challenge,
+                  unsigned challen __attribute__((unused)),
+                  const char *response,
+                  unsigned resplen __attribute__((unused)))
+#else
+                  const char *challenge __attribute__((unused)),
+                  unsigned challen __attribute__((unused)),
+                  const char *response __attribute__((unused)),
+                  unsigned resplen __attribute__((unused)))
+#endif
+{
+#ifdef DO_SASL_CHECKAPOP
+    sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn;
+    char *user, *user_end;
+    const char *password_request[] = { SASL_AUX_PASSWORD, NULL };
+    size_t user_len;
+    int result;
+
+    if (_sasl_server_active==0)
+       return SASL_NOTINIT;
+
+    /* check if it's just a query if we are enabled */
+    if(!challenge)
+       return SASL_OK;
+
+    /* check params */
+    if (!conn) return SASL_BADPARAM;
+    if (!response)
+       PARAMERROR(conn);
+
+    /* Parse out username and digest.
+     *
+     * Per RFC 1939, response must be "<user> <digest>", where
+     * <digest> is a 16-octet value which is sent in hexadecimal
+     * format, using lower-case ASCII characters.
+     */
+    user_end = strrchr(response, ' ');
+    if (!user_end || strspn(user_end + 1, "0123456789abcdef") != 32) 
+    {
+        sasl_seterror(conn, 0, "Bad Digest");
+        RETURN(conn,SASL_BADPROT);
+    }
+    user_len = (size_t)(user_end - response);
+    user = sasl_ALLOC(user_len + 1);
+    memcpy(user, response, user_len);
+    user[user_len] = '\0';
+
+    result = prop_request(s_conn->sparams->propctx, password_request);
+    if(result != SASL_OK) 
+    {
+        sasl_FREE(user);
+        RETURN(conn, result);
+    }
+
+    /* erase the plaintext password */
+    s_conn->sparams->utils->prop_erase(s_conn->sparams->propctx,
+                                      password_request[0]);
+
+    /* Cannonify it */
+    result = _sasl_canon_user(conn, user, user_len,
+                             SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                             &(conn->oparams));
+    sasl_FREE(user);
+
+    if(result != SASL_OK) RETURN(conn, result);
+
+    /* Do APOP verification */
+    result = _sasl_auxprop_verify_apop(conn, conn->oparams.authid,
+       challenge, user_end + 1, s_conn->user_realm);
+
+    /* Do authorization */
+    if(result == SASL_OK) {
+      result = do_authorization((sasl_server_conn_t *)conn);
+    } else {
+        /* If verification failed, we don't want to encourage getprop to work */
+       conn->oparams.user = NULL;
+       conn->oparams.authid = NULL;
+    }
+
+    RETURN(conn, result);
+#else /* sasl_checkapop was disabled at compile time */
+    sasl_seterror(conn, SASL_NOLOG,
+       "sasl_checkapop called, but was disabled at compile time");
+    RETURN(conn, SASL_NOMECH);
+#endif /* DO_SASL_CHECKAPOP */
+}
+
+/* It would be nice if we can show other information like Author, Company, Year, plugin version */
+static void
+_sasl_print_mechanism (
+  server_sasl_mechanism_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char delimiter;
+
+    if (stage == SASL_INFO_LIST_START) {
+       printf ("List of server plugins follows\n");
+       return;
+    } else if (stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    /* Process the mechanism */
+    printf ("Plugin \"%s\" ", m->plugname);
+
+    switch (m->condition) {
+       case SASL_OK:
+           printf ("[loaded]");
+           break;
+
+       case SASL_CONTINUE:
+           printf ("[delayed]");
+           break;
+
+       case SASL_NOUSER:
+           printf ("[no users]");
+           break;
+
+       default:
+           printf ("[unknown]");
+           break;
+    }
+
+    printf (", \tAPI version: %d\n", m->version);
+
+    if (m->plug != NULL) {
+       printf ("\tSASL mechanism: %s, best SSF: %d, supports setpass: %s\n",
+               m->plug->mech_name,
+               m->plug->max_ssf,
+               (m->plug->setpass != NULL) ? "yes" : "no"
+               );
+
+
+       printf ("\tsecurity flags:");
+       
+       delimiter = ' ';
+       if (m->plug->security_flags & SASL_SEC_NOANONYMOUS) {
+           printf ("%cNO_ANONYMOUS", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_NOPLAINTEXT) {
+           printf ("%cNO_PLAINTEXT", delimiter);
+           delimiter = '|';
+       }
+       
+       if (m->plug->security_flags & SASL_SEC_NOACTIVE) {
+           printf ("%cNO_ACTIVE", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_NODICTIONARY) {
+           printf ("%cNO_DICTIONARY", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_FORWARD_SECRECY) {
+           printf ("%cFORWARD_SECRECY", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_PASS_CREDENTIALS) {
+           printf ("%cPASS_CREDENTIALS", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->security_flags & SASL_SEC_MUTUAL_AUTH) {
+           printf ("%cMUTUAL_AUTH", delimiter);
+           delimiter = '|';
+       }
+
+
+
+       printf ("\n\tfeatures:");
+       
+       delimiter = ' ';
+       if (m->plug->features & SASL_FEAT_WANT_CLIENT_FIRST) {
+           printf ("%cWANT_CLIENT_FIRST", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_SERVER_FIRST) {
+           printf ("%cSERVER_FIRST", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_ALLOWS_PROXY) {
+           printf ("%cPROXY_AUTHENTICATION", delimiter);
+           delimiter = '|';
+       }
+
+       if (m->plug->features & SASL_FEAT_NEEDSERVERFQDN) {
+           printf ("%cNEED_SERVER_FQDN", delimiter);
+           delimiter = '|';
+       }
+
+        /* Is this one used? */
+        if (m->plug->features & SASL_FEAT_SERVICE) {
+           printf ("%cSERVICE", delimiter);
+           delimiter = '|';
+       }
+
+        if (m->plug->features & SASL_FEAT_GETSECRET) {
+           printf ("%cNEED_GETSECRET", delimiter);
+           delimiter = '|';
+       }
+    }
+
+    if (m->f) {
+       printf ("\n\twill be loaded from \"%s\"", m->f);
+    }
+
+    printf ("\n");
+}
+
+/* Dump information about available server plugins (separate functions should be
+   used for canon and auxprop plugins */
+int sasl_server_plugin_info (
+  const char *c_mech_list,             /* space separated mechanism list or NULL for ALL */
+  sasl_server_info_callback_t *info_cb,
+  void *info_cb_rock
+)
+{
+    mechanism_t *m;
+    server_sasl_mechanism_t plug_data;
+    char * cur_mech;
+    char *mech_list = NULL;
+    char * p;
+
+    if (info_cb == NULL) {
+       info_cb = _sasl_print_mechanism;
+    }
+
+    if (mechlist != NULL) {
+       info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock);
+
+       if (c_mech_list == NULL) {
+           m = mechlist->mech_list; /* m point to beginning of the list */
+
+           while (m != NULL) {
+               memcpy (&plug_data, &m->m, sizeof(plug_data));
+
+               info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+           
+               m = m->next;
+           }
+       } else {
+            mech_list = strdup(c_mech_list);
+
+           cur_mech = mech_list;
+
+           while (cur_mech != NULL) {
+               p = strchr (cur_mech, ' ');
+               if (p != NULL) {
+                   *p = '\0';
+                   p++;
+               }
+
+               m = mechlist->mech_list; /* m point to beginning of the list */
+
+               while (m != NULL) {
+                   if (strcasecmp (cur_mech, m->m.plug->mech_name) == 0) {
+                       memcpy (&plug_data, &m->m, sizeof(plug_data));
+
+                       info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock);
+                   }
+           
+                   m = m->next;
+               }
+
+               cur_mech = p;
+           }
+
+            free (mech_list);
+       }
+
+       info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock);
+
+       return (SASL_OK);
+    }
+
+    return (SASL_NOTINIT);
+}
diff --git a/lib/seterror.c b/lib/seterror.c
new file mode 100644 (file)
index 0000000..5980ea7
--- /dev/null
@@ -0,0 +1,263 @@
+/* seterror.c - sasl_seterror split out because glue libraries
+ *              can't pass varargs lists
+ * Rob Siemborski
+ * Tim Martin
+ * split from common.c by Rolf Braun
+ * $Id: seterror.c,v 1.9 2003/12/12 17:30:18 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#ifdef HAVE_SYSLOG
+#include <syslog.h>
+#endif
+#include <stdarg.h>
+#include <ctype.h>
+
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+#include "saslint.h"
+
+#ifdef WIN32
+/* need to handle the fact that errno has been defined as a function
+   in a dll, not an extern int */
+# ifdef errno
+#  undef errno
+# endif /* errno */
+#endif /* WIN32 */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* this is apparently no longer a user function */
+static int _sasl_seterror_usererr(int saslerr)
+{
+    /* Hide the difference in a username failure and a password failure */
+    if (saslerr == SASL_NOUSER)
+       return SASL_BADAUTH;
+
+    /* otherwise return the error given; no transform necessary */
+    return saslerr;
+}
+
+/* set the error string which will be returned by sasl_errdetail() using  
+ *  syslog()-style formatting (e.g. printf-style with %m as the string form
+ *  of an 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
+ */
+void sasl_seterror(sasl_conn_t *conn,
+                  unsigned flags,
+                  const char *fmt, ...) 
+{
+  size_t outlen=0; /* current length of output buffer */
+  size_t pos = 0; /* current position in format string */
+  size_t formatlen;
+  int result;
+  sasl_log_t *log_cb = NULL;
+  void *log_ctx;
+  int ival;
+  char *cval;
+  va_list ap; /* varargs thing */
+  char **error_buf;
+  size_t *error_buf_len;
+
+  if(!conn) {
+#ifndef SASL_OSX_CFMGLUE
+      if(!(flags & SASL_NOLOG)) {
+         /* See if we have a logging callback... */
+         result = _sasl_getcallback(NULL, SASL_CB_LOG, &log_cb, &log_ctx);
+         if (result == SASL_OK && ! log_cb)
+             result = SASL_FAIL;
+         if (result != SASL_OK)
+             return;
+         
+         log_cb(log_ctx, SASL_LOG_FAIL,
+                "No sasl_conn_t passed to sasl_seterror");
+      }  
+#endif /* SASL_OSX_CFMGLUE */
+      return;
+  } else if(!fmt) return;    
+
+/* we need to use a back end function to get the buffer because the
+   cfm glue can't be rooting around in the internal structs */
+  _sasl_get_errorbuf(conn, &error_buf, &error_buf_len);
+
+  formatlen = strlen(fmt);
+
+  va_start(ap, fmt); /* start varargs */
+
+  while(pos<formatlen)
+  {
+    if (fmt[pos]!='%') /* regular character */
+    {
+      result = _buf_alloc(error_buf, error_buf_len, outlen+1);
+      if (result != SASL_OK)
+       return;
+      (*error_buf)[outlen]=fmt[pos];
+      outlen++;
+      pos++;
+    } else { /* formating thing */
+      int done=0;
+      char frmt[10];
+      int frmtpos=1;
+      char tempbuf[21];
+      frmt[0]='%';
+      pos++;
+
+      while (done==0)
+      {
+       switch(fmt[pos])
+         {
+         case 's': /* need to handle this */
+           cval = va_arg(ap, char *); /* get the next arg */
+           result = _sasl_add_string(error_buf, error_buf_len,
+                                     &outlen, cval);
+             
+           if (result != SASL_OK) /* add the string */
+             return;
+
+           done=1;
+           break;
+
+         case '%': /* double % output the '%' character */
+           result = _buf_alloc(error_buf, error_buf_len, outlen+1);
+           if (result != SASL_OK)
+             return;
+           (*error_buf)[outlen]='%';
+           outlen++;
+           done=1;
+           break;
+
+         case 'm': /* insert the errno string */
+           result = _sasl_add_string(error_buf, error_buf_len,
+                                     &outlen,
+                                     strerror(va_arg(ap, int)));
+           if (result != SASL_OK)
+             return;
+           done=1;
+           break;
+
+         case 'z': /* insert the sasl error string */
+           result = _sasl_add_string(error_buf, error_buf_len, &outlen,
+                        (char *)sasl_errstring(_sasl_seterror_usererr(
+                                               va_arg(ap, int)),NULL,NULL));
+           if (result != SASL_OK)
+             return;
+           done=1;
+           break;
+
+         case 'c':
+           frmt[frmtpos++]=fmt[pos];
+           frmt[frmtpos]=0;
+           tempbuf[0] = (char) va_arg(ap, int); /* get the next arg */
+           tempbuf[1]='\0';
+           
+           /* now add the character */
+           result = _sasl_add_string(error_buf, error_buf_len,
+                                     &outlen, tempbuf);
+           if (result != SASL_OK)
+             return;
+           done=1;
+           break;
+
+         case 'd':
+         case 'i':
+           frmt[frmtpos++]=fmt[pos];
+           frmt[frmtpos]=0;
+           ival = va_arg(ap, int); /* get the next arg */
+
+           snprintf(tempbuf,20,frmt,ival); /* have snprintf do the work */
+           /* now add the string */
+           result = _sasl_add_string(error_buf, error_buf_len,
+                                     &outlen, tempbuf);
+           if (result != SASL_OK)
+             return;
+           done=1;
+
+           break;
+         default: 
+           frmt[frmtpos++]=fmt[pos]; /* add to the formating */
+           frmt[frmtpos]=0;        
+           if (frmtpos>9) 
+             done=1;
+         }
+       pos++;
+       if (pos>formatlen)
+         done=1;
+      }
+
+    }
+  }
+
+  (*error_buf)[outlen]='\0'; /* put 0 at end */
+
+  va_end(ap);  
+
+#ifndef SASL_OSX_CFMGLUE
+  if(!(flags & SASL_NOLOG)) {
+      /* See if we have a logging callback... */
+      result = _sasl_getcallback(conn, SASL_CB_LOG, &log_cb, &log_ctx);
+      if (result == SASL_OK && ! log_cb)
+         result = SASL_FAIL;
+      if (result != SASL_OK)
+         return;
+      
+      result = log_cb(log_ctx, SASL_LOG_FAIL, conn->error_buf);
+  }
+#endif /* SASL_OSX_CFMGLUE */
+}
diff --git a/lib/snprintf.c b/lib/snprintf.c
new file mode 100644 (file)
index 0000000..bf88c78
--- /dev/null
@@ -0,0 +1,784 @@
+/**************************************************************
+ * Original:
+ * Patrick Powell Tue Apr 11 09:48:21 PDT 1995
+ * A bombproof version of doprnt (dopr) included.
+ * Sigh.  This sort of thing is always nasty do deal with.  Note that
+ * the version here does not include floating point...
+ *
+ * snprintf() is used instead of sprintf() as it does limit checks
+ * for string length.  This covers a nasty loophole.
+ *
+ * The other functions are there to prevent NULL pointers from
+ * causing nast effects.
+ *
+ * More Recently:
+ *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
+ *  This was ugly.  It is still ugly.  I opted out of floating point
+ *  numbers, but the formatter understands just about everything
+ *  from the normal C string format, at least as far as I can tell from
+ *  the Solaris 2.5 printf(3S) man page.
+ *
+ *  Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1
+ *    Ok, added some minimal floating point support, which means this
+ *    probably requires libm on most operating systems.  Don't yet
+ *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
+ *    was pretty badly broken, it just wasn't being exercised in ways
+ *    which showed it, so that's been fixed.  Also, formated the code
+ *    to mutt conventions, and removed dead code left over from the
+ *    original.  Also, there is now a builtin-test, just compile with:
+ *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
+ *    and run snprintf for results.
+ * 
+ *  Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i
+ *    The PGP code was using unsigned hexadecimal formats. 
+ *    Unfortunately, unsigned formats simply didn't work.
+ *
+ *  Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8
+ *    The original code assumed that both snprintf() and vsnprintf() were
+ *    missing.  Some systems only have snprintf() but not vsnprintf(), so
+ *    the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF.
+ *
+ **************************************************************/
+
+#include <config.h>
+
+#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
+
+#include <string.h>
+# include <ctype.h>
+#include <sys/types.h>
+
+/* varargs declarations: */
+
+#if defined(HAVE_STDARG_H)
+# include <stdarg.h>
+# define HAVE_STDARGS    /* let's hope that works everywhere (mj) */
+# define VA_LOCAL_DECL   va_list ap
+# define VA_START(f)     va_start(ap, f)
+# define VA_SHIFT(v,t)  ;   /* no-op for ANSI */
+# define VA_END          va_end(ap)
+#else
+# if defined(HAVE_VARARGS_H)
+#  include <varargs.h>
+#  undef HAVE_STDARGS
+#  define VA_LOCAL_DECL   va_list ap
+#  define VA_START(f)     va_start(ap)      /* f is ignored! */
+#  define VA_SHIFT(v,t) v = va_arg(ap,t)
+#  define VA_END        va_end(ap)
+# else
+/*XX ** NO VARARGS ** XX*/
+# endif
+#endif
+
+/*int snprintf (char *str, size_t count, const char *fmt, ...);*/
+/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/
+
+static void dopr (char *buffer, size_t maxlen, const char *format, 
+                  va_list args);
+static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
+                   char *value, int flags, int min, int max);
+static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
+                   long value, int base, int min, int max, int flags);
+static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
+                  long double fvalue, int min, int max, int flags);
+static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c );
+
+/*
+ * dopr(): poor man's version of doprintf
+ */
+
+/* format read states */
+#define DP_S_DEFAULT 0
+#define DP_S_FLAGS   1
+#define DP_S_MIN     2
+#define DP_S_DOT     3
+#define DP_S_MAX     4
+#define DP_S_MOD     5
+#define DP_S_CONV    6
+#define DP_S_DONE    7
+
+/* format flags - Bits */
+#define DP_F_MINUS     (1 << 0)
+#define DP_F_PLUS      (1 << 1)
+#define DP_F_SPACE     (1 << 2)
+#define DP_F_NUM       (1 << 3)
+#define DP_F_ZERO      (1 << 4)
+#define DP_F_UP        (1 << 5)
+#define DP_F_UNSIGNED  (1 << 6)
+
+/* Conversion Flags */
+#define DP_C_SHORT   1
+#define DP_C_LONG    2
+#define DP_C_LDOUBLE 3
+
+#define char_to_int(p) (p - '0')
+#define MAX(p,q) ((p >= q) ? p : q)
+
+static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
+{
+  char ch;
+  long value;
+  long double fvalue;
+  char *strvalue;
+  int min;
+  int max;
+  int state;
+  int flags;
+  int cflags;
+  size_t currlen;
+  
+  state = DP_S_DEFAULT;
+  currlen = flags = cflags = min = 0;
+  max = -1;
+  ch = *format++;
+
+  while (state != DP_S_DONE)
+  {
+    if ((ch == '\0') || (currlen >= maxlen)) 
+      state = DP_S_DONE;
+
+    switch(state) 
+    {
+    case DP_S_DEFAULT:
+      if (ch == '%') 
+       state = DP_S_FLAGS;
+      else 
+       dopr_outch (buffer, &currlen, maxlen, ch);
+      ch = *format++;
+      break;
+    case DP_S_FLAGS:
+      switch (ch) 
+      {
+      case '-':
+       flags |= DP_F_MINUS;
+        ch = *format++;
+       break;
+      case '+':
+       flags |= DP_F_PLUS;
+        ch = *format++;
+       break;
+      case ' ':
+       flags |= DP_F_SPACE;
+        ch = *format++;
+       break;
+      case '#':
+       flags |= DP_F_NUM;
+        ch = *format++;
+       break;
+      case '0':
+       flags |= DP_F_ZERO;
+        ch = *format++;
+       break;
+      default:
+       state = DP_S_MIN;
+       break;
+      }
+      break;
+    case DP_S_MIN:
+      if (isdigit((unsigned char)ch)) 
+      {
+       min = 10*min + char_to_int (ch);
+       ch = *format++;
+      } 
+      else if (ch == '*') 
+      {
+       min = va_arg (args, int);
+       ch = *format++;
+       state = DP_S_DOT;
+      } 
+      else 
+       state = DP_S_DOT;
+      break;
+    case DP_S_DOT:
+      if (ch == '.') 
+      {
+       state = DP_S_MAX;
+       ch = *format++;
+      } 
+      else 
+       state = DP_S_MOD;
+      break;
+    case DP_S_MAX:
+      if (isdigit((unsigned char)ch)) 
+      {
+       if (max < 0)
+         max = 0;
+       max = 10*max + char_to_int (ch);
+       ch = *format++;
+      } 
+      else if (ch == '*') 
+      {
+       max = va_arg (args, int);
+       ch = *format++;
+       state = DP_S_MOD;
+      } 
+      else 
+       state = DP_S_MOD;
+      break;
+    case DP_S_MOD:
+      /* Currently, we don't support Long Long, bummer */
+      switch (ch) 
+      {
+      case 'h':
+       cflags = DP_C_SHORT;
+       ch = *format++;
+       break;
+      case 'l':
+       cflags = DP_C_LONG;
+       ch = *format++;
+       break;
+      case 'L':
+       cflags = DP_C_LDOUBLE;
+       ch = *format++;
+       break;
+      default:
+       break;
+      }
+      state = DP_S_CONV;
+      break;
+    case DP_S_CONV:
+      switch (ch) 
+      {
+      case 'd':
+      case 'i':
+       if (cflags == DP_C_SHORT) 
+         value = va_arg (args, short int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, long int);
+       else
+         value = va_arg (args, int);
+       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+       break;
+      case 'o':
+       flags |= DP_F_UNSIGNED;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned short int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags);
+       break;
+      case 'u':
+       flags |= DP_F_UNSIGNED;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned short int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags);
+       break;
+      case 'X':
+       flags |= DP_F_UP;
+      case 'x':
+       flags |= DP_F_UNSIGNED;
+       if (cflags == DP_C_SHORT)
+         value = va_arg (args, unsigned short int);
+       else if (cflags == DP_C_LONG)
+         value = va_arg (args, unsigned long int);
+       else
+         value = va_arg (args, unsigned int);
+       fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags);
+       break;
+      case 'f':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       /* um, floating point? */
+       fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
+       break;
+      case 'E':
+       flags |= DP_F_UP;
+      case 'e':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       break;
+      case 'G':
+       flags |= DP_F_UP;
+      case 'g':
+       if (cflags == DP_C_LDOUBLE)
+         fvalue = va_arg (args, long double);
+       else
+         fvalue = va_arg (args, double);
+       break;
+      case 'c':
+       dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
+       break;
+      case 's':
+       strvalue = va_arg (args, char *);
+       if (max < 0) 
+         max = maxlen; /* ie, no max */
+       fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max);
+       break;
+      case 'p':
+       strvalue = va_arg (args, void *);
+       fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags);
+       break;
+      case 'n':
+       if (cflags == DP_C_SHORT) 
+       {
+         short int *num;
+         num = va_arg (args, short int *);
+         *num = currlen;
+        } 
+       else if (cflags == DP_C_LONG) 
+       {
+         long int *num;
+         num = va_arg (args, long int *);
+         *num = currlen;
+        } 
+       else 
+       {
+         int *num;
+         num = va_arg (args, int *);
+         *num = currlen;
+        }
+       break;
+      case '%':
+       dopr_outch (buffer, &currlen, maxlen, ch);
+       break;
+      case 'w':
+       /* not supported yet, treat as next char */
+       ch = *format++;
+       break;
+      default:
+       /* Unknown, skip */
+       break;
+      }
+      ch = *format++;
+      state = DP_S_DEFAULT;
+      flags = cflags = min = 0;
+      max = -1;
+      break;
+    case DP_S_DONE:
+      break;
+    default:
+      /* hmm? */
+      break; /* some picky compilers need this */
+    }
+  }
+  if (currlen < maxlen - 1) 
+    buffer[currlen] = '\0';
+  else 
+    buffer[maxlen - 1] = '\0';
+}
+
+static void fmtstr (char *buffer, size_t *currlen, size_t maxlen,
+                   char *value, int flags, int min, int max)
+{
+  int padlen, strln;     /* amount to pad */
+  int cnt = 0;
+  
+  if (value == 0)
+  {
+    value = "<NULL>";
+  }
+
+  for (strln = 0; value[strln]; ++strln); /* strlen */
+  padlen = min - strln;
+  if (padlen < 0) 
+    padlen = 0;
+  if (flags & DP_F_MINUS) 
+    padlen = -padlen; /* Left Justify */
+
+  while ((padlen > 0) && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --padlen;
+    ++cnt;
+  }
+  while (*value && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, *value++);
+    ++cnt;
+  }
+  while ((padlen < 0) && (cnt < max)) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++padlen;
+    ++cnt;
+  }
+}
+
+/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
+
+static void fmtint (char *buffer, size_t *currlen, size_t maxlen,
+                   long value, int base, int min, int max, int flags)
+{
+  int signvalue = 0;
+  unsigned long uvalue;
+  char convert[20];
+  int place = 0;
+  int spadlen = 0; /* amount to space pad */
+  int zpadlen = 0; /* amount to zero pad */
+  int caps = 0;
+  
+  if (max < 0)
+    max = 0;
+
+  uvalue = value;
+
+  if(!(flags & DP_F_UNSIGNED))
+  {
+    if( value < 0 ) {
+      signvalue = '-';
+      uvalue = -value;
+    }
+    else
+      if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+       signvalue = '+';
+    else
+      if (flags & DP_F_SPACE)
+       signvalue = ' ';
+  }
+  
+  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
+
+  do {
+    convert[place++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")
+      [uvalue % (unsigned)base  ];
+    uvalue = (uvalue / (unsigned)base );
+  } while(uvalue && (place < 20));
+  if (place == 20) place--;
+  convert[place] = 0;
+
+  zpadlen = max - place;
+  spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
+  if (zpadlen < 0) zpadlen = 0;
+  if (spadlen < 0) spadlen = 0;
+  if (flags & DP_F_ZERO)
+  {
+    zpadlen = MAX(zpadlen, spadlen);
+    spadlen = 0;
+  }
+  if (flags & DP_F_MINUS) 
+    spadlen = -spadlen; /* Left Justifty */
+
+#ifdef DEBUG_SNPRINTF
+  dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
+      zpadlen, spadlen, min, max, place));
+#endif
+
+  /* Spaces */
+  while (spadlen > 0) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --spadlen;
+  }
+
+  /* Sign */
+  if (signvalue) 
+    dopr_outch (buffer, currlen, maxlen, signvalue);
+
+  /* Zeros */
+  if (zpadlen > 0) 
+  {
+    while (zpadlen > 0)
+    {
+      dopr_outch (buffer, currlen, maxlen, '0');
+      --zpadlen;
+    }
+  }
+
+  /* Digits */
+  while (place > 0) 
+    dopr_outch (buffer, currlen, maxlen, convert[--place]);
+  
+  /* Left Justified spaces */
+  while (spadlen < 0) {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++spadlen;
+  }
+}
+
+static long double abs_val (long double value)
+{
+  long double result = value;
+
+  if (value < 0)
+    result = -value;
+
+  return result;
+}
+
+static long double pow10 (int exp)
+{
+  long double result = 1;
+
+  while (exp)
+  {
+    result *= 10;
+    exp--;
+  }
+  
+  return result;
+}
+
+static long round (long double value)
+{
+  long intpart;
+
+  intpart = value;
+  value = value - intpart;
+  if (value >= 0.5)
+    intpart++;
+
+  return intpart;
+}
+
+static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
+                  long double fvalue, int min, int max, int flags)
+{
+  int signvalue = 0;
+  long double ufvalue;
+  char iconvert[20];
+  char fconvert[20];
+  int iplace = 0;
+  int fplace = 0;
+  int padlen = 0; /* amount to pad */
+  int zpadlen = 0; 
+  int caps = 0;
+  long intpart;
+  long fracpart;
+  
+  /* 
+   * AIX manpage says the default is 0, but Solaris says the default
+   * is 6, and sprintf on AIX defaults to 6
+   */
+  if (max < 0)
+    max = 6;
+
+  ufvalue = abs_val (fvalue);
+
+  if (fvalue < 0)
+    signvalue = '-';
+  else
+    if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
+      signvalue = '+';
+    else
+      if (flags & DP_F_SPACE)
+       signvalue = ' ';
+
+#if 0
+  if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
+#endif
+
+  intpart = ufvalue;
+
+  /* 
+   * Sorry, we only support 9 digits past the decimal because of our 
+   * conversion method
+   */
+  if (max > 9)
+    max = 9;
+
+  /* We "cheat" by converting the fractional part to integer by
+   * multiplying by a factor of 10
+   */
+  fracpart = round ((pow10 (max)) * (ufvalue - intpart));
+
+  if (fracpart >= pow10 (max))
+  {
+    intpart++;
+    fracpart -= pow10 (max);
+  }
+
+#ifdef DEBUG_SNPRINTF
+  dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart));
+#endif
+
+  /* Convert integer part */
+  do {
+    iconvert[iplace++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10];
+    intpart = (intpart / 10);
+  } while(intpart && (iplace < 20));
+  if (iplace == 20) iplace--;
+  iconvert[iplace] = 0;
+
+  /* Convert fractional part */
+  do {
+    fconvert[fplace++] =
+      (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10];
+    fracpart = (fracpart / 10);
+  } while(fracpart && (fplace < 20));
+  if (fplace == 20) fplace--;
+  fconvert[fplace] = 0;
+
+  /* -1 for decimal point, another -1 if we are printing a sign */
+  padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); 
+  zpadlen = max - fplace;
+  if (zpadlen < 0)
+    zpadlen = 0;
+  if (padlen < 0) 
+    padlen = 0;
+  if (flags & DP_F_MINUS) 
+    padlen = -padlen; /* Left Justifty */
+
+  if ((flags & DP_F_ZERO) && (padlen > 0)) 
+  {
+    if (signvalue) 
+    {
+      dopr_outch (buffer, currlen, maxlen, signvalue);
+      --padlen;
+      signvalue = 0;
+    }
+    while (padlen > 0)
+    {
+      dopr_outch (buffer, currlen, maxlen, '0');
+      --padlen;
+    }
+  }
+  while (padlen > 0)
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    --padlen;
+  }
+  if (signvalue) 
+    dopr_outch (buffer, currlen, maxlen, signvalue);
+
+  while (iplace > 0) 
+    dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]);
+
+  /*
+   * Decimal point.  This should probably use locale to find the correct
+   * char to print out.
+   */
+  dopr_outch (buffer, currlen, maxlen, '.');
+
+  while (fplace > 0) 
+    dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
+
+  while (zpadlen > 0)
+  {
+    dopr_outch (buffer, currlen, maxlen, '0');
+    --zpadlen;
+  }
+
+  while (padlen < 0) 
+  {
+    dopr_outch (buffer, currlen, maxlen, ' ');
+    ++padlen;
+  }
+}
+
+static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
+{
+  if (*currlen < maxlen)
+    buffer[(*currlen)++] = c;
+}
+#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */
+
+#ifndef HAVE_VSNPRINTF
+int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
+{
+  str[0] = 0;
+  dopr(str, count, fmt, args);
+  return(strlen(str));
+}
+#endif /* !HAVE_VSNPRINTF */
+
+#ifndef HAVE_SNPRINTF
+/* VARARGS3 */
+#ifdef HAVE_STDARGS
+int snprintf (char *str,size_t count,const char *fmt,...)
+#else
+int snprintf (va_alist) va_dcl
+#endif
+{
+#ifndef HAVE_STDARGS
+  char *str;
+  size_t count;
+  char *fmt;
+#endif
+  VA_LOCAL_DECL;
+    
+  VA_START (fmt);
+  VA_SHIFT (str, char *);
+  VA_SHIFT (count, size_t );
+  VA_SHIFT (fmt, char *);
+  (void) vsnprintf(str, count, fmt, ap);
+  VA_END;
+  return(strlen(str));
+}
+
+#ifdef TEST_SNPRINTF
+#ifndef LONG_STRING
+#define LONG_STRING 1024
+#endif
+int main (void)
+{
+  char buf1[LONG_STRING];
+  char buf2[LONG_STRING];
+  char *fp_fmt[] = {
+    "%-1.5f",
+    "%1.5f",
+    "%123.9f",
+    "%10.5f",
+    "% 10.5f",
+    "%+22.9f",
+    "%+4.9f",
+    "%01.3f",
+    "%4f",
+    "%3.1f",
+    "%3.2f",
+    NULL
+  };
+  double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 
+    0.9996, 1.996, 4.136, 0};
+  char *int_fmt[] = {
+    "%-1.5d",
+    "%1.5d",
+    "%123.9d",
+    "%5.5d",
+    "%10.5d",
+    "% 10.5d",
+    "%+22.33d",
+    "%01.3d",
+    "%4d",
+    NULL
+  };
+  long int_nums[] = { -1, 134, 91340, 341, 0203, 0};
+  int x, y;
+  int fail = 0;
+  int num = 0;
+
+  printf ("Testing snprintf format codes against system sprintf...\n");
+
+  for (x = 0; fp_fmt[x] != NULL ; x++)
+    for (y = 0; fp_nums[y] != 0 ; y++)
+    {
+      snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]);
+      sprintf (buf2, fp_fmt[x], fp_nums[y]);
+      if (strcmp (buf1, buf2))
+      {
+       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
+           fp_fmt[x], buf1, buf2);
+       fail++;
+      }
+      num++;
+    }
+
+  for (x = 0; int_fmt[x] != NULL ; x++)
+    for (y = 0; int_nums[y] != 0 ; y++)
+    {
+      snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]);
+      sprintf (buf2, int_fmt[x], int_nums[y]);
+      if (strcmp (buf1, buf2))
+      {
+       printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf  = %s\n", 
+           int_fmt[x], buf1, buf2);
+       fail++;
+      }
+      num++;
+    }
+  printf ("%d tests failed out of %d.\n", fail, num);
+}
+#endif /* SNPRINTF_TEST */
+
+#endif /* !HAVE_SNPRINTF */
diff --git a/lib/staticopen.h b/lib/staticopen.h
new file mode 100644 (file)
index 0000000..dbf3b33
--- /dev/null
@@ -0,0 +1,180 @@
+/* staticopen.h
+ * Rob Siemborski
+ * Howard Chu
+ * $Id: staticopen.h,v 1.8 2005/02/16 20:52:09 shadow 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.
+ */
+
+typedef enum {
+       UNKNOWN = 0, SERVER = 1, CLIENT = 2, AUXPROP = 3, CANONUSER = 4
+} _sasl_plug_type;
+
+typedef struct {
+       _sasl_plug_type type;
+       char *name;
+       sasl_client_plug_init_t *plug;
+} _sasl_plug_rec;
+
+/* For static linking */
+#define SPECIFIC_CLIENT_PLUG_INIT_PROTO( x ) \
+sasl_client_plug_init_t x##_client_plug_init
+
+#define SPECIFIC_SERVER_PLUG_INIT_PROTO( x ) \
+sasl_server_plug_init_t x##_server_plug_init
+
+#define SPECIFIC_AUXPROP_PLUG_INIT_PROTO( x ) \
+sasl_auxprop_init_t x##_auxprop_plug_init
+
+#define SPECIFIC_CANONUSER_PLUG_INIT_PROTO( x ) \
+sasl_canonuser_init_t x##_canonuser_plug_init
+
+/* Static Compillation Foo */
+#define SPECIFIC_CLIENT_PLUG_INIT( x, n )\
+       { CLIENT, n, x##_client_plug_init }
+#define SPECIFIC_SERVER_PLUG_INIT( x, n )\
+       { SERVER, n, (sasl_client_plug_init_t *)x##_server_plug_init }
+#define SPECIFIC_AUXPROP_PLUG_INIT( x, n )\
+       { AUXPROP, n, (sasl_client_plug_init_t *)x##_auxprop_plug_init }
+#define SPECIFIC_CANONUSER_PLUG_INIT( x, n )\
+       { CANONUSER, n, (sasl_client_plug_init_t *)x##_canonuser_plug_init }
+
+#ifdef STATIC_ANONYMOUS
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( anonymous );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( anonymous );
+#endif
+#ifdef STATIC_CRAMMD5
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( crammd5 );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( crammd5 );
+#endif
+#ifdef STATIC_DIGESTMD5
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( digestmd5 );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( digestmd5 );
+#endif
+#ifdef STATIC_GSSAPIV2
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( gssapiv2 );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( gssapiv2 );
+#endif
+#ifdef STATIC_KERBEROS4
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( kerberos4 );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( kerberos4 );
+#endif
+#ifdef STATIC_LOGIN
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( login );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( login );
+#endif
+#ifdef STATIC_NTLM
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( ntlm );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( ntlm );
+#endif
+#ifdef STATIC_OTP
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( otp );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( otp );
+#endif
+#ifdef STATIC_PLAIN
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( plain );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( plain );
+#endif
+#ifdef STATIC_SRP
+extern SPECIFIC_SERVER_PLUG_INIT_PROTO( srp );
+extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( srp );
+#endif
+#ifdef STATIC_SASLDB
+extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sasldb );
+#endif
+#ifdef STATIC_SQL
+extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sql );
+#endif
+#ifdef STATIC_LDAPDB
+extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( ldapdb );
+#endif
+
+_sasl_plug_rec _sasl_static_plugins[] = {
+#ifdef STATIC_ANONYMOUS
+       SPECIFIC_SERVER_PLUG_INIT( anonymous, "ANONYMOUS" ),
+       SPECIFIC_CLIENT_PLUG_INIT( anonymous, "ANONYMOUS" ),
+#endif
+#ifdef STATIC_CRAMMD5
+       SPECIFIC_SERVER_PLUG_INIT( crammd5, "CRAM-MD5" ),
+       SPECIFIC_CLIENT_PLUG_INIT( crammd5, "CRAM-MD5" ),
+#endif
+#ifdef STATIC_DIGESTMD5
+       SPECIFIC_SERVER_PLUG_INIT( digestmd5, "DIGEST-MD5" ),
+       SPECIFIC_CLIENT_PLUG_INIT( digestmd5, "DIGEST-MD5" ),
+#endif
+#ifdef STATIC_GSSAPIV2
+       SPECIFIC_SERVER_PLUG_INIT( gssapiv2, "GSSAPI" ),
+       SPECIFIC_CLIENT_PLUG_INIT( gssapiv2, "GSSAPI" ),
+#endif
+#ifdef STATIC_KERBEROS4
+       SPECIFIC_SERVER_PLUG_INIT( kerberos4, "KERBEROS_V4" ),
+       SPECIFIC_CLIENT_PLUG_INIT( kerberos4, "KERBEROS_V4" ),
+#endif
+#ifdef STATIC_LOGIN
+       SPECIFIC_SERVER_PLUG_INIT( login, "LOGIN" ),
+       SPECIFIC_CLIENT_PLUG_INIT( login, "LOGIN" ),
+#endif
+#ifdef STATIC_NTLM
+       SPECIFIC_SERVER_PLUG_INIT( ntlm, "NTLM" ),
+       SPECIFIC_CLIENT_PLUG_INIT( ntlm, "NTLM" ),
+#endif
+#ifdef STATIC_OTP
+       SPECIFIC_SERVER_PLUG_INIT( otp, "OTP" ),
+       SPECIFIC_CLIENT_PLUG_INIT( otp, "OTP" ),
+#endif
+#ifdef STATIC_PLAIN
+       SPECIFIC_SERVER_PLUG_INIT( plain, "PLAIN" ),
+       SPECIFIC_CLIENT_PLUG_INIT( plain, "PLAIN" ),
+#endif
+#ifdef STATIC_SRP
+       SPECIFIC_SERVER_PLUG_INIT( srp, "SRP" ),
+       SPECIFIC_CLIENT_PLUG_INIT( srp, "SRP" ),
+#endif
+#ifdef STATIC_SASLDB
+       SPECIFIC_AUXPROP_PLUG_INIT( sasldb, "SASLDB" ),
+#endif
+#ifdef STATIC_SQL
+       SPECIFIC_AUXPROP_PLUG_INIT( sql, "SQL" ),
+#endif
+#ifdef STATIC_LDAPDB
+    SPECIFIC_AUXPROP_PLUG_INIT( ldapdb, "LDAPDB" ),
+#endif
+       { UNKNOWN, NULL, NULL }
+};
diff --git a/lib/windlopen.c b/lib/windlopen.c
new file mode 100644 (file)
index 0000000..46d054f
--- /dev/null
@@ -0,0 +1,310 @@
+/* windlopen.c--Windows dynamic loader interface
+ * Ryan Troll
+ * $Id: windlopen.c,v 1.16 2003/10/20 15:19:59 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.
+ */
+
+#include <stdio.h>
+#include <io.h>
+#include <sys/stat.h>
+
+#include <config.h>
+#include <sasl.h>
+#include "saslint.h"
+
+#define DLL_SUFFIX     ".dll"
+#define DLL_MASK       "*" DLL_SUFFIX
+#define DLL_MASK_LEN   5
+
+const int _is_sasl_server_static = 0;
+
+/* : inefficient representation, but works */
+typedef struct lib_list 
+{
+    struct lib_list *next;
+    HMODULE library;
+} lib_list_t;
+
+static lib_list_t *lib_list_head = NULL;
+
+int _sasl_locate_entry(void *library,
+                      const char *entryname,
+                      void **entry_point) 
+{
+    if(entryname == NULL) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no entryname in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+    if(library == NULL) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no library in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+    if(entry_point == NULL) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "no entrypoint output pointer in _sasl_locate_entry");
+       return SASL_BADPARAM;
+    }
+
+    *entry_point = GetProcAddress(library, entryname);
+
+    if (*entry_point == NULL) {
+#if 0 /* This message appears to confuse people */
+       _sasl_log(NULL, SASL_LOG_DEBUG,
+                 "unable to get entry point %s: %s", entryname,
+                 GetLastError());
+#endif
+       return SASL_FAIL;
+    }
+
+    return SASL_OK;
+}
+
+static int _sasl_plugin_load(char *plugin, void *library,
+                            const char *entryname,
+                            int (*add_plugin)(const char *, void *)) 
+{
+    void *entry_point;
+    int result;
+    
+    result = _sasl_locate_entry(library, entryname, &entry_point);
+    if(result == SASL_OK) {
+       result = add_plugin(plugin, entry_point);
+       if(result != SASL_OK)
+           _sasl_log(NULL, SASL_LOG_DEBUG,
+                     "_sasl_plugin_load failed on %s for plugin: %s\n",
+                     entryname, plugin);
+    }
+
+    return result;
+}
+
+/* loads a plugin library */
+int _sasl_get_plugin(const char *file,
+                    const sasl_callback_t *verifyfile_cb,
+                    void **libraryptr)
+{
+    int r = 0;
+    HINSTANCE library;
+    lib_list_t *newhead;
+    
+    r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
+                   (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
+    if (r != SASL_OK) return r;
+
+    newhead = sasl_ALLOC(sizeof(lib_list_t));
+    if(!newhead) return SASL_NOMEM;
+
+    if (!(library = LoadLibrary (file))) {
+       _sasl_log(NULL, SASL_LOG_ERR,
+                 "unable to LoadLibrary %s: %s", file, GetLastError());
+       sasl_FREE(newhead);
+       return SASL_FAIL;
+    }
+
+    newhead->library = library;
+    newhead->next = lib_list_head;
+    lib_list_head = newhead;
+
+    *libraryptr = library;
+    return SASL_OK;
+}
+
+
+
+/* gets the list of mechanisms */
+int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
+                      const sasl_callback_t *getpath_cb,
+                      const sasl_callback_t *verifyfile_cb)
+{
+    int result;
+    char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2];
+                               /* 1 for '\\' 1 for trailing '\0' */
+    char * pattern;
+    char c;
+    int pos;
+    const char *path=NULL;
+    int position;
+    const add_plugin_list_t *cur_ep;
+    struct stat statbuf;               /* filesystem entry information */
+    intptr_t fhandle;                  /* file handle for _findnext function */
+    struct _finddata_t finddata;       /* data returned by _findnext() */
+    size_t prefix_len;
+
+    if (! entrypoints
+       || ! getpath_cb
+       || getpath_cb->id != SASL_CB_GETPATH
+       || ! getpath_cb->proc
+       || ! verifyfile_cb
+       || verifyfile_cb->id != SASL_CB_VERIFYFILE
+       || ! verifyfile_cb->proc)
+       return SASL_BADPARAM;
+
+    /* get the path to the plugins */
+    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
+                                                   &path);
+    if (result != SASL_OK) return result;
+    if (! path) return SASL_FAIL;
+
+    if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
+       return SASL_FAIL;
+    }
+
+    position=0;
+    do {
+       pos=0;
+       do {
+           c=path[position];
+           position++;
+           cur_dir[pos]=c;
+           pos++;
+       } while ((c!=PATHS_DELIMITER) && (c!=0));
+       cur_dir[pos-1]='\0';
+
+
+/* : check to make sure that a valid directory name was passed in */
+       if (stat (cur_dir, &statbuf) < 0) {
+           continue;
+       }
+       if ((statbuf.st_mode & S_IFDIR) == 0) {
+           continue;
+       }
+
+       strcpy (prefix, cur_dir);
+       prefix_len = strlen (prefix);
+
+/* : Don't append trailing \ unless required */
+       if (prefix[prefix_len-1] != '\\') {
+           strcat (prefix,"\\");
+           prefix_len++;
+       }
+
+       pattern = prefix;
+
+/* : Check that we have enough space for "*.dll" */
+       if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) {
+           _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big");
+            continue;
+       }
+
+       strcat (prefix + prefix_len, "*" DLL_SUFFIX);
+
+        fhandle = _findfirst (pattern, &finddata);
+        if (fhandle == -1) {   /* no matching files */
+            continue;
+        }
+
+/* : Truncate "*.dll" */
+       prefix[prefix_len] = '\0';
+
+       do {
+           size_t length;
+           void *library;
+           char *c;
+           char plugname[PATH_MAX];
+
+           length = strlen(finddata.name);
+           if (length < 5) { /* At least <Ch>.dll */
+               continue; /* can not possibly be what we're looking for */
+           }
+
+/* : Check for overflow */
+           if (length + prefix_len >= PATH_MAX) continue; /* too big */
+
+           if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) {
+               continue;
+           }
+
+/* : Check that it is not a directory */
+           if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) {
+               continue;
+           }
+
+/* : Construct full name from prefix and name */
+
+           strcpy (full_name, prefix);
+           strcat (full_name, finddata.name);
+               
+/* cut off .dll suffix -- this only need be approximate */
+           strcpy (plugname, finddata.name);
+           c = strrchr(plugname, '.');
+           if (c != NULL) *c = '\0';
+
+           result = _sasl_get_plugin (full_name, verifyfile_cb, &library);
+
+           if (result != SASL_OK) {
+               continue;
+           }
+
+           for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
+                   _sasl_plugin_load(plugname, library, cur_ep->entryname,
+                                     cur_ep->add_plugin);
+               /* If this fails, it's not the end of the world */
+           }
+       } while (_findnext (fhandle, &finddata) == 0);
+       
+       _findclose (fhandle);
+
+    } while ((c!='=') && (c!=0));
+
+    return SASL_OK;
+}
+
+int
+_sasl_done_with_plugins(void)
+{
+    lib_list_t *libptr, *libptr_next;
+    
+    for(libptr = lib_list_head; libptr; libptr = libptr_next) {
+       libptr_next = libptr->next;
+       if (libptr->library != NULL) {
+           FreeLibrary(libptr->library);
+       }
+       sasl_FREE(libptr);
+    }
+
+    lib_list_head = NULL;
+
+    return SASL_OK;
+}
diff --git a/mac/CommonKClient/KClientPublic.h b/mac/CommonKClient/KClientPublic.h
new file mode 100755 (executable)
index 0000000..adde0af
--- /dev/null
@@ -0,0 +1,15 @@
+// include file for portable interface to KClient
+#if __dest_os == __mac_os
+#include "macKClientPublic.h"
+#else if __dest_os == __win32_os
+#define PC
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+#include "win32KClientPublic.h"
+#include "KClientKrbPC.h"
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/mac/CommonKClient/mac_kclient/KClient.c b/mac/CommonKClient/mac_kclient/KClient.c
new file mode 100755 (executable)
index 0000000..9f9ef63
--- /dev/null
@@ -0,0 +1,944 @@
+/*
+       KClient.c -- Application library for KClient
+
+       Â© Copyright 1994,1995 by Cornell University
+       
+       Initial coding 8/94 by Peter Bosanko.
+*/
+
+#ifndef _KrbDriver_
+#include "krbdriver.h"
+#endif
+
+#ifndef _DEVICES_
+#include       <Devices.h>
+#endif
+
+#include "kcglue_des.h"
+
+#define KC_SESSION ((KClientRec *)session)
+#define KC_PB (&(((KClientRec *)session)->hiParm))
+#define OLD_KC_PB ((krbHiParmBlock *)session)
+#define PICK_PARM (kcRec ? (void*) kcRec : (void*) pb)
+#define KCLIENTDRIVER "\p.Kerberos"
+
+/* Forward Declarations */
+
+OSErr KClientSendMessage(short msg, void *parm);
+OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  );
+krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec );
+OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString );
+
+/*
+ * call into des ecb_encrypt
+ */
+/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
+int KClient_des_ecb_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,int do_encrypt)
+{
+       KClientKey sessionKey;
+       Key_schedule schedule;
+       
+       int rc=KClientGetSessionKey(session,&sessionKey);
+       if(rc!=0)
+               return rc;
+       rc=kcglue_des_key_sched(&sessionKey,schedule);
+       if(rc!=0)
+               return rc;
+       kcglue_des_ecb_encrypt(v1,v2,schedule,do_encrypt);
+       return rc;
+}
+
+/*
+ * call into des pcbc_encrypt
+ */
+/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
+int KClient_des_pcbc_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,long len,int do_encrypt)
+{
+       KClientKey sessionKey;
+       Key_schedule schedule;
+       
+       int rc=KClientGetSessionKey(session,&sessionKey);
+       if(rc!=0)
+               return rc;
+       rc=kcglue_des_key_sched(&sessionKey,schedule);
+       if(rc!=0)
+               return rc;
+       kcglue_des_pcbc_encrypt(v1,v2,len,schedule,&sessionKey,do_encrypt);
+       return rc;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSendMessage(short msg, void *parm)
+{
+       ParamBlockRec aPBR;
+       short refNum = 0;
+       
+/************************************************** 
+       OK to "open" driver everytime because driver
+       just returns if it's already open.
+       This saves us from having to pass around refNum
+       or store it in a global.                     
+***************************************************/
+       
+       OSErr err = OpenDriver(KCLIENTDRIVER,&refNum);
+       if (err) return err;
+
+       aPBR.cntrlParam.ioCompletion = nil;
+       aPBR.cntrlParam.ioVRefNum = 0;
+       aPBR.cntrlParam.ioCRefNum = refNum;
+       aPBR.cntrlParam.csCode = msg;
+       BlockMove(&parm,aPBR.cntrlParam.csParam,sizeof(parm));
+               
+       (void) PBControlImmed( &aPBR );
+
+       err = aPBR.cntrlParam.ioResult;
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+krbHiParmBlock *KClientSessionKind(  KClientSessionInfo *session, KClientRec **kcRec )
+{
+       if (KC_SESSION->tag==NEW_KCLIENT_TAG) {
+               /* Newer driver, use newer session record */
+               if (kcRec)
+                       *kcRec          = KC_SESSION;
+               return KC_PB;
+       }
+       else {
+               if (kcRec)
+                       *kcRec          = NULL;
+               return OLD_KC_PB;
+       }
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetPassword(  KClientSessionInfo *session, char *password  )
+{
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+       
+       pb->user = password;
+       return KClientSendMessage(cKrbSetPassword,PICK_PARM);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientNewSession(KClientSessionInfo *session, unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort)
+{
+       OSErr err;
+
+       err = KClientSendMessage(cKrbNewClientSession,KC_SESSION);
+       
+       if (err==cKrbBadSelector) {
+               /* old driver, so initialize by hand */
+               short i,e = sizeof(KClientSessionInfo) / sizeof(long);
+               long *s = (long *) session;
+               for (i=0;i<e;i++) *s++ = 0;
+               err = noErr;
+       }
+
+       KC_SESSION->libVersion          = 2;
+       KC_PB->lAddr                            = lAddr;
+       KC_PB->lPort                            = lPort;
+       KC_PB->fAddr                            = fAddr;
+       KC_PB->fPort                            = fPort;
+               
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDisposeSession(KClientSessionInfo *session)
+{
+       KClientRec *kcRec;
+       (void) KClientSessionKind(session,&kcRec);
+       
+       if (kcRec)
+               return KClientSendMessage(cKrbDisposeSession,session);
+
+       return noErr;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+/*
+ * modified by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
+ */
+OSErr KClientGetTicketForService(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen)
+{
+       return KClientGetTicketForServiceFull(session,service,buf,buflen,0);
+}
+
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * store the passed long in network byte order
+ */
+static char *put_long(char *dst,long aval)
+{
+       *dst++=aval>>24;
+       *dst++=aval>>16;
+       *dst++=aval>>8;
+       *dst++=aval;
+       return dst;
+}
+
+/*
+ * - int = 1 byte
+ * - long = 4 bytes
+ * long length of all the following [kclientism]
+ * ticket format, from reading mk_req.c
+ * int KRB_PROT_VERSION      
+ * int AUTH_MSG_APPL_REQUEST
+ * int key version numbner
+ * string realm
+ * int ticket length
+ * int authenticator length
+ * ticket
+ * authenticator [
+ *   string name
+ *   string instance
+ *   string realm
+ *   long checksum
+ *   byte GMT microseconds/5
+ *   int GMT time
+ * ] encrypted in session key
+ */
+
+/*---------------------------------------------------------------------------------------------------*/
+/*
+ * created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum
+ */
+OSErr KClientGetTicketForServiceFull(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long cks)
+{
+       char *p=(char *)buf;
+       long tkt_len;
+       long auth_len;
+       char wbuf[1500];
+
+       OSErr err;      
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       pb->service = service;
+       pb->buf = (char *) buf;
+       pb->buflen = *buflen;
+       pb->checksum = cks;
+       err = KClientSendMessage(cKrbGetTicketForService,PICK_PARM);
+       *buflen = pb->buflen;
+       if(err!=0)
+               return err;
+       /*
+        * if checksum is zero, buth kclientman and kclient will correctly get the ticket
+        * if checksum is non zero, then kclientman will have incorrectly encoded 0 in the checksum
+        * field of the authenticator, kclient will have encoded the correct checksum...
+        * rather than check the underlying authentication package (kclient vs kclientman)
+        * we will go ahead and decrypt the authenticator and fix the checksum.  this is unessary but
+        * harmless for kclient.
+     */
+       if(cks==0)
+               return 0;
+       p+=4+3+strlen(p+7)+1; /*4 byte kclient len, vers,req, kvno*/
+       tkt_len= (*p++)&0x0ff;
+       auth_len= (*p++)&0x0ff;
+       p+=tkt_len;
+       err=KClient_des_pcbc_encrypt(session,(unsigned char *)p,(unsigned char *)wbuf,auth_len,0);
+       if(err!=0)
+               return err;
+       {
+               char *w=wbuf;
+               /* printf("name='%s'\n",w); */
+               w+=strlen(w)+1; /*skip name */
+               /* printf("instance='%s'\n",w); */
+               w+=strlen(w)+1; /*skip instance */
+               /* printf("realm='%s'\n",w); */
+               w+=strlen(w)+1; /*realm*/
+               w=put_long(w,cks);
+       }
+       err=KClient_des_pcbc_encrypt(session,(unsigned char *)wbuf,(unsigned char *)wbuf,auth_len,1);
+       memcpy(p,wbuf,auth_len);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientLogin(  KClientSessionInfo *session, KClientKey *privateKey )
+{      
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+       
+       pb->service = (char *) privateKey; /* pointer to private key in first 4 bytes */
+       err = KClientSendMessage(cKrbLogin,PICK_PARM);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetPrompt(  KClientSessionInfo *session, char *prompt )
+{      
+       KClientRec *kcRec;
+       (void) KClientSessionKind(session,&kcRec);
+
+       if (kcRec)
+               kcRec->prompt = prompt;
+       else return cKrbBadSelector;
+       
+       return noErr;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientPasswordLogin(  KClientSessionInfo *session, char *password, KClientKey *privateKey )
+{
+       OSErr err;
+       
+       if ( ( err = KClientSetPassword(session,password) ) != noErr )
+                return err;
+       
+       return KClientLogin(session,privateKey);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientPasswordToKey( char *password, KClientKey *privateKey )
+{
+       ParamBlockRec aPBR;
+       short refNum;
+       OSErr err;
+       
+       if ( (err = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
+               return err;
+
+       aPBR.cntrlParam.ioCompletion = nil;
+       aPBR.cntrlParam.ioVRefNum = 0;
+       aPBR.cntrlParam.ioCRefNum = refNum;
+       aPBR.cntrlParam.csCode = cKrbPasswordToKey;
+       ((long *)aPBR.cntrlParam.csParam)[0] = (long)password;
+       ((long *)aPBR.cntrlParam.csParam)[1] = (long)privateKey;
+               
+       (void) PBControl( &aPBR, false );
+       return aPBR.cntrlParam.ioResult;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientKeyLogin( KClientSessionInfo *session, KClientKey *privateKey )
+{
+       OSErr err;
+
+       err = KClientSendMessage(cKrbSetKey,privateKey);
+       if (err) return err;
+       
+       return KClientLogin(session,privateKey);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientLogout( )
+{
+       krbHiParmBlock  cpb;
+
+       return KClientSendMessage(cKrbDeleteAllSessions, &cpb);
+}
+               
+/*---------------------------------------------------------------------------------------------------*/
+short KClientStatus( )
+{
+       char user[40];
+       
+       user[0] = '\0';
+       (void) KClientGetUserName(user);
+       if (*user != 0)
+               return KClientLoggedIn;
+       return KClientNotLoggedIn;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr _KClientVersion( StringPtr driver, short *majorVersion, short *minorVersion, char *versionString )
+{
+       ParamBlockRec aPBR;
+       short refNum;
+       OSErr err;
+       
+       if ( (err = OpenDriver(driver,&refNum)) != noErr)
+               return err;
+
+       aPBR.cntrlParam.ioCompletion = nil;
+       aPBR.cntrlParam.ioVRefNum = 0;
+       aPBR.cntrlParam.ioCRefNum = refNum;
+       aPBR.cntrlParam.csCode = cKrbDriverVersion;
+       ((long *)aPBR.cntrlParam.csParam)[1] = (long)versionString;
+               
+       (void) PBControl( &aPBR, false );
+       err = aPBR.cntrlParam.ioResult;
+       
+       /* For pre-2.0, do some detective work */
+       if (err==cKrbBadSelector) {
+               *majorVersion = 1;
+               aPBR.cntrlParam.csCode = cKrbGetDesPointers;
+               ((long *)aPBR.cntrlParam.csParam)[1] = 11; /* so it doesn't return anything */
+               (void) PBControl( &aPBR, false );
+               if (aPBR.cntrlParam.ioResult==cKrbOldDriver) {
+                       *minorVersion = 1;
+                       if (versionString)
+                               *((long *)versionString) = '1.1\0';
+               }
+               else {
+                       *minorVersion = 0;
+                       if (versionString)
+                               *((long *)versionString) = '1.0\0';
+               }
+               err = 0;
+       }
+       else {
+               *majorVersion = aPBR.cntrlParam.csParam[0];
+               *minorVersion = aPBR.cntrlParam.csParam[1];
+       }
+       
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientVersion( short *majorVersion, short *minorVersion, char *versionString )
+{
+       return _KClientVersion(KCLIENTDRIVER,majorVersion,minorVersion,versionString);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetUserName(char *user)
+{
+       OSErr err;
+       KClientSessionInfo s,*session = &s;
+       
+       KC_SESSION->tag = 0;
+       OLD_KC_PB->user = user;
+       err = KClientSendMessage(cKrbGetUserName,session);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetSessionUserName(KClientSessionInfo *session, char *user, short nameType )
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       pb->user = user;
+       kcRec->nameType = nameType;
+       err = KClientSendMessage(cKrbGetSessionUserName,PICK_PARM);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetUserName(char *user)
+{
+       OSErr err;
+       KClientSessionInfo s,*session = &s;
+       
+       KC_SESSION->tag = 0;
+       OLD_KC_PB->user = user;
+       err = KClientSendMessage(cKrbSetUserName,session);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientCacheInitialTicket(KClientSessionInfo *session, char *service)
+{
+       OSErr err;      
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+               
+       pb->service = service;
+       err = KClientSendMessage(cKrbCacheInitialTicket,PICK_PARM);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetSessionKey(KClientSessionInfo *session, KClientKey *sessionKey)
+{      
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       /* Not logged in and no server context */
+       if ((!kcRec || !kcRec->serverContext) && KClientStatus()==KClientNotLoggedIn)
+               return cKrbNotLoggedIn;
+       
+       BlockMove(&(pb->sessionKey),sessionKey,sizeof(KClientKey));
+       return 0;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientMakeSendAuth(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long checksum, char *applicationVersion)
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+               
+       pb->service = service;
+       pb->buf = (char *) buf;
+       pb->buflen = *buflen;
+       pb->checksum = checksum;
+       pb->applicationVersion = applicationVersion;
+       err = KClientSendMessage(cKrbGetAuthForService,PICK_PARM);
+       *buflen = pb->buflen;
+       return err;
+}                              
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientVerifyReplyTicket(KClientSessionInfo *session, void *buf,unsigned long *buflen )
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+       
+       pb->buf = (char *) buf;
+       pb->buflen = *buflen;
+       err = KClientSendMessage(cKrbCheckServiceResponse,PICK_PARM);
+       *buflen = pb->buflen;
+       return err;
+}
+               
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientEncrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,void *encryptBuf,unsigned long *encryptLength)
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       pb->buf = (char *) buf;
+       pb->buflen = buflen;
+       pb->encryptBuf = (char *) encryptBuf;
+       err = KClientSendMessage(cKrbEncrypt,PICK_PARM);
+       *encryptLength = pb->encryptLength;
+       return err;
+}
+               
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDecrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,
+                                       unsigned long *decryptOffset,unsigned long *decryptLength)
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       pb->buf = (char *) buf;
+       pb->buflen = buflen;
+       err = KClientSendMessage(cKrbDecrypt,PICK_PARM);
+       *decryptOffset = pb->decryptOffset;
+       *decryptLength = pb->decryptLength;
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+void KClientErrorText(OSErr err, char *text)
+{
+       ParamBlockRec aPBR;
+       short refNum;
+       OSErr oerr;
+       
+       if ( (oerr = OpenDriver(KCLIENTDRIVER,&refNum)) != noErr)
+               return;
+
+       aPBR.cntrlParam.ioCompletion = nil;
+       aPBR.cntrlParam.ioVRefNum = 0;
+       aPBR.cntrlParam.ioCRefNum = refNum;
+       aPBR.cntrlParam.csCode = cKrbGetErrorText;
+       ((long *)aPBR.cntrlParam.csParam)[0] = (long)err;
+       ((long *)aPBR.cntrlParam.csParam)[1] = (long)text;
+               
+       (void) PBControl( &aPBR, false );
+       
+       /* In case driver is old, at least return something */
+       if (aPBR.cntrlParam.ioResult==cKrbBadSelector) {
+               BlockMove("Kerberos error",text,15);            
+       }
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+/* Kerberized Server routines                                                                        */
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerNewSession( KClientSessionInfo *session, char *service,unsigned long lAddr, 
+                                               unsigned short lPort,unsigned long fAddr,unsigned short fPort)
+{
+       OSErr err;
+
+       KC_PB->service                          = service;
+
+       err = KClientSendMessage(cKrbNewServerSession,KC_SESSION);
+       
+       if (err)
+               return err;
+
+       KC_SESSION->libVersion          = 2;
+       KC_PB->lAddr                            = lAddr;
+       KC_PB->lPort                            = lPort;
+       KC_PB->fAddr                            = fAddr;
+       KC_PB->fPort                            = fPort;
+               
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerVerifyTicket( KClientSessionInfo *session, void *buf, char *filename )
+{
+       OSErr err;
+       KC_PB->buf = (char *) buf;
+       KC_SESSION->filename = filename;
+
+       err = KClientSendMessage(cKrbServerVerifyTicket,KC_SESSION);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerGetReplyTicket( KClientSessionInfo *session, void *buf, unsigned long *buflen )
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+       
+       pb->buf                 = (char *) buf;
+       pb->buflen      = *buflen;
+
+       err = KClientSendMessage(cKrbServerGetReplyTkt,PICK_PARM);
+       if (err) return err;
+       
+       *buflen = pb->buflen;
+       return noErr;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerAddKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename )
+{
+       OSErr err;
+       KClientKey key;
+       char srv[128];
+       char tkt[1250];
+       unsigned long len;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       if (!kcRec)
+               return cKrbBadSelector; /* old driver */
+       
+       KC_SESSION->filename    = filename;
+       KC_PB->service                  = service;
+
+       if (!service) {
+               /* No service, build from scratch, prompt the user */
+               /* Get the user to log in, using service principle and password */
+               KClientLogout();
+               err = KClientLogin( session, &key );
+               if (err) return err;
+               
+               err = KClientGetUserName(srv);
+               if (err) return err;
+
+               /* Get a service ticket for the service so that we can obtain key version number */
+               err = KClientGetTicketForService(session, srv,tkt,&len);
+               if (err) return err;
+                               
+               KC_PB->service = srv;
+               BlockMove(&key,KC_SESSION->serverKey,8);
+               KC_SESSION->keyVersion  = tkt[6];               /* tkt contains private key's version in the seventh byte */
+       }
+       else {
+               KC_SESSION->keyVersion  = version;
+               BlockMove(privateKey,KC_SESSION->serverKey,8);
+               KC_PB->service          = service;
+       }
+       
+       return KClientSendMessage(cKrbAddServiceKey,session);
+
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerGetKey( KClientSessionInfo *session, KClientKey *privateKey,char *service, long version, char *filename )
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+               
+       if (!kcRec)
+               return cKrbBadSelector; /* old driver */
+
+       KC_SESSION->keyVersion  = version;
+       KC_SESSION->filename    = filename;
+       KC_PB->service                  = service;
+
+       err = KClientSendMessage(cKrbGetServiceKey,KC_SESSION);
+       if (err) return err;
+
+       BlockMove(KC_SESSION->serverKey,privateKey,8);
+       return noErr;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KServerGetSessionTimeRemaining( KClientSessionInfo *session, long *seconds )
+{
+       OSErr err;
+       KClientRec *kcRec;
+       krbHiParmBlock *pb = KClientSessionKind(session,&kcRec);
+
+       err = KClientSendMessage(cKrbGetSessionTimeRemaining,PICK_PARM);
+       *seconds = pb->checksum;
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+/* Configuration routines                                                                            */
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetLocalRealm( char *realm )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       return KClientSendMessage(cKrbGetLocalRealm,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetLocalRealm( char *realm )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       return KClientSendMessage(cKrbSetLocalRealm,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetRealm( char *host, char *realm )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       pb.host = host;
+       return KClientSendMessage(cKrbGetRealm,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientAddRealmMap( char *host, char *realm )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       pb.host = host;
+       return KClientSendMessage(cKrbAddRealmMap,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDeleteRealmMap( char *host )
+{
+       krbParmBlock pb;
+       pb.host = host;
+       return KClientSendMessage(cKrbDeleteRealmMap,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthRealmMap( long n, char *host, char *realm )
+{
+       krbParmBlock pb;        
+       pb.host = host;
+       pb.uRealm = realm;
+       pb.itemNumber = &n;
+       return KClientSendMessage(cKrbGetNthRealmMap,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthServer( long n, char *host, char *realm, Boolean admin )
+{
+       krbParmBlock pb;
+       
+       pb.host = host;
+       pb.uRealm = realm;
+       pb.itemNumber = &n;
+       pb.admin = (long) admin;
+       return KClientSendMessage(cKrbGetNthServer,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientAddServerMap( char *host, char *realm, Boolean admin )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       pb.host = host;
+       pb.admin = admin ? 1 : 0;
+       return KClientSendMessage(cKrbAddServerMap,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDeleteServerMap( char *host, char *realm )
+{
+       krbParmBlock pb;
+       pb.uRealm = realm;
+       pb.host = host;
+       return KClientSendMessage(cKrbDeleteServerMap,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthServerMap( long n, char *host, char *realm, Boolean *admin )
+{
+       OSErr err;
+       long ladmin;
+       krbParmBlock pb;
+       
+       pb.uRealm = realm;
+       pb.host = host;
+       pb.adminReturn = &ladmin;
+       pb.itemNumber = &n;
+       err = KClientSendMessage(cKrbGetNthServerMap,&pb);
+       *admin = (ladmin==1);
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthServerPort( long n, short *port )
+{
+       OSErr err;
+       krbParmBlock pb;
+       pb.itemNumber = &n;
+       err = KClientSendMessage(cKrbGetNthServerPort,&pb);
+       *port = pb.port;
+       return err;
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetNthServerPort( long n, short port )
+{
+       krbParmBlock pb;
+       pb.itemNumber = &n;
+       pb.port = port;
+       return KClientSendMessage(cKrbSetNthServerPort,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNumSessions( long *n )
+{
+       krbParmBlock pb;
+       pb.itemNumber = n;
+       return KClientSendMessage(cKrbGetNumSessions,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthSession( long n, char *name, char *instance, char *realm )
+{
+       krbParmBlock pb;
+       pb.itemNumber = &n;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       return KClientSendMessage(cKrbGetNthSession,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDeleteSession( char *name, char *instance, char *realm )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       return KClientSendMessage(cKrbDeleteSession,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       pb.cred = cred;
+       return KClientSendMessage(cKrbGetCredentials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientAddCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       pb.cred = cred;
+       return KClientSendMessage(cKrbAddCredentials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDeleteCredentials( char *name, char *instance, char *realm, 
+                                                               char *sname, char *sinstance, char *srealm )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       pb.sName = sname;
+       pb.sInstance = sinstance;
+       pb.sRealm = srealm;
+       return KClientSendMessage(cKrbDeleteCredentials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNumCredentials( long *n, char *name, char *instance, char *realm )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       pb.itemNumber = n;
+       return KClientSendMessage(cKrbGetNumCredentials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthCredential( long n, char *name, char *instance, char *realm,
+                                                               char *sname, char *sinstance, char *srealm )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.uInstance = instance;
+       pb.uRealm = realm;
+       pb.sName = sname;
+       pb.sInstance = sinstance;
+       pb.sRealm = srealm;
+       pb.itemNumber = &n;
+       return KClientSendMessage(cKrbGetNthCredentials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientAddSpecial( char *service, char *name )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.sName = service;
+       return KClientSendMessage(cKrbAddSpecial,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientDeleteSpecial( char *service )
+{
+       krbParmBlock pb;
+       pb.sName = service;
+       return KClientSendMessage(cKrbDeleteSpecial,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNumSpecials( long *n )
+{
+       krbParmBlock pb;
+       pb.itemNumber = n;
+       return KClientSendMessage(cKrbGetNumSpecials,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetNthSpecial( long n, char *name, char *service )
+{
+       krbParmBlock pb;
+       pb.uName = name;
+       pb.sName = service;
+       pb.itemNumber = &n;
+       return KClientSendMessage(cKrbGetNthSpecial,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientSetOption( short option, void *value )
+{
+       krbParmBlock pb;
+       pb.uName = (char *) value;
+       pb.port = option;
+       return KClientSendMessage(cKrbSetOption,&pb);
+}
+
+/*---------------------------------------------------------------------------------------------------*/
+OSErr KClientGetOption( short option, void *value )
+{
+       krbParmBlock pb;
+       pb.uName = (char *) value;
+       pb.port = option;
+       return KClientSendMessage(cKrbGetOption,&pb);
+}
+
diff --git a/mac/CommonKClient/mac_kclient/KClient.h b/mac/CommonKClient/mac_kclient/KClient.h
new file mode 100755 (executable)
index 0000000..81f940a
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+       KClient.h -- Application interface for KClient
+
+       Â© Copyright 1994,95 by Project Mandarin Inc.
+       
+       Initial coding                  8/94 Peter Bosanko.
+       Added new routines              8/95 PCB
+       Moved some constants
+       from krbdriver.h
+       
+========================================================================
+       DES and Kerberos portions of this file are...
+========================================================================
+       
+       Copyright (C) 1989 by the Massachusetts Institute of Technology
+
+       Export of this software from the United States of America is assumed
+       to require a specific license from the United States Government.
+       It is the responsibility of any person or organization contemplating
+       export to obtain such a license before exporting.
+
+WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+distribute this software and its documentation for any purpose and
+without fee is hereby granted, provided that the above copyright
+notice appear in all copies and that both that copyright notice and
+this permission notice appear in supporting documentation, and that
+the name of M.I.T. not be used in advertising or publicity pertaining
+to distribution of the software without specific, written prior
+permission.  M.I.T. makes no representations about the suitability of
+this software for any purpose.  It is provided "as is" without express
+or implied warranty.
+
+*/
+
+#ifndef        _KCLIENT_
+#define        _KCLIENT_
+
+#ifndef _TYPES_
+#include <Types.h>
+#endif
+
+/* Error codes */
+
+enum {
+       cKrbCorruptedFile = -1024,      /* couldn't find a needed resource */
+       cKrbNoKillIO,                           /* can't killIO because all calls sync */
+       cKrbBadSelector,                        /* csCode passed doesn't select a recognized function */
+       cKrbCantClose,                          /* we must always remain open */
+       cKrbMapDoesntExist,                     /* tried to access a map that doesn't exist (index too large,
+                                                                       or criteria doesn't match anything) */
+       cKrbSessDoesntExist,            /* tried to access a session that doesn't exist */
+       cKrbCredsDontExist,                     /* tried to access credentials that don't exist */
+       cKrbTCPunavailable,                     /* couldn't open MacTCP driver */
+       cKrbUserCancelled,                      /* user cancelled a log in operation */
+       cKrbConfigurationErr,           /* Kerberos Preference file is not configured properly */
+       cKrbServerRejected,                     /* A server rejected our ticket */
+       cKrbServerImposter,                     /* Server appears to be a phoney */
+       cKrbServerRespIncomplete,       /* Server response is not complete */
+       cKrbNotLoggedIn,                        /* Returned by cKrbGetUserName if user is not logged in */
+       cKrbOldDriver,                          /* old version of the driver */
+       cKrbDriverInUse,                        /* driver is not reentrant */
+       cKrbAppInBkgnd,                         /* driver won't put up password dialog when in background */
+       cKrbInvalidSession,                     /* invalid structure passed to KClient/KServer routine */
+       cKrbOptionNotDefined,           /* returned from GetOption */
+       
+       cKrbKerberosErrBlock = -20000   /* start of block of 256 kerberos error numbers */
+};
+
+#define LARGEST_DRIVER_ERROR   cKrbOptionNotDefined
+
+typedef char KClientErrString[64];
+
+enum { KClientLoggedIn, KClientNotLoggedIn };
+
+/* Different kerberos name formats (for KServerGetUserName) */
+enum { 
+       KClientLocalName,                               /* Don't specify realm */
+       KClientCommonName,                              /* Only specify realm if it isn't local */
+       KClientFullName                                 /* Always specify realm */
+};
+
+/* Options */
+enum {
+       kclientOptionSaveName = 1,
+       kclientOptionSynchTime,
+       kclientOptionShowMenu,
+       kclientOptionInstalled_1_6
+};
+
+struct KClientKey {
+       unsigned char keyBytes[8];
+};
+typedef struct KClientKey KClientKey;
+
+struct KClientSessionInfo {
+       char sessionBytes[256];
+};
+typedef struct KClientSessionInfo KClientSessionInfo;
+typedef KClientSessionInfo *KClientSessionPtr;
+
+/* Defines for obsolete function names */
+#define KClientInitSession             KClientNewSession
+#define KClientVerifySendAuth  KClientVerifyReplyTicket
+
+/************************************/
+/* Some includes from des.h & krb.h */
+/************************************/
+#if defined(powerc) || defined(__powerc)
+#pragma options align=mac68k
+#endif
+
+#ifndef DES_DEFS
+
+typedef unsigned char des_cblock[8];   /* crypto-block size */
+
+/* Key schedule */
+typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
+
+#endif /* DES_DEFS */
+
+#ifndef KRB_DEFS
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define        ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+    long     length;           /* Length of the text */
+    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */
+    unsigned long mbz;         /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+struct credentials {
+    char    service[ANAME_SZ]; /* Service name */
+    char    instance[INST_SZ]; /* Instance */
+    char    realm[REALM_SZ];   /* Auth domain */
+    C_Block session;           /* Session key */
+    long     lifetime;         /* Lifetime */
+    long     kvno;             /* Key version number */
+    KTEXT_ST ticket_st;                /* The ticket itself */
+    long    issue_date;                /* The issue time */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+    unsigned char *app_data;   /* pointer to appl data */
+    unsigned long app_length;  /* length of appl data */
+    unsigned long hash;                /* hash to lookup replay */
+    long     swap;             /* swap bytes? */
+    long    time_sec;          /* msg timestamp seconds */
+    unsigned char time_5ms;    /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+typedef unsigned long u_long;
+typedef unsigned short u_short;
+
+#define KRB_PASSWORD_SERVICE  "changepw.kerberos"
+
+#endif /* KRB_DEFS */
+
+#if defined(powerc) || defined(__powerc)
+#pragma options align=reset
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * call into des ecb_encrypt
+ */
+/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
+int KClient_des_ecb_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,int do_encrypt);
+
+/*
+ * call into des pcbc_encrypt
+ */
+/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
+int KClient_des_pcbc_encrypt(KClientSessionInfo  *session,des_cblock v1,des_cblock v2,long len,int do_encrypt);
+
+OSErr KClientNewSession(KClientSessionInfo *session, unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort);
+
+OSErr KClientDisposeSession(KClientSessionInfo  *session);
+
+/* created by n3liw+@cmu.edu to support SASL, need to be able to specify checksum */
+OSErr KClientGetTicketForServiceFull(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long cks);
+
+OSErr KClientGetTicketForService(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen);
+
+OSErr KClientLogin( KClientSessionInfo *session, KClientKey *privateKey );
+
+OSErr KClientSetPrompt(  KClientSessionInfo *session, char *prompt );
+
+OSErr KClientPasswordLogin( KClientSessionInfo *session, char *password, KClientKey *privateKey );
+
+OSErr KClientPasswordToKey( char *password, KClientKey *privateKey );
+
+OSErr KClientKeyLogin( KClientSessionInfo *session, KClientKey *privateKey );
+
+OSErr KClientLogout( void );
+               
+short KClientStatus( void );
+
+OSErr KClientVersion( short *majorVersion, short *minorVersion, char *versionString );
+
+OSErr KClientGetUserName(char *user);
+
+OSErr KClientGetSessionUserName(KClientSessionInfo *session, char *user, short nameType);
+
+OSErr KClientSetUserName(char *user);
+
+OSErr KClientCacheInitialTicket(KClientSessionInfo *session, char *service);
+
+OSErr KClientGetSessionKey(KClientSessionInfo *session, KClientKey *sessionKey);
+
+OSErr KClientMakeSendAuth(KClientSessionInfo *session, char *service,void *buf,unsigned long *buflen,long checksum, char *applicationVersion);
+                               
+OSErr KClientVerifyReplyTicket(KClientSessionInfo *session, void *buf,unsigned long *buflen );
+               
+OSErr KClientEncrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,void *encryptBuf,unsigned long *encryptLength);
+               
+OSErr KClientDecrypt(KClientSessionInfo *session, void *buf,unsigned long buflen,unsigned long *decryptOffset,unsigned long *decryptLength);
+
+void KClientErrorText(OSErr err, char *text);
+
+
+/* KServer calls */
+
+OSErr KServerNewSession( KClientSessionInfo *session, char *service, 
+                                               unsigned long lAddr,unsigned short lPort,unsigned long fAddr,unsigned short fPort);
+
+OSErr KServerVerifyTicket( KClientSessionInfo *session, void *buf, char *keyFileName );
+
+OSErr KServerGetReplyTicket( KClientSessionInfo *session, void *buf, unsigned long *buflen );
+
+OSErr KServerGetKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename );
+
+OSErr KServerAddKey( KClientSessionInfo *session, KClientKey *privateKey, char *service, long version, char *filename );
+
+OSErr KServerGetSessionTimeRemaining( KClientSessionInfo *session, long *seconds );
+
+/* Configuration routines */
+
+OSErr KClientGetLocalRealm( char *realm );
+
+OSErr KClientSetLocalRealm( char *realm );
+
+OSErr KClientGetRealm( char *host, char *realm );
+
+OSErr KClientAddRealmMap( char *host, char *realm );
+
+OSErr KClientDeleteRealmMap( char *host );
+
+OSErr KClientGetNthRealmMap( long n, char *host, char *realm );
+
+OSErr KClientGetNthServer( long n, char *host, char *realm, Boolean admin );
+
+OSErr KClientAddServerMap( char *host, char *realm, Boolean admin );
+
+OSErr KClientDeleteServerMap( char *host, char *realm );
+
+OSErr KClientGetNthServerMap( long n, char *host, char *realm, Boolean *admin );
+
+OSErr KClientGetNthServerPort( long n, short *port );
+
+OSErr KClientSetNthServerPort( long n, short port );
+
+OSErr KClientGetNumSessions( long *n );
+
+OSErr KClientGetNthSession( long n, char *name, char *instance, char *realm );
+
+OSErr KClientDeleteSession( char *name, char *instance, char *realm );
+
+OSErr KClientGetCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred );
+
+OSErr KClientAddCredentials( char *name, char *instance, char *realm, CREDENTIALS *cred );
+
+OSErr KClientDeleteCredentials( char *name, char *instance, char *realm, 
+                                                               char *sname, char *sinstance, char *srealm );
+
+
+OSErr KClientGetNumCredentials( long *n, char *name, char *instance, char *realm );
+
+OSErr KClientGetNthCredential( long n, char *name, char *instance, char *realm,
+                                                               char *sname, char *sinstance, char *srealm );
+
+OSErr KClientAddSpecial( char *service, char *name );
+
+OSErr KClientDeleteSpecial( char *service );
+
+OSErr KClientGetNumSpecials( long *n );
+
+OSErr KClientGetNthSpecial( long n, char *name, char *service );
+
+OSErr KClientSetOption( short option, void *value );
+
+OSErr KClientGetOption( short option, void *value );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient/KrbDriver.h b/mac/CommonKClient/mac_kclient/KrbDriver.h
new file mode 100755 (executable)
index 0000000..3f2ba94
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+       KrbDriver.h -- This is the KClient driver's direct call interface.
+       This file defines all of the csCodes used by the driver and the three
+       structures used for passing information to and from the driver.
+               
+       Â© Copyright 1992,95 by Cornell University
+       
+       Initial coding                                          1/92 Peter Bosanko
+       Moved some constants to kclient.h       8/95 PCB
+*/
+
+#ifndef _KrbDriver_    
+#define        _KrbDriver_
+
+#ifndef _KCLIENT_
+#include "KClient.h"
+#endif
+
+/* csCodes for Control Calls */
+enum {
+       cKrbKillIO = 1,
+       cKrbGetLocalRealm,
+       cKrbSetLocalRealm,
+       cKrbGetRealm,
+       cKrbAddRealmMap,
+       cKrbDeleteRealmMap,
+       cKrbGetNthRealmMap,
+       cKrbGetNthServer,
+       cKrbAddServerMap,
+       cKrbDeleteServerMap,
+       cKrbGetNthServerMap,
+       cKrbGetNumSessions,
+       cKrbGetNthSession,
+       cKrbDeleteSession,
+       cKrbGetCredentials,
+       cKrbAddCredentials,
+       cKrbDeleteCredentials,
+       cKrbGetNumCredentials,
+       cKrbGetNthCredentials,
+       cKrbDeleteAllSessions,
+       cKrbGetTicketForService,
+       cKrbGetAuthForService,
+       cKrbCheckServiceResponse,
+       cKrbEncrypt,
+       cKrbDecrypt,
+       cKrbCacheInitialTicket,
+       cKrbGetUserName,
+       cKrbSetUserName,
+       cKrbSetPassword,
+       cKrbGetDesPointers,
+       cKrbGetErrorText,
+       cKrbLogin,
+       cKrbSetKey,
+       cKrbKerberos,
+       cKrbGetNthServerPort,
+       cKrbSetNthServerPort,
+       cKrbDriverVersion,
+       cKrbPasswordToKey,
+       cKrbNewClientSession,
+       cKrbNewServerSession,
+       cKrbDisposeSession,
+       cKrbServerVerifyTicket,
+       cKrbServerGetReplyTkt,
+       cKrbGetServiceKey,
+       cKrbAddServiceKey,
+       cKrbGetOption,
+       cKrbSetOption,
+       cKrbAdditionalLogin,
+       cKrbControlPanelEnter,
+       cKrbControlPanelLeave,
+       cKrbGetSessionTimeRemaining,
+       cKrbGetSessionUserName,
+       cKrbGetNumSpecials,
+       cKrbGetNthSpecial,
+       cKrbAddSpecial,
+       cKrbDeleteSpecial
+};
+
+/* Need to switch to short word alignment on power pc */
+
+#if defined(powerc) || defined(__powerc)
+#pragma options align=mac68k
+#endif
+
+/* Parameter block for high level calls */
+
+struct krbHiParmBlock  {
+                       char                    *service;               /* full name -- combined service, instance, realm */
+                       char                    *buf;
+                       unsigned long   buflen;
+                       long                    checksum;
+                       unsigned long   lAddr;
+                       unsigned short  lPort;
+                       unsigned long   fAddr;
+                       unsigned short  fPort;
+                       unsigned long   decryptOffset;
+                       unsigned long   decryptLength;
+                       char                    *encryptBuf;
+                       unsigned long   encryptLength;
+                       char                    *applicationVersion;    /* Version string must be 8 bytes long!  */
+                       char                    sessionKey[8];                  /* for internal use                      */
+                       char                    schedule[128];                  /* for internal use                      */
+                       char                    *user;
+};
+typedef struct krbHiParmBlock krbHiParmBlock;
+typedef krbHiParmBlock *KrbParmPtr;
+typedef KrbParmPtr *KrbParmHandle;
+
+/* New KClient record */
+
+#define                NEW_KCLIENT_TAG 0xF7FAF7FA
+
+struct KClientRec      {
+                       long                    tag;
+                       krbHiParmBlock  hiParm;
+                       long                    libVersion;
+                       void                    *serverContext;
+                       char                    *filename;
+                       long                    keyVersion;
+                       char                    serverKey[8];
+                       char                    *prompt;
+                       short                   nameType;
+};
+typedef struct KClientRec KClientRec;
+
+/* ********************************************************* */
+/* The rest of these defs are for low level calls            */
+/* ********************************************************* */
+
+/* Parameter block for low level calls */              
+struct krbParmBlock    {
+                       char    *uName;
+                       char    *uInstance;
+                       char    *uRealm;                        /* also where local realm or mapping realm passed */
+                       char    *sName;
+                       char    *sInstance;
+                       char    *sRealm;
+                       char    *host;                          /* also netorhost */
+                       long    admin;                          /* isadmin, mustadmin */
+                       long    *itemNumber;
+                       long    *adminReturn;           /* when it needs to be passed back */
+                       CREDENTIALS *cred;
+                       short   port;
+};
+typedef struct krbParmBlock krbParmBlock;
+
+#if defined(powerc) || defined(__powerc)
+#pragma options align=reset
+#endif
+
+#endif
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient/kcglue_des.c b/mac/CommonKClient/mac_kclient/kcglue_des.c
new file mode 100755 (executable)
index 0000000..cb0302f
--- /dev/null
@@ -0,0 +1,22 @@
+#include "des.h"
+#include "kcglue_des.h"
+
+/* $Id: kcglue_des.c,v 1.2 2001/12/04 02:05:33 rjs3 Exp $
+ * kclient and des have different definitions for key schedules
+ * this file is to include in the kclient code without dragging in the des definitions
+ */
+int kcglue_des_key_sched(void *akey,void *asched)
+{
+       return des_key_sched(akey,asched);
+}
+
+void kcglue_des_ecb_encrypt(void *asrc,void *adest,void *asched,int direction)
+{
+       des_ecb_encrypt(asrc,adest,asched,direction);
+}
+
+void kcglue_des_pcbc_encrypt(void *asrc,void *adest,long length,void *asched,void *akey,int direction)
+{
+       des_pcbc_encrypt(asrc,adest,length,asched,akey,direction);
+}
+
diff --git a/mac/CommonKClient/mac_kclient/kcglue_des.h b/mac/CommonKClient/mac_kclient/kcglue_des.h
new file mode 100755 (executable)
index 0000000..845590a
--- /dev/null
@@ -0,0 +1,8 @@
+
+/* $Id: kcglue_des.h,v 1.2 2001/12/04 02:05:33 rjs3 Exp $
+ * kclient and des have different definitions for key schedules
+ * this file is to include in the kclient code without dragging in the des definitions
+ */
+int kcglue_des_key_sched(void *akey,void *asched);
+void kcglue_des_ecb_encrypt(void *asrc,void *adest,void *asched,int direction);
+void kcglue_des_pcbc_encrypt(void *asrc,void *adest,long length,void *asched,void *akey,int direction);
diff --git a/mac/CommonKClient/mac_kclient/kcglue_krb.c b/mac/CommonKClient/mac_kclient/kcglue_krb.c
new file mode 100755 (executable)
index 0000000..f1a4fb1
--- /dev/null
@@ -0,0 +1,150 @@
+/* $Id: kcglue_krb.c,v 1.3 2003/02/13 19:55:56 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <kcglue_krb.h>
+#include "macKClientPublic.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define SOME_KRB_ERR_NUMBER (70)
+#define                MAX_KRB_ERRORS  256
+
+const char *krb_err_txt[MAX_KRB_ERRORS]={
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err"
+};
+
+
+/*
+ * given a service instance and realm, combine them to foo.bar@REALM
+ * return true upon success
+ */
+static int implode_krb_user_info(char *dst,const char *service,const char *instance,const char *realm)
+{
+       if(strlen(service)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       if(strlen(instance)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       if(strlen(realm)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       strcpy(dst,service);
+       dst+=strlen(dst);
+       if(instance[0]!=0) {
+               *dst++='.';
+               strcpy(dst,instance);
+               dst+=strlen(dst);
+       }
+       *dst++='@';
+       strcpy(dst,realm);
+       return TRUE;
+}
+
+int kcglue_krb_mk_req(void *dat,int *len, const char *service, char *instance, char *realm, 
+          long checksum,
+          void *des_key,
+          char *pname,
+          char *pinst)
+{
+       char tkt_buf[KCGLUE_MAX_KTXT_LEN+20];
+       char user_id[KCGLUE_MAX_K_STR_LEN+1];
+       KClientSessionInfo ses;
+       int have_session=FALSE;
+       int rc;
+
+       if(!implode_krb_user_info(user_id,service,instance,realm))
+               return SOME_KRB_ERR_NUMBER;
+
+       rc=KClientNewSession(&ses,0,0,0,0);
+       if(rc!=0)
+       return SOME_KRB_ERR_NUMBER;
+       have_session=TRUE;
+       
+    *len=sizeof(tkt_buf)-10;
+       rc=KClientGetTicketForServiceFull(&ses,user_id,tkt_buf,len,checksum);
+       if(rc==0) {
+               memcpy(dat,tkt_buf+4,*len);     /*kclient puts out a 4 byte length that mit doesnt*/
+               rc=KClientGetSessionKey(&ses,des_key);
+       }
+       if(rc==0)
+               rc=KClientGetUserName(pname);
+       *pinst=0;
+       if(have_session)
+       KClientDisposeSession(&ses);
+  
+       if(rc!=0)
+               return SOME_KRB_ERR_NUMBER;
+       return 0;
+}
diff --git a/mac/CommonKClient/mac_kclient/kcglue_krb.h b/mac/CommonKClient/mac_kclient/kcglue_krb.h
new file mode 100755 (executable)
index 0000000..5ddcc40
--- /dev/null
@@ -0,0 +1,23 @@
+/* $Id: kcglue_krb.h,v 1.2 2001/12/04 02:05:33 rjs3 Exp $
+ * mit kerberos and kclient include files are not compatable
+ * the define things with the same name but different implementations
+ * this is an interface that can be included with either kclient.h
+ * or krb.h.  It bridges between the two of them
+ */
+#define KCGLUE_ITEM_SIZE (40) /* name instance or realm size*/
+#define KCGLUE_MAX_K_STR_LEN (KCGLUE_ITEM_SIZE*3+2) /* id.instance@realm */
+#define        KCGLUE_MAX_KTXT_LEN     1250
+
+int kcglue_krb_mk_req(
+               void *dat,
+               int *len,
+               const char *service,
+               char *instance,
+               char *realm, 
+               long checksum,
+               void *des_key,
+               char *pname,
+               char *pinst
+               );
+          
diff --git a/mac/CommonKClient/mac_kclient/macKClientPublic.h b/mac/CommonKClient/mac_kclient/macKClientPublic.h
new file mode 100755 (executable)
index 0000000..66160ab
--- /dev/null
@@ -0,0 +1 @@
+#include "KClient.h"
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient/mac_krb_lib1.c b/mac/CommonKClient/mac_kclient/mac_krb_lib1.c
new file mode 100755 (executable)
index 0000000..5b3d0d4
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: mac_krb_lib1.c,v 1.3 2003/02/13 19:55:56 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.
+ */
+/*
+ * library to emulate unix kerberos on a macintosh
+ */
+#include <config.h>
+#include <krb.h>
+#include <extra_krb.h>
+#include <kcglue_krb.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <stdio.h>
+
+/*
+ * given a hostname return the kerberos realm
+ * NOT thread safe....
+ */
+char *krb_realmofhost(const char *s)
+{
+       s=strchr(s,'.');
+       if(s==0)
+               return "ANDREW.CMU.EDU";
+       return (char *)(s+1);
+}
+
+/*
+ * return the default instance to use for a given hostname
+ * NOT thread safe... but then neathoer is the real kerberos one
+ */
+char *krb_get_phost(const char *alias)
+{
+#define MAX_HOST_LEN (512)
+    static char instance[MAX_HOST_LEN];
+    char *dst=instance;
+    int remaining=MAX_HOST_LEN-10;
+    while(remaining-->0) {
+       char ch= *alias++;
+       if(ch==0) break;
+       if(isupper(ch))
+               ch=tolower(ch);
+       if(ch=='.')
+               break;
+       *dst++=ch;
+    }
+    *dst=0;
+    return instance;
+}
diff --git a/mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache.h b/mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache.h
new file mode 100755 (executable)
index 0000000..b604ab8
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Export of this software from the United States of America may require a\r * specific license from the United States Government.  It is the\r * responsibility of any person or organization contemplating export to\r * obtain such a license before exporting.\r * \r * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute\r * this software and its documentation for any purpose and without fee is\r * hereby granted, provided that the above copyright notice appear in all\r * copies and that both that copyright notice and this permission notice\r * appear in supporting documentation, and that the name of M.I.T. not be\r * used in advertising or publicity pertaining to distribution of the\r * software without specific, written prior permission.  Furthermore if you\r * modify this software you must label your software as modified software\r * and not distribute it in such a fashion that it might be confused with\r * the original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache.h,v 1.2 2001/12/04 02:05:36 rjs3 Exp $ */\r\r/*\r * Declarations for Credentials Cache API Library\r *\r * API specification: <http://web.mit.edu/pismere/kerberos/ccache-api-v2.html>\r *\r *    Revision 1: Frank Dabek, 6/4/1998\r *    Revision 2: meeroh, 2/24/1999\r *      Revision 3: meeroh, 11/12/1999\r *\r */\r \r#ifndef __CREDENTIALSCACHE__\r#define __CREDENTIALSCACHE__\r\r#ifdef __cplusplus\rextern "C" {\r#endif /* __cplusplus */\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <CoreServices/CoreServices.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <MacTypes.h>\r#else\r    #error "Unknown OS; no system types available"\r#endif\r\r#if PRAGMA_IMPORT\r#  pragma import on\r#endif\r\r/* This stuff is to make sure that we always use the same compiler options for\r   this header file. Otherwise we get really exciting failure modes -- meeroh */\r#if PRAGMA_STRUCT_ALIGN\r       #pragma options align=mac68k4byte\r#elif PRAGMA_STRUCT_PACKPUSH\r #pragma pack(push, 4)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(4)\r#endif\r\r#if PRAGMA_ENUM_ALWAYSINT\r      #pragma enumsalwaysint on\r#endif\r\r#if TARGET_CPU_68K\r   #pragma fourbyteints on\r#endif \r\r/*\r * Constants\r */\r \r/* API versions */\renum {\r       ccapi_version_2 = 2,\r   ccapi_version_3 = 3,\r   ccapi_version_4 = 4\r};\r \r/* Errors */\renum {\r   ccNoError                                                       = 0,\r\r  ccIteratorEnd                                           = 201,\r ccErrBadParam,\r ccErrNoMem,\r    ccErrInvalidContext,\r   ccErrInvalidCCache,\r\r   ccErrInvalidString,                                     /* 206 */\r      ccErrInvalidCredentials,\r       ccErrInvalidCCacheIterator,\r    ccErrInvalidCredentialsIterator,\r       ccErrInvalidLock,\r\r     ccErrBadName,                                           /* 211 */\r      ccErrBadCredentialsVersion,\r    ccErrBadAPIVersion,\r    ccErrContextLocked,\r    ccErrContextUnlocked,\r\r ccErrCCacheLocked,                                      /* 216 */\r      ccErrCCacheUnlocked,\r   ccErrBadLockType,\r      ccErrNeverDefault,\r     ccErrCredentialsNotFound,\r\r     ccErrCCacheNotFound,                                    /* 221 */\r      ccErrContextNotFound,\r        ccErrServerUnavailable\r};\r\r/* Credentials versions */\renum {\r     cc_credentials_v4 = 1,\r cc_credentials_v5 = 2,\r cc_credentials_v4_v5 = 3\r};\r\r/*\r * Basic types\r */\r \rtypedef UInt32 cc_uint32;\rtypedef SInt32 cc_int32;\rtypedef cc_uint32 cc_time_t;\r\r/*\r * API types\r */\r \r/* Forward declarations */\rstruct cc_context_f;\rtypedef struct cc_context_f cc_context_f;\r\rstruct cc_ccache_f;\rtypedef struct cc_ccache_f cc_ccache_f;\r\rstruct cc_ccache_iterator_f;\rtypedef struct cc_ccache_iterator_f cc_ccache_iterator_f;\r\rstruct cc_ccache_iterator_f;\rtypedef struct cc_credentials_iterator_f cc_credentials_iterator_f;\r\rstruct cc_string_f;\rtypedef struct cc_string_f cc_string_f;\r\rstruct cc_credentials_f;\rtypedef struct cc_credentials_f cc_credentials_f;\r\r/* Credentials types */\r\renum {  /* Make sure all of these are multiples of four (for alignment sanity) */\r      cc_v4_name_size         = 40,\r  cc_v4_instance_size     = 40,\r  cc_v4_realm_size        = 40,\r  cc_v4_ticket_size       = 1254\r};\r\renum cc_string_to_key_type {\r        cc_v4_stk_afs = 0,\r     cc_v4_stk_des = 1,\r     cc_v4_stk_columbia_special = 2,\r        cc_v4_stk_unknown = 3\r};\r\rstruct cc_credentials_v4_t {\r cc_uint32                       version;\r       char                            principal [cc_v4_name_size];\r   char                            principal_instance [cc_v4_instance_size];\r      char                            service [cc_v4_name_size];\r     char                            service_instance [cc_v4_instance_size];\r        char                            realm [cc_v4_realm_size];\r      unsigned char           session_key [8];\r       cc_int32                        kvno;\r  cc_int32                        string_to_key_type;\r    cc_time_t                       issue_date;\r    cc_int32                        lifetime;\r      cc_uint32                       address;\r       cc_int32                        ticket_size;\r   unsigned char           ticket [cc_v4_ticket_size];\r};\rtypedef struct cc_credentials_v4_t cc_credentials_v4_t;\r\rstruct cc_data {\r       cc_uint32                       type;\r  cc_uint32                       length;\r        void*                           data;\r};\rtypedef struct cc_data cc_data;\r\rstruct cc_credentials_v5_t {\r char*                           client;\r        char*                           server;\r        cc_data                         keyblock;\r      cc_time_t                       authtime;\r      cc_time_t                       starttime;\r     cc_time_t                       endtime;\r       cc_time_t                       renew_till;\r    cc_uint32                       is_skey;\r       cc_uint32                       ticket_flags;\r  cc_data**                       addresses;\r     cc_data                         ticket;\r        cc_data                         second_ticket;\r cc_data**                       authdata;\r};\rtypedef struct cc_credentials_v5_t cc_credentials_v5_t;\r\rstruct cc_credentials_union {\r    cc_int32                        version;\r       union {\r                cc_credentials_v4_t*    credentials_v4;\r                cc_credentials_v5_t*    credentials_v5;\r        }                                       credentials;\r};\rtypedef struct cc_credentials_union cc_credentials_union;\r\r/* Exposed parts */\r\rstruct cc_context_d {\r  const cc_context_f*     functions;\r#if TARGET_OS_MAC\r   const cc_context_f*     otherFunctions;\r#endif\r};\rtypedef struct cc_context_d cc_context_d;\rtypedef cc_context_d*       cc_context_t;\r\rstruct cc_ccache_d {\r    const cc_ccache_f*      functions;\r#if TARGET_OS_MAC\r   const cc_ccache_f*      otherFunctions;\r#endif\r};\rtypedef struct cc_ccache_d cc_ccache_d;\rtypedef cc_ccache_d*  cc_ccache_t;\r\rstruct cc_ccache_iterator_d {\r    const cc_ccache_iterator_f*     functions;\r#if TARGET_OS_MAC\r   const cc_ccache_iterator_f*     otherFunctions;\r#endif\r};\rtypedef struct cc_ccache_iterator_d cc_ccache_iterator_d;\rtypedef cc_ccache_iterator_d*       cc_ccache_iterator_t;\r\rstruct cc_credentials_iterator_d {\r      const cc_credentials_iterator_f*        functions;\r#if TARGET_OS_MAC\r   const cc_credentials_iterator_f*        otherFunctions;\r#endif\r};\rtypedef struct cc_credentials_iterator_d cc_credentials_iterator_d;\rtypedef cc_credentials_iterator_d*        cc_credentials_iterator_t;\r\rstruct cc_string_d {\r       const char*                     data;\r  const cc_string_f*      functions;\r#if TARGET_OS_MAC\r   const cc_string_f*      otherFunctions;\r#endif\r};\rtypedef struct cc_string_d cc_string_d;\rtypedef cc_string_d*  cc_string_t;\r\rstruct cc_credentials_d {\r        const cc_credentials_union* data;\r      const cc_credentials_f* functions;\r#if TARGET_OS_MAC\r   const cc_credentials_f* otherFunctions;\r#endif\r};\rtypedef struct cc_credentials_d cc_credentials_d;\rtypedef cc_credentials_d* cc_credentials_t;\r\r/* Function pointer structs */\r\rstruct  cc_context_f {\r    cc_int32    (*release) (\r                                cc_context_t context);\r    cc_int32    (*get_change_time) (\r                                cc_context_t context,\r                                cc_time_t* time);\r    cc_int32    (*get_default_ccache_name) (\r                                cc_context_t context,\r                                cc_string_t* name);\r    cc_int32    (*open_ccache) (\r                                cc_context_t context,\r                                const char* name,\r                                cc_ccache_t* ccache);\r    cc_int32    (*open_default_ccache) (\r                                cc_context_t context,\r                                cc_ccache_t* ccache);\r    cc_int32    (*create_ccache) (\r                                cc_context_t context,\r                                const char* name,\r                                cc_uint32 cred_vers,\r                                const char* principal, \r                                cc_ccache_t* ccache);\r    cc_int32    (*create_default_ccache) (\r                                cc_context_t context,\r                                cc_uint32 cred_vers,\r                                const char* principal, \r                                cc_ccache_t* ccache);\r    cc_int32    (*create_new_ccache) (\r                                cc_context_t context,\r                                cc_uint32 cred_vers,\r                                const char* principal, \r                                cc_ccache_t* ccache);\r    cc_int32    (*new_ccache_iterator) (\r                                cc_context_t context,\r                                cc_ccache_iterator_t* iterator);\r    cc_int32    (*lock) (\r                                cc_context_t context,\r                                cc_uint32 lock_type,\r                                cc_uint32 block);\r    cc_int32    (*unlock) (\r                                cc_context_t context);\r    cc_int32    (*compare) (\r                                cc_context_t context,\r                                cc_context_t compare_to,\r                                cc_uint32* equal);\r};\r\rstruct cc_ccache_f {\r    cc_int32    (*release) (\r                                 cc_ccache_t ccache);\r    cc_int32    (*destroy) (\r                                 cc_ccache_t ccache);\r    cc_int32    (*set_default) (\r                                 cc_ccache_t ccache);\r    cc_int32    (*get_credentials_version) (\r                                 cc_ccache_t ccache,\r                                 cc_uint32* credentials_version);\r    cc_int32    (*get_name) (\r                                 cc_ccache_t ccache,\r                                 cc_string_t* name);\r    cc_int32    (*get_principal) (\r                                 cc_ccache_t ccache,\r                                 cc_uint32 credentials_version,\r                                 cc_string_t* principal);\r    cc_int32    (*set_principal) (\r                                 cc_ccache_t ccache,\r                                 cc_uint32 credentials_version,\r                                 const char* principal);\r    cc_int32    (*store_credentials) (\r                                 cc_ccache_t ccache,\r                                 const cc_credentials_union* credentials);\r    cc_int32    (*remove_credentials) (\r                                 cc_ccache_t ccache,\r                                 cc_credentials_t credentials);\r    cc_int32    (*new_credentials_iterator) (\r                                 cc_ccache_t ccache,\r                                 cc_credentials_iterator_t* iterator);\r    cc_int32    (*move) (\r                                 cc_ccache_t source,\r                                 cc_ccache_t destination);\r    cc_int32    (*lock) (\r                                 cc_ccache_t ccache,\r                                 cc_uint32 block,\r                                 cc_uint32 lock_type);\r    cc_int32    (*unlock) (\r                                 cc_ccache_t ccache);\r    cc_int32    (*get_last_default_time) (\r                                 cc_ccache_t ccache,\r                                 cc_time_t* time);\r    cc_int32    (*get_change_time) (\r                                 cc_ccache_t ccache,\r                                 cc_time_t* time);\r    cc_int32    (*compare) (\r                                cc_ccache_t ccache,\r                                cc_ccache_t compare_to,\r                                cc_uint32* equal);\r};\r\rstruct cc_string_f {\r     cc_int32        (*release) (\r                                                           cc_string_t string);\r};\r\rstruct cc_credentials_f {\r     cc_int32        (*release) (\r                                                           cc_credentials_t credentials);\r    cc_int32    (*compare) (\r                                cc_credentials_t credentials,\r                                cc_credentials_t compare_to,\r                                cc_uint32* equal);\r};\r\r                     \rstruct cc_ccache_iterator_f {\r    cc_int32    (*release) (\r                                 cc_ccache_iterator_t iter);\r    cc_int32    (*next) (\r                                 cc_ccache_iterator_t iter,\r                                 cc_ccache_t* ccache);\r};\r\rstruct cc_credentials_iterator_f {\r    cc_int32    (*release) (\r                                 cc_credentials_iterator_t iter);\r    cc_int32    (*next) (\r                                 cc_credentials_iterator_t iter,\r                                 cc_credentials_t* ccache);\r};\r\r/*\r * API functions\r */\r \rcc_int32 cc_initialize (\r   cc_context_t*           outContext,\r    cc_int32                        inVersion,\r     cc_int32*                       outSupportedVersion,\r   char const**            outVendor);\r    \r/*\r * Convenience macros\r */\r \r#define         cc_context_release(context)                                                                                                             \\r                      ((context) -> functions -> release (context))\r#define           cc_context_get_change_time(context, time)                                                                               \\r                      ((context) -> functions -> get_change_time (context, time))\r#define             cc_context_get_default_ccache_name(context, name)                                                               \\r                      ((context) -> functions -> get_default_ccache_name (context, name))\r#define             cc_context_open_ccache(context, name, ccache)                                                                   \\r                      ((context) -> functions -> open_ccache (context, name, ccache))\r#define         cc_context_open_default_ccache(context, ccache)                                                                 \\r                      ((context) -> functions -> open_default_ccache (context, ccache))\r#define               cc_context_create_ccache(context, name, version, principal, ccache)                             \\r                      ((context) -> functions -> create_ccache (context, name, version, principal, ccache))\r#define           cc_context_create_default_ccache(context, version, principal, ccache)                           \\r                      ((context) -> functions -> create_default_ccache (context, version, principal, ccache))\r#define         cc_context_create_new_ccache(context, version, principal, ccache)                               \\r                      ((context) -> functions -> create_new_ccache (context, version, principal, ccache))\r#define             cc_context_new_ccache_iterator(context, iterator)                                                               \\r                      ((context) -> functions -> new_ccache_iterator (context, iterator))\r#define             cc_context_lock(context, type, lock)                                                                                    \\r                      ((context) -> functions -> lock (context, type, lock))\r#define          cc_context_unlock(context)                                                                                      \\r                      ((context) -> functions -> unlock (context))\r#define            cc_context_compare(context, compare_to, equal)                                                                  \\r                      ((context) -> functions -> compare (context, compare_to, equal))\r\r#define               cc_ccache_release(ccache)                                                                                                               \\r                      ((ccache) -> functions -> release (ccache))\r#define             cc_ccache_destroy(ccache)                                                                                                               \\r                      ((ccache) -> functions -> destroy (ccache))\r#define             cc_ccache_set_default(ccache)                                                                                                   \\r                      ((ccache) -> functions -> set_default (ccache))\r#define         cc_ccache_get_credentials_version(ccache, version)                                                              \\r                      ((ccache) -> functions -> get_credentials_version (ccache, version))\r#define            cc_ccache_get_name(ccache, name)                                                                                                \\r                      ((ccache) -> functions -> get_name (ccache, name))\r#define              cc_ccache_get_principal(ccache, version, principal)                                                             \\r                      ((ccache) -> functions -> get_principal (ccache, version, principal))\r#define           cc_ccache_set_principal(ccache, version, principal)                                                             \\r                      ((ccache) -> functions -> set_principal (ccache, version, principal))\r#define           cc_ccache_store_credentials(ccache, credentials)                                                                \\r                      ((ccache) -> functions -> store_credentials (ccache, credentials))\r#define              cc_ccache_remove_credentials(ccache, credentials)                                                               \\r                      ((ccache) -> functions -> remove_credentials (ccache, credentials))\r#define             cc_ccache_new_credentials_iterator(ccache, iterator)                                                    \\r                      ((ccache) -> functions -> new_credentials_iterator (ccache, iterator))\r#define          cc_ccache_lock(ccache, lock)                                                                                                    \\r                      ((ccache) -> functions -> lock (ccache, lock))\r#define          cc_ccache_unlock(ccache, unlock)                                                                                                        \\r                      ((ccache) -> functions -> unlock (ccache, unlock))\r#define              cc_ccache_get_last_default_time(ccache, time)                                                                   \\r                      ((ccache) -> functions -> get_last_default_time (ccache, time))\r#define         cc_ccache_get_change_time(ccache, time)                                                                                 \\r                      ((ccache) -> functions -> get_change_time (ccache, time))\r#define               cc_ccache_move(source, destination)                                                                                             \\r                      ((source) -> functions -> move (source, destination))\r#define           cc_ccache_compare(ccache, compare_to, equal)                                                                    \\r                      ((ccache) -> functions -> compare (ccache, compare_to, equal))\r\r#define         cc_string_release(string)                                                                                                               \\r                      ((string) -> functions -> release (string))\r\r#define            cc_credentials_release(credentials)                                                                                             \\r                      ((credentials) -> functions -> release (credentials))\r#define           cc_credentials_compare(credentials, compare_to, equal)                                                  \\r                      ((credentials) -> functions -> compare (credentials, compare_to, equal))\r\r#define               cc_ccache_iterator_release(iterator)                                                                                    \\r                      ((iterator) -> functions -> release (iterator))\r#define         cc_ccache_iterator_next(iterator, ccache)                                                                               \\r                      ((iterator) -> functions -> next (iterator, ccache))\r   \r#define                cc_credentials_iterator_release(iterator)                                                                               \\r                      ((iterator) -> functions -> release (iterator))\r#define         cc_credentials_iterator_next(iterator, credentials)                                                             \\r                      ((iterator) -> functions -> next (iterator, credentials))\r                      \r#if PRAGMA_STRUCT_ALIGN\r       #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#if PRAGMA_ENUM_ALWAYSINT\r       #pragma enumsalwaysint reset\r#endif\r\r#if TARGET_CPU_68K\r        #pragma fourbyteints reset\r#endif \r\r#if PRAGMA_IMPORT\r# pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif /* __cplusplus */\r\r#endif /* __CREDENTIALSCACHE__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache2.h b/mac/CommonKClient/mac_kclient3/Headers/CredentialsCache/CredentialsCache2.h
new file mode 100755 (executable)
index 0000000..1b28c52
--- /dev/null
@@ -0,0 +1 @@
+/*\r * This is backwards compatibility for CCache API v2 clients to be able to run \r * against the CCache API v3 library\r */\r \r#ifndef __CREDENTIALSCACHE2__\r#define __CREDENTIALSCACHE2__\r \r#include <CredentialsCache/CredentialsCache.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif /* __cplusplus */\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if PRAGMA_IMPORT\r#      pragma import on\r#endif\r\r/* This stuff is to make sure that we always use the same compiler options for\r   this header file. Otherwise we get really exciting failure modes -- meeroh */\r/* Sadly, the v2 APi didn't specify the alignment, so we use the default except on MacOS\r   (where our implementation defined it to be 2-byte aligned) */\r#if TARGET_OS_MAC\r   #if PRAGMA_STRUCT_ALIGN\r                #pragma options align=mac68k\r   #elif PRAGMA_STRUCT_PACKPUSH\r           #pragma pack(push, 2)\r  #elif PRAGMA_STRUCT_PACK\r               #pragma pack(2)\r        #endif\r#endif\r\r#if PRAGMA_ENUM_ALWAYSINT\r       #pragma enumsalwaysint on\r#endif\r\r#if TARGET_CPU_68K\r   #pragma fourbyteints on\r#endif \r\r/* Some old types get directly mapped to new types */\r\rtypedef cc_context_d apiCB;\rtypedef cc_ccache_d ccache_p;\rtypedef cc_credentials_iterator_d ccache_cit_creds;\rtypedef cc_ccache_iterator_d ccache_cit_ccache;\rtypedef cc_data cc_data_compat;\rtypedef cc_int32 cc_cred_vers;\rtypedef cc_int32 cc_result;\r\r/* This doesn't exist in API v3 */\rtypedef cc_uint32 cc_flags;\r\r/* Credentials types are visible to the caller so we have to keep binary compatibility */\r\rtypedef struct cc_credentials_v5_compat {\r char*                           client;\r        char*                           server;\r        cc_data_compat          keyblock;\r      cc_time_t                       authtime;\r      cc_time_t                       starttime;\r     cc_time_t                       endtime;\r       cc_time_t                       renew_till;\r    cc_uint32                       is_skey;\r       cc_uint32                       ticket_flags;\r  cc_data_compat**        addresses;\r    cc_data_compat           ticket;\r        cc_data_compat          second_ticket;\r cc_data_compat**        authdata;\r} cc_credentials_v5_compat;\r \renum {\r MAX_V4_CRED_LEN = 1250\r};\r \renum {\r     KRB_NAME_SZ = 40,\r      KRB_INSTANCE_SZ = 40,\r  KRB_REALM_SZ = 40\r};\r \rtypedef struct cc_credentials_v4_compat {\r       unsigned char   kversion;\r      char                    principal[KRB_NAME_SZ+1];\r      char                    principal_instance[KRB_INSTANCE_SZ+1];\r char                    service[KRB_NAME_SZ+1];\r        char                    service_instance[KRB_INSTANCE_SZ+1];\r   char                    realm[KRB_REALM_SZ+1];\r unsigned char   session_key[8];\r        cc_int32                kvno;\r  cc_int32                str_to_key;\r    long                    issue_date;\r    cc_int32                lifetime;\r    cc_uint32         address;\r       cc_int32                ticket_sz;\r     unsigned char   ticket[MAX_V4_CRED_LEN];\r       unsigned long   oops;\r} cc_credentials_v4_compat;\r\rtypedef union cred_ptr_union_compat {\r    cc_credentials_v4_compat*  pV4Cred;\r    cc_credentials_v5_compat*  pV5Cred;\r} cred_ptr_union_compat;\r \rtypedef struct cred_union {\r    cc_int32                            cred_type;  // cc_cred_vers\r    cred_ptr_union_compat   cred;\r} cred_union;\r\r/* NC info structure is gone in v3 */\r\rstruct infoNC {\r    char*           name;\r  char*           principal;\r     cc_int32        vers;\r};\r\rtypedef struct infoNC infoNC;\r\r/* Some old type names */\r\rtypedef cc_credentials_v4_compat V4Cred_type;\rtypedef cc_credentials_v5_compat cc_creds;\rstruct ccache_cit;\rtypedef struct ccache_cit ccache_cit;\r\renum {\r  CC_API_VER_2 = ccapi_version_2\r};\r\renum {\r      CC_NOERROR,\r    CC_BADNAME,\r    CC_NOTFOUND,\r   CC_END,\r        CC_IO,\r CC_WRITE,\r      CC_NOMEM,\r      CC_FORMAT,\r     CC_LOCKED,\r     CC_BAD_API_VERSION,\r    CC_NO_EXIST,\r   CC_NOT_SUPP,\r   CC_BAD_PARM,\r   CC_ERR_CACHE_ATTACH,\r   CC_ERR_CACHE_RELEASE,\r  CC_ERR_CACHE_FULL,\r     CC_ERR_CRED_VERSION\r};\r\renum {\r CC_CRED_UNKNOWN,\r       CC_CRED_V4,\r    CC_CRED_V5,\r    CC_CRED_MAX\r};\r\rcc_int32 cc_shutdown (\r apiCB**                         ioContext);\r    \rcc_int32 cc_get_NC_info (\r     apiCB*                          inContext,\r     infoNC***                       outInfo);\r      \rcc_int32 cc_get_change_time (\r apiCB*                          inContext,\r     cc_time_t*                      outTime);\r      \rcc_int32 cc_open (\r    apiCB*                          inContext,\r     const char*                     inName,\r        cc_int32                        inVersion,\r     cc_uint32                       inFlags,\r       ccache_p**                      outCCache);\r    \rcc_int32 cc_create (\r  apiCB*                          inContext,\r     const char*                     inName,\r        const char*                     inPrincipal,\r   cc_int32                        inVersion,\r     cc_uint32                       inFlags,\r       ccache_p**                      outCCache);\r    \rcc_int32 cc_close (\r   apiCB*                          inContext,\r     ccache_p**                      ioCCache);\r     \rcc_int32 cc_destroy (\r apiCB*                          inContext,\r     ccache_p**                      ioCCache);\r     \rcc_int32 cc_seq_fetch_NCs_begin (\r     apiCB*                          inContext,\r     ccache_cit**            outIterator);\r\rcc_int32 cc_seq_fetch_NCs_next (\r        apiCB*                          inContext,\r     ccache_p**                      outCCache,\r     ccache_cit*                     inIterator);\r\rcc_int32 cc_seq_fetch_NCs_end (\r  apiCB*                          inContext,\r     ccache_cit**            ioIterator);\r\rcc_int32 cc_get_name (\r   apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      char**                          outName);\r      \rcc_int32 cc_get_cred_version (\r        apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      cc_int32*                       outVersion);\r   \rcc_int32 cc_set_principal (\r   apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      cc_int32                        inVersion,\r     char*                           inPrincipal);\r  \rcc_int32 cc_get_principal (\r   apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      char**                          outPrincipal);\r \rcc_int32 cc_store (\r   apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      cred_union                      inCredentials);\r\rcc_int32 cc_remove_cred (\r     apiCB*                          inContext,\r     ccache_p*                       inCCache,\r      cred_union                      inCredentials);\r\rcc_int32 cc_seq_fetch_creds_begin (\r   apiCB*                          inContext,\r     const ccache_p*         inCCache,\r      ccache_cit**            outIterator);\r\rcc_int32 cc_seq_fetch_creds_next (\r      apiCB*                          inContext,\r     cred_union**            outCreds,\r      ccache_cit*                     inIterator);\r   \rcc_int32 cc_seq_fetch_creds_end (\r     apiCB*                          inContext,\r     ccache_cit**            ioIterator);\r   \rcc_int32 cc_free_principal (\r  apiCB*                          inContext,\r     char**                          ioPrincipal);\r\rcc_int32 cc_free_name (\r apiCB*                          inContext,\r     char**                          ioName);\r\rcc_int32 cc_free_creds (\r     apiCB*                          inContext,\r     cred_union**            creds);\r\rcc_int32 cc_free_NC_info (\r    apiCB*                          inContext,\r     infoNC***                       ioInfo);\r       \r#if TARGET_OS_MAC\r     #if PRAGMA_STRUCT_ALIGN\r                #pragma options align=reset\r    #elif PRAGMA_STRUCT_PACKPUSH\r           #pragma pack(pop)\r      #elif PRAGMA_STRUCT_PACK\r               #pragma pack()\r #endif\r#endif\r\r#if PRAGMA_ENUM_ALWAYSINT\r       #pragma enumsalwaysint reset\r#endif\r\r#if TARGET_CPU_68K\r        #pragma fourbyteints reset\r#endif \r\r#if PRAGMA_IMPORT\r# pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif /* __cplusplus */\r\r#endif /* __CREDENTIALSCACHE2__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/GSS/GSS.h b/mac/CommonKClient/mac_kclient3/Headers/GSS/GSS.h
new file mode 100755 (executable)
index 0000000..3dd2b1e
--- /dev/null
@@ -0,0 +1 @@
+#include <GSS/gssapi.h>\r#include <GSS/gssapi_krb5.h>\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi.h b/mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi.h
new file mode 100755 (executable)
index 0000000..ddb0b0c
--- /dev/null
@@ -0,0 +1,830 @@
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION 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 _GSSAPI_H_
+#define _GSSAPI_H_
+
+/*
+ * Determine platform-dependent configuration.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+       #include <KerberosSupport/KerberosSupport.h>
+       
+       #if TARGET_API_MAC_OS8 || (TARGET_API_MAC_CARBON && !TARGET_API_MAC_OSX)
+               #include <Kerberos5/win-mac.h>
+       #endif
+#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
+#endif
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#define GSS_DLLIMP
+#define KRB5_EXPORTVAR
+#endif
+#ifndef FAR
+#define FAR
+#define NEAR
+#endif
+
+#define        GSS_SIZEOF_INT          SIZEOF_INT
+#define        GSS_SIZEOF_LONG         SIZEOF_LONG
+#define        GSS_SIZEOF_SHORT        SIZEOF_SHORT
+
+/*
+ * Make sure we have a definition for PROTOTYPE.
+ */
+#if !defined(PROTOTYPE)
+#if defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32) || defined(__ultrix)
+#define PROTOTYPE(x) x
+#else
+#define PROTOTYPE(x) ()
+#endif
+#endif
+
+/*
+ * First, include stddef.h to get size_t defined.
+ */
+#if    HAVE_STDDEF_H
+#include <stddef.h>
+#endif /* HAVE_STDDEF_H */
+
+/*
+ * POSIX says that sys/types.h is where size_t is defined.
+ */
+#ifndef macintosh
+#include <sys/types.h>
+#endif
+
+/*
+ * If the platform supports the xom.h header file, it should be included here.
+ */
+#if    HAVE_XOM_H
+#include <xom.h>
+#endif /* HAVE_XOM_H */
+
+/*
+ * $Id: gssapi.h,v 1.2 2001/12/04 02:05:37 rjs3 Exp $
+ */
+
+/*
+ * First, define the three platform-dependent pointer types.
+ */
+
+typedef void FAR * gss_name_t;
+typedef void FAR * gss_cred_id_t;
+typedef void FAR * gss_ctx_id_t;
+
+/*
+ * The following type must be defined as the smallest natural unsigned integer
+ * supported by the platform that has at least 32 bits of precision.
+ */
+#if (GSS_SIZEOF_SHORT == 4)
+typedef unsigned short gss_uint32;
+typedef short gss_int32;
+#elif (GSS_SIZEOF_INT == 4)
+typedef unsigned int gss_uint32;
+typedef int gss_int32;
+#elif (GSS_SIZEOF_LONG == 4)
+typedef unsigned long gss_uint32;
+typedef long gss_int32;
+#endif
+
+#ifdef OM_STRING
+/*
+ * We have included the xom.h header file.  Use the definition for
+ * OM_object identifier.
+ */
+typedef OM_object_identifier   gss_OID_desc, *gss_OID;
+#else  /* OM_STRING */
+/*
+ * We can't use X/Open definitions, so roll our own.
+ */
+typedef gss_uint32     OM_uint32;
+
+typedef struct gss_OID_desc_struct {
+      OM_uint32 length;
+      void      FAR *elements;
+} gss_OID_desc, FAR *gss_OID;
+#endif /* OM_STRING */
+
+typedef struct gss_OID_set_desc_struct  {
+      size_t  count;
+      gss_OID elements;
+} gss_OID_set_desc, FAR *gss_OID_set;
+
+typedef struct gss_buffer_desc_struct {
+      size_t length;
+      void FAR *value;
+} gss_buffer_desc, FAR *gss_buffer_t;
+
+typedef struct gss_channel_bindings_struct {
+      OM_uint32 initiator_addrtype;
+      gss_buffer_desc initiator_address;
+      OM_uint32 acceptor_addrtype;
+      gss_buffer_desc acceptor_address;
+      gss_buffer_desc application_data;
+} FAR *gss_channel_bindings_t;
+
+/*
+ * For now, define a QOP-type as an OM_uint32 (pending resolution of ongoing
+ * discussions).
+ */
+typedef        OM_uint32       gss_qop_t;
+typedef        int             gss_cred_usage_t;
+
+/*
+ * Flag bits for context-level services.
+ */
+#define GSS_C_DELEG_FLAG 1
+#define GSS_C_MUTUAL_FLAG 2
+#define GSS_C_REPLAY_FLAG 4
+#define GSS_C_SEQUENCE_FLAG 8
+#define GSS_C_CONF_FLAG 16
+#define GSS_C_INTEG_FLAG 32
+#define        GSS_C_ANON_FLAG 64
+#define GSS_C_PROT_READY_FLAG 128
+#define GSS_C_TRANS_FLAG 256
+
+/*
+ * Credential usage options
+ */
+#define GSS_C_BOTH 0
+#define GSS_C_INITIATE 1
+#define GSS_C_ACCEPT 2
+
+/*
+ * Status code types for gss_display_status
+ */
+#define GSS_C_GSS_CODE 1
+#define GSS_C_MECH_CODE 2
+
+/*
+ * The constant definitions for channel-bindings address families
+ */
+#define GSS_C_AF_UNSPEC     0
+#define GSS_C_AF_LOCAL      1
+#define GSS_C_AF_INET       2
+#define GSS_C_AF_IMPLINK    3
+#define GSS_C_AF_PUP        4
+#define GSS_C_AF_CHAOS      5
+#define GSS_C_AF_NS         6
+#define GSS_C_AF_NBS        7
+#define GSS_C_AF_ECMA       8
+#define GSS_C_AF_DATAKIT    9
+#define GSS_C_AF_CCITT      10
+#define GSS_C_AF_SNA        11
+#define GSS_C_AF_DECnet     12
+#define GSS_C_AF_DLI        13
+#define GSS_C_AF_LAT        14
+#define GSS_C_AF_HYLINK     15
+#define GSS_C_AF_APPLETALK  16
+#define GSS_C_AF_BSC        17
+#define GSS_C_AF_DSS        18
+#define GSS_C_AF_OSI        19
+#define GSS_C_AF_X25        21
+
+#define GSS_C_AF_NULLADDR   255
+
+/*
+ * Various Null values.
+ */
+#define GSS_C_NO_NAME ((gss_name_t) 0)
+#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
+#define GSS_C_NO_OID ((gss_OID) 0)
+#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
+#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
+#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
+#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
+#define GSS_C_EMPTY_BUFFER {0, NULL}
+
+/*
+ * Some alternate names for a couple of the above values.  These are defined
+ * for V1 compatibility.
+ */
+#define        GSS_C_NULL_OID          GSS_C_NO_OID
+#define        GSS_C_NULL_OID_SET      GSS_C_NO_OID_SET
+
+/*
+ * Define the default Quality of Protection for per-message services.  Note
+ * that an implementation that offers multiple levels of QOP may either reserve
+ * a value (for example zero, as assumed here) to mean "default protection", or
+ * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
+ * QOP value.  However a value of 0 should always be interpreted by a GSSAPI
+ * implementation as a request for the default protection level.
+ */
+#define GSS_C_QOP_DEFAULT 0
+
+/*
+ * Expiration time of 2^32-1 seconds means infinite lifetime for a
+ * credential or security context
+ */
+#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
+
+
+/* Major status codes */
+
+#define GSS_S_COMPLETE 0
+
+/*
+ * Some "helper" definitions to make the status code macros obvious.
+ */
+#define GSS_C_CALLING_ERROR_OFFSET 24
+#define GSS_C_ROUTINE_ERROR_OFFSET 16
+#define GSS_C_SUPPLEMENTARY_OFFSET 0
+#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
+#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
+
+/*
+ * The macros that test status codes for error conditions.  Note that the
+ * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
+ * evaluates its argument only once.
+ */
+#define GSS_CALLING_ERROR(x) \
+  ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
+#define GSS_ROUTINE_ERROR(x) \
+  ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
+#define GSS_SUPPLEMENTARY_INFO(x) \
+  ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
+#define GSS_ERROR(x) \
+  ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
+         (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
+
+/*
+ * Now the actual status code definitions
+ */
+
+/*
+ * Calling errors:
+ */
+#define GSS_S_CALL_INACCESSIBLE_READ \
+                             (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_INACCESSIBLE_WRITE \
+                             (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
+#define GSS_S_CALL_BAD_STRUCTURE \
+                             (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
+
+/*
+ * Routine errors:
+ */
+#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DEFECTIVE_CREDENTIAL \
+     (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CREDENTIALS_EXPIRED \
+     (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_CONTEXT_EXPIRED \
+     (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_DUPLICATE_ELEMENT \
+     (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+#define GSS_S_NAME_NOT_MN \
+     (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
+
+/*
+ * Supplementary info bits:
+ */
+#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
+#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
+#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
+#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
+#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
+
+
+/*
+ * Finally, function prototypes for the GSSAPI routines.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Macintoh CFM-68K magic incantation */
+#if PRAGMA_IMPORT
+#pragma import on
+#endif
+
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack(2)
+#endif
+
+/* Reserved static storage for GSS_oids.  Comments are quotes from RFC 2744.
+ *
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) user_name(1)}.  The constant
+ * GSS_C_NT_USER_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_USER_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) machine_uid_name(2)}.
+ * The constant GSS_C_NT_MACHINE_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_MACHINE_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03"},
+ * corresponding to an object-identifier value of
+ * {iso(1) member-body(2) United States(840) mit(113554)
+ * infosys(1) gssapi(2) generic(1) string_uid_name(3)}.
+ * The constant GSS_C_NT_STRING_UID_NAME should be
+ * initialized to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_STRING_UID_NAME;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x02"},
+ * corresponding to an object-identifier value of
+ * {iso(1) org(3) dod(6) internet(1) security(5)
+ * nametypes(6) gss-host-based-services(2)).  The constant
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be initialized to point
+ * to that gss_OID_desc.  This is a deprecated OID value, and
+ * implementations wishing to support hostbased-service names
+ * should instead use the GSS_C_NT_HOSTBASED_SERVICE OID,
+ * defined below, to identify such names;
+ * GSS_C_NT_HOSTBASED_SERVICE_X should be accepted a synonym
+ * for GSS_C_NT_HOSTBASED_SERVICE when presented as an input
+ * parameter, but should not be emitted by GSS-API
+ * implementations
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE_X;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {10, (void *)"\x2a\x86\x48\x86\xf7\x12"
+ *              "\x01\x02\x01\x04"}, corresponding to an
+ * object-identifier value of {iso(1) member-body(2)
+ * Unites States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}.  The constant
+ * GSS_C_NT_HOSTBASED_SERVICE should be initialized
+ * to point to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\01\x05\x06\x03"},
+ * corresponding to an object identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 3(gss-anonymous-name)}.  The constant
+ * and GSS_C_NT_ANONYMOUS should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_ANONYMOUS;
+
+
+/*
+ * The implementation must reserve static storage for a
+ * gss_OID_desc object containing the value
+ * {6, (void *)"\x2b\x06\x01\x05\x06\x04"},
+ * corresponding to an object-identifier value of
+ * {1(iso), 3(org), 6(dod), 1(internet), 5(security),
+ * 6(nametypes), 4(gss-api-exported-name)}.  The constant
+ * GSS_C_NT_EXPORT_NAME should be initialized to point
+ * to that gss_OID_desc.
+ */
+GSS_DLLIMP extern gss_OID GSS_C_NT_EXPORT_NAME;
+
+/* Function Prototypes */
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_acquire_cred
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_name_t,                        /* desired_name */
+            OM_uint32,                 /* time_req */
+            gss_OID_set,               /* desired_mechs */
+            gss_cred_usage_t,          /* cred_usage */
+            gss_cred_id_t FAR *,       /* output_cred_handle */
+            gss_OID_set FAR *,         /* actual_mechs */
+            OM_uint32 FAR *            /* time_rec */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_cred
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_cred_id_t FAR *                /* cred_handle */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_init_sec_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_cred_id_t,             /* claimant_cred_handle */
+            gss_ctx_id_t FAR *,                /* context_handle */
+            gss_name_t,                        /* target_name */
+            gss_OID,                   /* mech_type (used to be const) */
+            OM_uint32,                 /* req_flags */
+            OM_uint32,                 /* time_req */
+            gss_channel_bindings_t,    /* input_chan_bindings */
+            gss_buffer_t,              /* input_token */
+            gss_OID FAR *,             /* actual_mech_type */
+            gss_buffer_t,              /* output_token */
+            OM_uint32 FAR *,           /* ret_flags */
+            OM_uint32 FAR *            /* time_rec */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_accept_sec_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_ctx_id_t FAR *,                /* context_handle */
+            gss_cred_id_t,             /* acceptor_cred_handle */
+            gss_buffer_t,              /* input_token_buffer */
+            gss_channel_bindings_t,    /* input_chan_bindings */
+            gss_name_t FAR *,          /* src_name */
+            gss_OID FAR *,             /* mech_type */
+            gss_buffer_t,              /* output_token */
+            OM_uint32 FAR *,           /* ret_flags */
+            OM_uint32 FAR *,           /* time_rec */
+            gss_cred_id_t FAR *                /* delegated_cred_handle */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_process_context_token
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_ctx_id_t,              /* context_handle */
+            gss_buffer_t               /* token_buffer */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_delete_sec_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_ctx_id_t FAR *,                /* context_handle */
+            gss_buffer_t               /* output_token */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_context_time
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_ctx_id_t,              /* context_handle */
+            OM_uint32 FAR *            /* time_rec */
+           ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_get_mic
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           gss_qop_t,                  /* qop_req */
+           gss_buffer_t,               /* message_buffer */
+           gss_buffer_t                /* message_token */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_verify_mic
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           gss_buffer_t,               /* message_buffer */
+           gss_buffer_t,               /* message_token */
+           gss_qop_t *                 /* qop_state */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_wrap
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           int,                        /* conf_req_flag */
+           gss_qop_t,                  /* qop_req */
+           gss_buffer_t,               /* input_message_buffer */
+           int FAR *,                  /* conf_state */
+           gss_buffer_t                /* output_message_buffer */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_unwrap
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           gss_buffer_t,               /* input_message_buffer */
+           gss_buffer_t,               /* output_message_buffer */
+           int FAR *,                  /* conf_state */
+           gss_qop_t FAR *             /* qop_state */
+          ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_display_status
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            OM_uint32,                 /* status_value */
+            int,                       /* status_type */
+            gss_OID,                   /* mech_type (used to be const) */
+            OM_uint32 FAR *,           /* message_context */
+            gss_buffer_t               /* status_string */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_indicate_mechs
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_OID_set FAR *          /* mech_set */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_compare_name
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_name_t,                        /* name1 */
+            gss_name_t,                        /* name2 */
+            int FAR *                  /* name_equal */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_display_name
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_name_t,                        /* input_name */
+            gss_buffer_t,              /* output_name_buffer */
+            gss_OID FAR *              /* output_name_type */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_name
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_buffer_t,              /* input_name_buffer */
+            gss_OID,                   /* input_name_type(used to be const) */
+            gss_name_t FAR *           /* output_name */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_name
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_name_t FAR *           /* input_name */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_buffer
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_buffer_t               /* buffer */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_oid_set
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_OID_set FAR *          /* set */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_cred
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+            gss_cred_id_t,             /* cred_handle */
+            gss_name_t FAR *,          /* name */
+            OM_uint32 FAR *,           /* lifetime */
+            gss_cred_usage_t FAR *,    /* cred_usage */
+            gss_OID_set FAR *          /* mechanisms */
+           ));
+
+/* Last argument new for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           gss_name_t FAR *,           /* src_name */
+           gss_name_t FAR *,           /* targ_name */
+           OM_uint32 FAR *,            /* lifetime_rec */
+           gss_OID FAR *,              /* mech_type */
+           OM_uint32 FAR *,            /* ctx_flags */
+           int FAR *,                  /* locally_initiated */
+           int FAR *                   /* open */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_wrap_size_limit
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t,               /* context_handle */
+           int,                        /* conf_req_flag */
+           gss_qop_t,                  /* qop_req */
+           OM_uint32,                  /* req_output_size */
+           OM_uint32 *                 /* max_input_size */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_name_object
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           void FAR *,                 /* input_name */
+           gss_OID,                    /* input_name_type */
+           gss_name_t FAR *            /* output_name */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_name_object
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_name_t,                 /* input_name */
+           gss_OID,                    /* desired_name_type */
+           void FAR * FAR *            /* output_name */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_add_cred
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_cred_id_t,              /* input_cred_handle */
+           gss_name_t,                 /* desired_name */
+           gss_OID,                    /* desired_mech */
+           gss_cred_usage_t,           /* cred_usage */
+           OM_uint32,                  /* initiator_time_req */
+           OM_uint32,                  /* acceptor_time_req */
+           gss_cred_id_t FAR *,        /* output_cred_handle */
+           gss_OID_set FAR *,          /* actual_mechs */
+           OM_uint32 FAR *,            /* initiator_time_rec */
+           OM_uint32 FAR *             /* acceptor_time_rec */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_cred_by_mech
+PROTOTYPE( (OM_uint32  FAR *,          /* minor_status */
+           gss_cred_id_t,              /* cred_handle */
+           gss_OID,                    /* mech_type */
+           gss_name_t FAR *,           /* name */
+           OM_uint32 FAR *,            /* initiator_lifetime */
+           OM_uint32 FAR *,            /* acceptor_lifetime */
+           gss_cred_usage_t FAR *      /* cred_usage */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_sec_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_ctx_id_t FAR *,         /* context_handle */
+           gss_buffer_t                /* interprocess_token */
+           ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_import_sec_context
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_buffer_t,               /* interprocess_token */
+           gss_ctx_id_t FAR *          /* context_handle */
+           ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_release_oid
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID FAR *               /* oid */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_create_empty_oid_set
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID_set FAR *           /* oid_set */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_add_oid_set_member
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID,                    /* member_oid */
+           gss_OID_set FAR *           /* oid_set */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_test_oid_set_member
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID,                    /* member */
+           gss_OID_set,                /* set */
+           int FAR *                   /* present */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_str_to_oid
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_buffer_t,               /* oid_str */
+           gss_OID FAR *               /* oid */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_oid_to_str
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID,                    /* oid */
+           gss_buffer_t                /* oid_str */
+          ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_inquire_names_for_mech
+PROTOTYPE( (OM_uint32 FAR *,           /* minor_status */
+           gss_OID,                    /* mechanism */
+           gss_OID_set FAR *           /* name_types */
+          ));
+
+/*
+ * The following routines are obsolete variants of gss_get_mic, gss_wrap,
+ * gss_verify_mic and gss_unwrap.  They should be provided by GSSAPI V2
+ * implementations for backwards compatibility with V1 applications.  Distinct
+ * entrypoints (as opposed to #defines) should be provided, to allow GSSAPI
+ * V1 applications to link against GSSAPI V2 implementations.
+ */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_sign
+PROTOTYPE( (OM_uint32 FAR *,    /* minor_status */
+            gss_ctx_id_t,      /* context_handle */
+            int,               /* qop_req */
+            gss_buffer_t,      /* message_buffer */
+            gss_buffer_t       /* message_token */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_verify
+PROTOTYPE( (OM_uint32 FAR *,    /* minor_status */
+            gss_ctx_id_t,      /* context_handle */
+            gss_buffer_t,      /* message_buffer */
+            gss_buffer_t,      /* token_buffer */
+            int FAR *           /* qop_state */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_seal
+PROTOTYPE( (OM_uint32 FAR *,    /* minor_status */
+            gss_ctx_id_t,      /* context_handle */
+            int,               /* conf_req_flag */
+            int,               /* qop_req */
+            gss_buffer_t,      /* input_message_buffer */
+            int FAR *,          /* conf_state */
+            gss_buffer_t       /* output_message_buffer */
+           ));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_unseal
+PROTOTYPE( (OM_uint32 FAR *,    /* minor_status */
+            gss_ctx_id_t,      /* context_handle */
+            gss_buffer_t,      /* input_message_buffer */
+            gss_buffer_t,      /* output_message_buffer */
+            int FAR *,          /* conf_state */
+            int FAR *           /* qop_state */
+           ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_export_name
+PROTOTYPE(     (OM_uint32  *,          /* minor_status */
+                const gss_name_t,      /* input_name */
+                gss_buffer_t           /* exported_name */
+       ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_duplicate_name
+PROTOTYPE(     (OM_uint32  *,          /* minor_status */
+                const gss_name_t,      /* input_name */
+                gss_name_t *           /* dest_name */
+       ));
+
+/* New for V2 */
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_canonicalize_name
+PROTOTYPE(     (OM_uint32  *,          /* minor_status */
+                const gss_name_t,      /* input_name */
+                const gss_OID,         /* mech_type */
+                gss_name_t *           /* output_name */
+       ));
+
+/* Macintosh CFM-68K magic incantation */
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack()
+#endif
+
+#ifdef PRAGMA_IMPORT_OFF
+#pragma import off
+#elif PRAGMA_IMPORT
+#pragma import reset
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* XXXX these are not part of the GSSAPI C bindings!  (but should be) */
+
+#define GSS_CALLING_ERROR_FIELD(x) \
+   (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
+#define GSS_ROUTINE_ERROR_FIELD(x) \
+   (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
+#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
+   (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
+
+/* XXXX This is a necessary evil until the spec is fixed */
+#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
+
+#endif /* _GSSAPI_H_ */
diff --git a/mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi_krb5.h b/mac/CommonKClient/mac_kclient3/Headers/GSS/gssapi_krb5.h
new file mode 100755 (executable)
index 0000000..05593e4
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * Copyright 1993 by OpenVision Technologies, Inc.
+ * 
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appears in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of OpenVision not be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OpenVision makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ * 
+ * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OPENVISION 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 _GSSAPI_KRB5_H_
+#define _GSSAPI_KRB5_H_
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+       #include <KerberosSupport/KerberosSupport.h>
+#endif
+
+#if TARGET_OS_MAC
+#include <Kerberos5/Kerberos5.h>
+#else
+#include <krb5.h>
+#endif
+
+/* C++ friendlyness */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Reserved static storage for GSS_oids.  See rfc 1964 for more details. */
+
+/* 2.1.1. Kerberos Principal Name Form: */
+GSS_DLLIMP extern const gss_OID_desc * const GSS_KRB5_NT_PRINCIPAL_NAME;
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * krb5(2) krb5_name(1)}.  The recommended symbolic name for this type
+ * is "GSS_KRB5_NT_PRINCIPAL_NAME". */
+
+/* 2.1.2. Host-Based Service Name Form */
+#define GSS_KRB5_NT_HOSTBASED_SERVICE_NAME GSS_C_NT_HOSTBASED_SERVICE
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) service_name(4)}.  The previously recommended symbolic
+ * name for this type is "GSS_KRB5_NT_HOSTBASED_SERVICE_NAME".  The
+ * currently preferred symbolic name for this type is
+ * "GSS_C_NT_HOSTBASED_SERVICE". */
+
+/* 2.2.1. User Name Form */
+#define GSS_KRB5_NT_USER_NAME GSS_C_NT_USER_NAME    
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) user_name(1)}.  The recommended symbolic name for this
+ * type is "GSS_KRB5_NT_USER_NAME". */
+
+/* 2.2.2. Machine UID Form */
+#define GSS_KRB5_NT_MACHINE_UID_NAME GSS_C_NT_MACHINE_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) machine_uid_name(2)}.  The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_MACHINE_UID_NAME". */
+
+/* 2.2.3. String UID Form */
+#define GSS_KRB5_NT_STRING_UID_NAME GSS_C_NT_STRING_UID_NAME
+/* This name form shall be represented by the Object Identifier {iso(1)
+ * member-body(2) United States(840) mit(113554) infosys(1) gssapi(2)
+ * generic(1) string_uid_name(3)}.  The recommended symbolic name for
+ * this type is "GSS_KRB5_NT_STRING_UID_NAME". */ 
+
+extern const gss_OID_desc * const gss_mech_krb5;
+extern const gss_OID_desc * const gss_mech_krb5_old;
+extern const gss_OID_desc * const gss_mech_krb5_v2;
+extern const gss_OID_set_desc * const gss_mech_set_krb5;
+extern const gss_OID_set_desc * const gss_mech_set_krb5_old;
+extern const gss_OID_set_desc * const gss_mech_set_krb5_both;
+extern const gss_OID_set_desc * const gss_mech_set_krb5_v2;
+extern const gss_OID_set_desc * const gss_mech_set_krb5_v1v2;
+
+extern const gss_OID_desc * const gss_nt_krb5_name;
+extern const gss_OID_desc * const gss_nt_krb5_principal;
+
+extern const gss_OID_desc krb5_gss_oid_array[];
+
+#define gss_krb5_nt_general_name       gss_nt_krb5_name
+#define gss_krb5_nt_principal          gss_nt_krb5_principal
+#define gss_krb5_nt_service_name       gss_nt_service_name
+#define gss_krb5_nt_user_name          gss_nt_user_name
+#define gss_krb5_nt_machine_uid_name   gss_nt_machine_uid_name
+#define gss_krb5_nt_string_uid_name    gss_nt_string_uid_name
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_krb5_get_tkt_flags 
+       PROTOTYPE((OM_uint32 *minor_status,
+                  gss_ctx_id_t context_handle,
+                  krb5_flags *ticket_flags));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_krb5_copy_ccache
+       PROTOTYPE((OM_uint32 *minor_status,
+                  gss_cred_id_t cred_handle,
+                  krb5_ccache out_ccache));
+
+GSS_DLLIMP OM_uint32 KRB5_CALLCONV gss_krb5_ccache_name
+       PROTOTYPE((OM_uint32 *minor_status, const char *name,
+                  const char **out_name));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GSSAPI_KRB5_H_ */
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KClient/KClient.h b/mac/CommonKClient/mac_kclient3/Headers/KClient/KClient.h
new file mode 100755 (executable)
index 0000000..924da13
--- /dev/null
@@ -0,0 +1 @@
+/*\r * KClient 3.0 API declarations\r * See KClient30-API.html\r *\r * $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KClient/KClient.h,v 1.2 2001/12/04 02:05:38 rjs3 Exp $\r */\r\r#ifndef __KCLIENT__\r#define     __KCLIENT__\r\r/* Constants */\r\renum {\r   /* No error */\r kcNoError                                       = 0,\r   \r       /* General runtime errors */\r   kcErrNoMemory                           = 23000,\r       kcErrBadParam,\r\r        /* Various invalid structures */\r       kcErrInvalidSession                     = 23010,\r       kcErrInvalidPrincipal,\r kcErrInvalidAddress,\r   kcErrInvalidFile,\r\r     /* Missing required settings in the session */\r kcErrNoClientPrincipal          = 23020,\r       kcErrNoServerPrincipal,\r        kcErrNoLocalAddress,\r   kcErrNoRemoteAddress,\r  kcErrNoSessionKey,\r     kcErrNoServiceKey,\r     kcErrNoChecksum,\r       \r       kcErrNotLoggedIn                        = 23030,\r       kcErrUserCancelled,\r    kcErrIncorrectPassword,\r        \r       kcErrBufferTooSmall                     = 23040,\r       kcErrKeyFileAccess,\r    kcErrFileNotFound,\r     kcErrInvalidPreferences,\r       kcErrChecksumMismatch,\r \r       kcFirstKerberosError                            = 20000,\r       kcLastKerberosError                                     = kcFirstKerberosError + 256\r};\r\r#ifndef rez\r\r#include <KerberosSupport/KerberosSupport.h>\r#include <CredentialsCache/CredentialsCache.h>\r#include <KerberosProfile/KerberosProfile.h>\r#include <KerberosDES/KerberosDES.h>\r#include <KClient/KClientTypes.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <CoreServices/CoreServices.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <Files.h>\r#else\r    #error "Unknown OS"\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r/* Functions */\r\rOSStatus KClientGetVersion (\r UInt16*                                 outMajorVersion,\r       UInt16*                                 outMinorVersion,\r       const char**                    outVersionString);\r\r/* Initialization / destruction */\r\rOSStatus KClientNewClientSession (\r     KClientSession*                 outSession);\r   \rOSStatus KClientNewServerSession (\r    KClientSession*                 inSession,\r     KClientPrincipal                inService);\r    \rOSStatus KClientDisposeSession (\r      KClientSession                  inSession);\r    \r/* Accessing session properties */\rOSStatus KClientGetClientPrincipal (\r       KClientSession                  inSession,\r     KClientPrincipal*               outPrincipal);\r \rOSStatus KClientSetClientPrincipal (\r  KClientSession                  inSession,\r     KClientPrincipal                inPrincipal);\r  \rOSStatus KClientGetServerPrincipal (\r  KClientSession                  inSession,\r     KClientPrincipal*               outPrincipal);\r \rOSStatus KClientSetServerPrincipal (\r  KClientSession                  inSession,\r     KClientPrincipal                inPrincipal);\r  \rOSStatus KClientGetLocalAddress (\r     KClientSession                  inSession,\r     KClientAddress*                 outLocalAddress);\r      \rOSStatus KClientSetLocalAddress (\r     KClientSession                  inSession,\r     const KClientAddress*   inLocalAddress);\r       \rOSStatus KClientGetRemoteAddress (\r    KClientSession                  inSession,\r     KClientAddress*                 outRemoteAddress);\r     \rOSStatus KClientSetRemoteAddress (\r    KClientSession                  inSession,\r     const KClientAddress*   inRemoteAddress);\r      \rOSStatus KClientGetSessionKey (\r       KClientSession                  inSession,\r     KClientKey*                             outKey);\r\rOSStatus KClientGetExpirationTime (\r  KClientSession                  inSession,\r     UInt32*                                 outExpiration);\r        \rOSStatus KClientSetKeyFile (\r  KClientSession                  inSession,\r     const KClientFile*              inKeyFile);\r    \r/* Logging in and out (client) */\r\rOSStatus KClientLogin (\r    KClientSession                  inSession);\r\rOSStatus KClientPasswordLogin (\r   KClientSession                  inSession,\r     const char*                     inPassword);\r   \rOSStatus KClientKeyFileLogin (\r        KClientSession                  inSession);\r\r/*OSStatus KClientKeyLogin (\r      KClientSession                  inSession,\r     const KClientKey*               inKey);*/\r      \rOSStatus KClientLogout (\r      KClientSession                  inSession);\r    \r/* Accessing service keys (server) */\r\rOSStatus KClientGetServiceKey (\r        KClientSession                  inSession,\r     UInt32                                  inVersion,\r     KClientKey*                             outKey);\r       \rOSStatus KClientAddServiceKey (\r       KClientSession                  inSession,\r     UInt32                                  inVersion,\r     const KClientKey*               inKey);\r        \r/* Authenticating to a service (client) */\r\rOSStatus KClientGetTicketForService (\r     KClientSession                  inSession,\r     UInt32                                  inChecksum,\r    void*                                   outBuffer,\r     UInt32*                                 ioBufferLength);\r       \rOSStatus KClientGetAuthenticatorForService (\r  KClientSession                  inSession,\r     UInt32                                  inChecksum,\r    const char*                             inApplicationVersion,\r  void*                                   outBuffer,\r     UInt32*                                 ioBufferLength);\r\rOSStatus KClientVerifyEncryptedServiceReply (\r        KClientSession                  inSession,\r     const void*                             inBuffer,\r      UInt32                                  inBufferLength);\r       \rOSStatus KClientVerifyProtectedServiceReply (\r KClientSession                  inSession,\r     const void*                             inBuffer,\r      UInt32                                  inBufferLength);\r       \r/* Authenticating a client (server) */\r\rOSStatus KClientVerifyAuthenticator (\r KClientSession                  inSession,\r     const void*                             inBuffer,\r      UInt32                                  inBufferLength);\r       \rOSStatus KClientGetEncryptedServiceReply (\r    KClientSession                  inSession,\r     void*                                   outBuffer,\r     UInt32*                                 ioBufferSize);\r \rOSStatus KClientGetProtectedServiceReply (\r    KClientSession                  inSession,\r     void*                                   outBuffer,\r     UInt32*                                 ioBufferSize);\r \r/* Communicating between a server and a client */\r\rOSStatus KClientEncrypt (\r  KClientSession                  inSession,\r     const void*                             inPlainBuffer,\r UInt32                                  inPlainBufferLength,\r   void*                                   outEncryptedBuffer,\r    UInt32*                                 ioEncryptedBufferLength);\r\rOSStatus KClientDecrypt (\r   KClientSession                  inSession,\r     void*                                   inEncryptedBuffer,\r     UInt32                                  inDecryptedBufferLength,\r       UInt32*                                 outPlainOffset,\r        UInt32*                                 outPlainLength);\r       \rOSStatus KClientProtectIntegrity (\r    KClientSession                  inSession,\r     const void*                             inPlainBuffer,\r UInt32                                  inPlainBufferLength,\r   void*                                   outProtectedBuffer,\r    UInt32*                                 ioProtectedBufferLength);\r\rOSStatus KClientVerifyIntegrity (\r   KClientSession                  inSession,\r     void*                                   inProtectedBuffer,\r     UInt32                                  inProtectedBufferLength,\r       UInt32*                                 outPlainOffset,\r        UInt32*                                 outPlainLength);\r       \r/* Miscellaneous */\r\rOSStatus KClientPasswordToKey (\r  KClientSession                  inSession,\r     const char*                             inPassword,\r    KClientKey*                             outKey);\r       \r/* Getting to other APIs */\r\rOSStatus KClientGetCCacheReference (\r     KClientSession                  inSession,\r     cc_ccache_t*                    outCCacheReference);\r\rOSStatus KClientGetProfileHandle (\r       KClientSession                  inSession,\r     profile_t*                              outProfileHandle);\r\r/* Principal manipulation */\r\rOSStatus KClientV4StringToPrincipal (\r        const char*                             inPrincipalString,\r     KClientPrincipal*               outPrincipal);\r \rOSStatus KClientPrincipalToV4String (\r KClientPrincipal                inPrincipal,\r   char*                                   outPrincipalString);\r   \rOSStatus KClientPrincipalToV4Triplet (\r        KClientPrincipal                inPrincipal,\r   char*                                   outName,\r       char*                                   outInstance,\r   char*                                   outRealm);\r     \rOSStatus KClientDisposePrincipal (\r    KClientPrincipal                inPrincipal);\r          \r#ifdef __cplusplus\r}\r#endif\r\r#endif /* !rez */\r\r#endif /* __KCLIENT__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KClient/KClientTypes.h b/mac/CommonKClient/mac_kclient3/Headers/KClient/KClientTypes.h
new file mode 100755 (executable)
index 0000000..0d2b3e0
--- /dev/null
@@ -0,0 +1 @@
+#ifndef        KClientTypes_h\r#define  KClientTypes_h\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r#include <KerberosDES/KerberosDES.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <CoreServices/CoreServices.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <Files.h>\r#else\r    #error "Unknown OS"\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r/* Constants */\r\r/* Different kerberos name formats */\renum { \r  KClientLocalName,                               /* Don't specify realm */\r      KClientCommonName,                              /* Only specify realm if it isn't local */\r     KClientFullName                                 /* Always specify realm */\r};\r\r/* Opaque types */\r\rstruct KClientSessionOpaque;\rtypedef struct KClientSessionOpaque* KClientSession;\r\rstruct KClientPrincipalOpaque;\rtypedef struct KClientPrincipalOpaque* KClientPrincipal;\r\r/* Visible types */\r\rtypedef FSSpec KClientFile;\r\rstruct KClientAddress {\r       UInt32                          address;\r       UInt16                          port;\r};\rtypedef struct KClientAddress KClientAddress;\r\rstruct KClientKey {\r    des_cblock                      key;\r};\rtypedef struct KClientKey KClientKey;\r\rstruct KClientKeySchedule {\r     des_key_schedule        keySchedule;\r};\rtypedef struct KClientKeySchedule KClientKeySchedule;\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* KClientTypes_h */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KClientCompat/KClientCompat.h b/mac/CommonKClient/mac_kclient3/Headers/KClientCompat/KClientCompat.h
new file mode 100755 (executable)
index 0000000..d5c9c8e
--- /dev/null
@@ -0,0 +1 @@
+/* \r * KClient 1.9 deprecated API\r *\r * $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KClientCompat/KClientCompat.h,v 1.2 2001/12/04 02:05:40 rjs3 Exp $\r */\r\r#ifndef        __KCLIENTCOMPAT__\r#define       __KCLIENTCOMPAT__\r\r/* Constants */\r\r/* Error codes, only listing the ones actually returned by the library */\renum {\r   cKrbMapDoesntExist                      = -1020,        /* tried to access a map that doesn't exist (index too large, or criteria doesn't match anything) */\r   cKrbSessDoesntExist                     = -1019,        /* tried to access a session that doesn't exist */\r     cKrbCredsDontExist                      = -1018,        /* tried to access credentials that don't exist */\r     cKrbUserCancelled                       = -1016,        /* user cancelled a log in operation */\r        cKrbConfigurationErr            = -1015,        /* Kerberos Preference file is not configured properly */\r      cKrbServerRejected                      = -1014,        /* A server rejected our ticket */\r     cKrbServerImposter                      = -1013,        /* Server appears to be a phoney */\r    cKrbServerRespIncomplete        = -1012,        /* Server response is not complete */\r  cKrbNotLoggedIn                         = -1011,        /* Returned by cKrbGetUserName if user is not logged in */\r     cKrbAppInBkgnd                          = -1008,        /* driver won't put up password dialog when in background */\r   cKrbInvalidSession                      = -1007,        /* invalid structure passed to KClient/KServer routine */\r              \r       cKrbKerberosErrBlock            = -20000        /* start of block of 256 kerberos error numbers */\r};\r\r#ifndef rez\r\r#if PRAGMA_ONCE\r#pragma once\r#endif /* PRAGMA_ONCE */\r\r#include <Kerberos4/Kerberos4.h>\r#include <KClient/KClientTypes.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\rtypedef KClientSession KClientSessionInfo;\r\renum {\r      KClientLoggedIn,\r       KClientNotLoggedIn\r};\r\rOSErr KClientVersionCompat (\r    SInt16*                                         outMajorVersion,\r       SInt16*                                         outMinorVersion,\r       char*                                           outVersionString);\r\rOSErr KClientNewSessionCompat (\r    KClientSessionInfo*                     inSession,\r     UInt32                                          inLocalAddress,\r        UInt16                                          inLocalPort,\r   UInt32                                          inRemoteAddress,\r       UInt16                                          inRemotePort);\r \rOSErr KClientDisposeSessionCompat (\r   KClientSessionInfo*                     inSession);\r    \rOSErr KClientGetTicketForServiceCompat (\r      KClientSessionInfo*                     inSession,\r     char*                                           inService,\r     void*                                           inBuffer,\r      UInt32*                                         outBufferLength);\r      \rOSErr KClientGetTicketForServiceWithChecksumCompat (\r  KClientSessionInfo*                     inSession,\r     UInt32                                          inChecksum,\r    char*                                           inService,\r     void*                                           inBuffer,\r      UInt32*                                         outBufferLength);\r      \rOSErr KClientLoginCompat (\r    KClientSessionInfo*                     inSession,\r     KClientKey*                                     outPrivateKey);\r        \rOSErr KClientPasswordLoginCompat (\r    KClientSessionInfo*                     inSession,\r     char*                                           inPassword,\r    KClientKey*                                     outPrivateKey);\r        \rOSErr KClientLogoutCompat (void);\r\rSInt16 KClientStatusCompat (void);\r\rOSErr KClientGetSessionKeyCompat (\r     KClientSessionInfo*                     inSession,\r     KClientKey*                                     outSessionKey);\r        \rOSErr KClientEncryptCompat (\r  KClientSessionInfo*                     inSession,\r     void*                                           inPlainBuffer,\r UInt32                                          inPlainBufferLength,\r   void*                                           outEncryptedBuffer,\r    UInt32*                                         ioEncryptedBufferLength);\r      \rOSErr KClientDecryptCompat (\r  KClientSessionInfo*                     inSession,\r     void*                                           inEncryptedBuffer,\r     UInt32                                          inEncryptedBufferLength,\r       UInt32*                                         outPlainBufferOffset,\r  UInt32*                                         outPlainBufferLength);\r\rOSErr KClientProtectIntegrityCompat (\r  KClientSessionInfo*                     inSession,\r     void*                                           inPlainBuffer,\r UInt32                                          inPlainBufferLength,\r   void*                                           outProtectedBuffer,\r    UInt32*                                         ioProtectedBufferLength);\r\rOSErr KClientVerifyIntegrityCompat (\r        KClientSessionInfo*                     inSession,\r     void*                                           inProtectedBuffer,\r     UInt32                                          inProtectedBufferLength,\r       UInt32*                                         outPlainBufferOffset,\r  UInt32*                                         outPlainBufferLength);\r\rOSErr KServerNewSessionCompat (\r        KClientSessionInfo*                     inSession,\r     char*                                           inService,\r     UInt32                                          inLocalAddress,\r        UInt16                                          inLocalPort,\r   UInt32                                          inRemoteAddress,\r       UInt16                                          inRemotePort);\r\rOSErr KServerVerifyTicketCompat (\r      KClientSessionInfo*                     inSession,\r     void*                                           inBuffer,\r      char*                                           inFilename);\r   \rOSErr KServerGetReplyTicketCompat (\r   KClientSessionInfo*                     inSession,\r     void*                                           outBuffer,\r     UInt32*                                         ioBufferLength);\r       \rOSErr KServerAddKeyCompat (\r   KClientSessionInfo*                     inSession,\r     KClientKey*                                     inPrivateKey,\r  char*                                           inService,\r     SInt32                                          inVersion,\r     char*                                           inFilename);\r   \rOSErr KServerGetKeyCompat (\r   KClientSessionInfo*                     inSession,\r     KClientKey*                                     outPrivateKey,\r char*                                           inService,\r     SInt32                                          inVersion,\r     char*                                           inFilename);\r\rOSErr KServerGetSessionTimeRemainingCompat (\r     KClientSessionInfo*                     inSession,\r     SInt32*                                         outSeconds);\r   \rOSErr KClientGetSessionUserNameCompat (\r       KClientSessionInfo*                     inSession,\r     char*                                           outUserName,\r   SInt16                                          inNameType);\r\rOSErr KClientMakeSendAuthCompat (\r        KClientSessionInfo*                     inSession,\r     char*                                           inService,\r     void*                                           outBuffer,\r     UInt32*                                         ioBufferLength,\r        SInt32                                          inChecksum,\r    char*                                           inApplicationVersion);\r \rOSErr KClientVerifyReplyTicketCompat (\r        KClientSessionInfo*                     inSession,\r     void*                                           inBuffer,\r      UInt32*                                         ioBufferLength);\r       \rOSErr KClientVerifyUnencryptedReplyTicketCompat (\r     KClientSessionInfo*                     inSession,\r     void*                                           inBuffer,\r      UInt32*                                         ioBufferLength);\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* !rez */\r\r#endif /* __KCLIENTCOMPAT__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KClientDeprecated/KClientDeprecated.h b/mac/CommonKClient/mac_kclient3/Headers/KClientDeprecated/KClientDeprecated.h
new file mode 100755 (executable)
index 0000000..05b104d
--- /dev/null
@@ -0,0 +1 @@
+/* \r * KClient 1.9 deprecated API\r *\r * $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KClientDeprecated/KClientDeprecated.h,v 1.2 2001/12/04 02:05:41 rjs3 Exp $\r */\r\r#ifndef        __KCLIENTDEPRECATED__\r#define   __KCLIENTDEPRECATED__\r\r#if PRAGMA_ONCE\r#pragma once\r#endif /* PRAGMA_ONCE */\r\r#include <KerberosSupport/KerberosSupport.h>\r#include <Kerberos4/Kerberos4.h>\r#include <KClient/KClientTypes.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r/*\r * Important!\r *\r * The following functions are deprecated. They will be removed from the library\r * and the header files in the future. See documentation for moving to KClient\r * 3.0 API to see how you can update your code.\r */\r\rOSStatus\rKClientCacheInitialTicketDeprecated (\r KClientSession*                 inSession,\r     char*                                   inService);\r\rOSStatus KClientGetLocalRealmDeprecated (\r char*                                   outRealm);\r\rOSStatus KClientSetLocalRealmDeprecated (\r  const char*                             inRealm);\r\rOSStatus KClientGetRealmDeprecated (\r        const char*                             inHost,\r        char*                                   outRealm);\r\rOSStatus KClientAddRealmMapDeprecated (\r    char*                                   inHost,\r        char*                                   inRealm);\r\rOSStatus KClientDeleteRealmMapDeprecated (\r  char*                                   inHost);\r\rOSStatus KClientGetNthRealmMapDeprecated (\r   SInt32                                  inIndex,\r       char*                                   outHost,\r       char*                                   outRealm);\r\rOSStatus KClientGetNthServerDeprecated (\r   SInt32                                  inIndex,\r       char*                                   outHost,\r       char*                                   inRealm,\r       Boolean                                 inAdmin);\r\rOSStatus KClientAddServerMapDeprecated (\r    char*                                   inHost,\r        char*                                   inRealm,\r       Boolean                                 inAdmin);\r\rOSStatus KClientDeleteServerMapDeprecated (\r char*                                   inHost,\r        char*                                   inRealm);\r\rOSStatus KClientGetNthServerMapDeprecated (\r SInt32                                  inIndex,\r       char*                                   outHost,\r       char*                                   outRealm,\r      Boolean*                                outAdmin);\r\rOSStatus KClientGetNthServerPortDeprecated (\r       SInt32                                  inIndex,\r       UInt16*                                 outPort);\r\rOSStatus KClientSetNthServerPortDeprecated (\r        SInt32                                  inIndex,\r       UInt16                                  inPort);\r\rOSStatus KClientGetNumSessionsDeprecated (\r   SInt32*                                 outSessions);\r\rOSStatus KClientGetNthSessionDeprecated (\r       SInt32                                  inIndex,\r       char*                                   outName,\r       char*                                   outInstance,\r   char*                                   outRealm);\r\rOSStatus KClientDeleteSessionDeprecated (\r  char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm);\r\rOSStatus KClientGetCredentialsDeprecated (\r  char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm,\r       CREDENTIALS*                    outCred);\r\rOSStatus KClientAddCredentialsDeprecated (\r  char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm,\r       CREDENTIALS*                    inCred);\r\rOSStatus KClientDeleteCredentialsDeprecated (\r        char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm, \r      char*                                   inSname,\r       char*                                   inSinstance,\r   char*                                   inSrealm);\r\rOSStatus KClientGetNumCredentialsDeprecated (\r      SInt32*                                 outNumCredentials,\r     char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm);\r\rOSStatus\rKClientGetNthCredentialDeprecated (\r        SInt32                                  inIndex,\r       char*                                   inName,\r        char*                                   inInstance,\r    char*                                   inRealm,\r       char*                                   inSname,\r       char*                                   inSinstance,\r   char*                                   inSrealm);\r\rOSStatus\rKClientGetUserNameDeprecated (\r    char*                                   outUserName);\r  \rvoid\rKClientGetErrorTextDeprecated (\r  OSErr                                   inError,\r       char*                                   outBuffer);\r\r\r/*\r * Warning!\r *\r * The following are K5Client calls. Not only are they deprecated, but they should\r * never have existed in the first place. They are here so that KClient can swallow\r * K5Client (Yummmmmm)\r */\r      \rOSStatus\rK5ClientGetTicketForServiceDeprecated (\r      char*                   inService,\r     void*                   outBuffer,\r     UInt32*                 outBufferLength);\r\rOSStatus\rK5ClientGetAuthenticatorForServiceDeprecated (\r     char*                   inService,\r     char*                   inApplicationVersion,\r  void*                   outBuffer,\r     UInt32*                 outBufferLength);\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* __KCLIENTDEPRECATED__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos/Kerberos.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos/Kerberos.h
new file mode 100755 (executable)
index 0000000..2e579be
--- /dev/null
@@ -0,0 +1 @@
+/* \r * Kerberos Framework Header File\r *\r * $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/Kerberos/Kerberos.h,v 1.2 2001/12/04 02:05:45 rjs3 Exp $\r */\r\r#ifndef __KERBEROS__\r#define __KERBEROS__\r\r#ifndef __KERBEROSSUPPORT__\r#include <KerberosSupport/KerberosSupport.h>\r#endif /* __KERBEROSSUPPORT__ */\r\r#ifndef __KERBEROSPREFERENCES__\r#include <KerberosPreferences/KerberosPreferences.h>\r#endif /* __KERBEROSPREFERENCES__ */\r\r#ifndef __KERBEROSDES__\r#include <KerberosDES/KerberosDES.h>\r#endif /* __KERBEROSDES__ */\r\r#ifndef __CREDENTIALSCACHE__\r#include <CredentialsCache/CredentialsCache.h>\r#endif /* __CREDENTIALSCACHE__ */\r\r#ifndef __KERBEROSLOGIN__\r#include <KerberosLogin/KerberosLogin.h>\r#endif /* __KERBEROSLOGIN__ */\r\r#ifndef __KERBEROSCOMERR__\r#include <KerberosComErr/KerberosComErr.h>\r#endif /* __KERBEROSCOMERR__ */\r\r#ifndef __KERBEROSPROFILE__\r#include <KerberosProfile/KerberosProfile.h>\r#endif /* __KERBEROSPROFILE__ */\r\r#ifndef __KERBEROS5__\r#include <Kerberos5/Kerberos5.h>\r#endif /* __KERBEROS5__ */\r\r#ifndef __GSS__\r#include <GSS/GSS.h>\r#endif /* __GSS__ */\r\r#ifndef __KERBEROS4__\r#include <Kerberos4/Kerberos4.h>\r#endif /* __KERBEROS4__ */\r\r/* This is private for Macdev\r#ifndef __KERBEROSWRAPPERS__\r#include <KerberosWrappers/KerberosWrappers.h>\r#endif /* __KERBEROSWRAPPERS__ */\r\r#ifndef __KCLIENT__\r#include <KClient/KClient.h>\r#endif /* __KCLIENT__ */\r\r#ifndef __KCLIENTCOMPAT__\r#include <KClientCompat/KClientCompat.h>\r#endif /* __KCLIENTCOMPAT__ */\r\r#ifndef __KCLIENTDEPRECATED__\r#include <KClientDeprecated/KClientDeprecated.h>\r#endif /* __KCLIENTDEPRECATED__ */\r\r#endif /* __KERBEROS__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos4/Kerberos4.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos4/Kerberos4.h
new file mode 100755 (executable)
index 0000000..ef9e57e
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Kerberos4.h\r *\r * Copyright 1987, 1988 by the Massachusetts Institute of Technology. \r *\r * For copying and distribution information, please see the file\r * <mit-copyright.h>. \r *\r * External defintions for the Kerberos library.  Internal definitions\r * (visible to Kerberos library source files) are in kerberos.h.\r */\r\r/* Only one time, please */\r#ifndef     __KERBEROS4__\r#define __KERBEROS4__\r\r#include <Kerberos4/krb.h>\r\r#endif /* __KERBEROS4__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos4/krb.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos4/krb.h
new file mode 100755 (executable)
index 0000000..81ea242
--- /dev/null
@@ -0,0 +1 @@
+/*\r * krb-sed.h\r *\r * Copyright 1987, 1988 by the Massachusetts Institute of Technology. \r *\r * For copying and distribution information, please see the file\r * <mit-copyright.h>. \r *\r * External defintions for the Kerberos library.  Internal definitions\r * (visible to Kerberos library source files) are in kerberos.h.\r */\r\r/* Only one time, please */\r#ifndef       KRB_H\r#define KRB_H\r\r/* Kerberos 4 Error Codes: */\r#define KSUCCESS                                 0\r#define KFAILURE                                 255\r\r#define KRB_NEVERDATE (0xFFFFFFFFUL)\r\r/* Error codes returned from the KDC */\r#define               KDC_OK                  0       /* Request OK */\r#define                KDC_NAME_EXP    1       /* Principal expired */\r#define         KDC_SERVICE_EXP 2       /* Service expired */\r#define           KDC_AUTH_EXP    3       /* Auth expired */\r#define              KDC_PKT_VER     4       /* Protocol version unknown */\r#define          KDC_P_MKEY_VER  5       /* Wrong master key version */\r#define          KDC_S_MKEY_VER  6       /* Wrong master key version */\r#define          KDC_BYTE_ORDER  7       /* Byte order unknown */\r#define                KDC_PR_UNKNOWN  8       /* Principal unknown */\r#define         KDC_PR_N_UNIQUE 9       /* Principal not unique */\r#define              KDC_NULL_KEY   10       /* Principal has null key */\r#define            KDC_GEN_ERR    20       /* Generic error from KDC */\r\r\r/* Values returned by get_credentials */\r#define         GC_OK                   0       /* Retrieve OK */\r#define               RET_OK                  0       /* Retrieve OK */\r#define               GC_TKFIL       21       /* Can't read ticket file */\r#define            RET_TKFIL      21       /* Can't read ticket file */\r#define            GC_NOTKT       22       /* Can't find ticket or TGT */\r#define          RET_NOTKT      22       /* Can't find ticket or TGT */\r\r\r/* Values returned by mk_ap_req         */\r#define             MK_AP_OK                0       /* Success */\r#define           MK_AP_TGTEXP   26       /* TGT Expired */\r\r/* Values returned by rd_ap_req */\r#define           RD_AP_OK                0       /* Request authentic */\r#define         RD_AP_UNDEC    31       /* Can't decode authenticator */\r#define                RD_AP_EXP      32       /* Ticket expired */\r#define            RD_AP_NYV      33       /* Ticket not yet valid */\r#define              RD_AP_REPEAT   34       /* Repeated request */\r#define          RD_AP_NOT_US   35       /* The ticket isn't for us */\r#define           RD_AP_INCON    36       /* Request is inconsistent */\r#define           RD_AP_TIME     37       /* delta_t too big */\r#define           RD_AP_BADD     38       /* Incorrect net address */\r#define             RD_AP_VERSION  39       /* protocol version mismatch */\r#define         RD_AP_MSG_TYPE 40       /* invalid msg type */\r#define          RD_AP_MODIFIED 41       /* message stream modified */\r#define           RD_AP_ORDER    42       /* message out of order */\r#define              RD_AP_UNAUTHOR 43       /* unauthorized request */\r\r/* Values returned by get_pw_tkt */\r#define         GT_PW_OK                0       /* Got password changing tkt */\r#define         GT_PW_NULL     51       /* Current PW is null */\r#define                GT_PW_BADPW    52       /* Incorrect current password */\r#define                GT_PW_PROT     53       /* Protocol Error */\r#define            GT_PW_KDCERR   54       /* Error returned by KDC */\r#define             GT_PW_NULLTKT  55       /* Null tkt returned by KDC */\r\r\r/* Values returned by send_to_kdc */\r#define           SKDC_OK                 0       /* Response received */\r#define         SKDC_RETRY     56       /* Retry count exceeded */\r#define              SKDC_CANT      57       /* Can't send request */\r\r/*\r * Values returned by get_in_tkt\r * (can also return SKDC_* and KDC errors)\r */\r\r#define           INTK_OK                 0       /* Ticket obtained */\r#define           INTK_PW_NULL   51       /* Current PW is null */\r#define                INTK_W_NOTALL  61       /* Not ALL tickets returned */\r#define          INTK_BADPW     62       /* Incorrect password */\r#define                INTK_PROT      63       /* Protocol Error */\r#define            INTK_ERR       70       /* Other error */\r\r/* Values returned by get_adtkt */\r#define         AD_OK      0      /* Ticket Obtained */\r#define         AD_NOTGT   71     /* Don't have tgt */\r\r/* Error codes returned by ticket file utilities */\r#define               NO_TKT_FIL              76      /* No ticket file found */\r#define              TKT_FIL_ACC             77      /* Couldn't access tkt file */\r#define          TKT_FIL_LCK             78      /* Couldn't lock ticket file */\r#define         TKT_FIL_FMT             79      /* Bad ticket file format */\r#define            TKT_FIL_INI             80      /* tf_init not called first */\r\r/* Error code returned by kparse_name */\r#define                KNAME_FMT               81      /* Bad Kerberos name format */\r\r/* Error code returned by krb_mk_safe */\r#define                SAFE_PRIV_ERROR -1      /* syscall error */\r\r#define KADM_RCSID                               (-1783126272)\r#define KADM_NO_REALM                            (-1783126271)\r#define KADM_NO_CRED                             (-1783126270)\r#define KADM_BAD_KEY                             (-1783126269)\r#define KADM_NO_ENCRYPT                          (-1783126268)\r#define KADM_NO_AUTH                             (-1783126267)\r#define KADM_WRONG_REALM                         (-1783126266)\r#define KADM_NO_ROOM                             (-1783126265)\r#define KADM_BAD_VER                             (-1783126264)\r#define KADM_BAD_CHK                             (-1783126263)\r#define KADM_NO_READ                             (-1783126262)\r#define KADM_NO_OPCODE                           (-1783126261)\r#define KADM_NO_HOST                             (-1783126260)\r#define KADM_UNK_HOST                            (-1783126259)\r#define KADM_NO_SERV                             (-1783126258)\r#define KADM_NO_SOCK                             (-1783126257)\r#define KADM_NO_CONN                             (-1783126256)\r#define KADM_NO_HERE                             (-1783126255)\r#define KADM_NO_MAST                             (-1783126254)\r#define KADM_NO_VERI                             (-1783126253)\r#define KADM_INUSE                               (-1783126252)\r#define KADM_UK_SERROR                           (-1783126251)\r#define KADM_UK_RERROR                           (-1783126250)\r#define KADM_UNAUTH                              (-1783126249)\r#define KADM_DATA                                (-1783126248)\r#define KADM_NOENTRY                             (-1783126247)\r#define KADM_NOMEM                               (-1783126246)\r#define KADM_NO_HOSTNAME                         (-1783126245)\r#define KADM_NO_BIND                             (-1783126244)\r#define KADM_LENGTH_ERROR                        (-1783126243)\r#define KADM_ILL_WILDCARD                        (-1783126242)\r#define KADM_DB_INUSE                            (-1783126241)\r#define KADM_INSECURE_PW                         (-1783126240)\r#define KADM_PW_MISMATCH                         (-1783126239)\r#define KADM_NOT_SERV_PRINC                      (-1783126238)\r\r#ifndef rez /* This stuff will confuse rez */\r\r#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))\r  #include <KerberosSupport/KerberosSupport.h>\r#endif\r\r#if TARGET_OS_MAC\r    #include <KerberosDES/KerberosDES.h>\r    #include <KerberosProfile/KerberosProfile.h>\r#else\r    #include <des.h>\r    #include <profile.h>\r#endif\r\r#if TARGET_API_MAC_OSX\r    #include <sys/types.h>\r    #include <sys/socket.h>\r    #include <netinet/in.h>\r#else\r    struct sockaddr_in;\r#endif\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <CoreServices/CoreServices.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <Files.h>\r#else\r #error "Unknown OS"\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif /* __cplusplus */\r\r#if PRAGMA_IMPORT\r#       pragma import on\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r       #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r#if PRAGMA_ENUM_ALWAYSINT\r      #pragma enumsalwaysint on\r#endif\r\r#if TARGET_CPU_68K\r   #pragma fourbyteints on\r#endif \r\r#if !defined(PROTOTYPE)\r#if defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32)\r#define PROTOTYPE(x) x\r#else\r#define PROTOTYPE(x) ()\r#endif\r#endif\r\r#define        INTERFACE       /* No special declaration?? FIXME. */\r#define FAR\r\r/* Sizes of types we need */\r#ifndef KRB_INT32\r#define KRB_INT32 SInt32\r#endif\r#ifndef KRB_UINT32\r#define KRB_UINT32 UInt32\r#endif\r\r/* The maximum sizes for aname, realm, sname, and instance +1 */\r#define         ANAME_SZ        40\r#define              REALM_SZ        40\r#define              SNAME_SZ        40\r#define              INST_SZ         40\r/* include space for '.' and '@' */\r#define          MAX_K_NAME_SZ   (ANAME_SZ + INST_SZ + REALM_SZ + 2)\r#define             KKEY_SZ         100\r#define             VERSION_SZ      1\r#define               MSG_TYPE_SZ     1\r#define               DATE_SZ         26      /* RTI date output */\r\r#ifndef DEFAULT_TKT_LIFE                  /* allow compile-time override */\r#define              DEFAULT_TKT_LIFE        120 /* default lifetime 10 hrs */\r#endif\r\r#define               TICKET_GRANTING_TICKET  "krbtgt"\r\r/* Definition of text structure used to pass text around */\r#define           MAX_KTXT_LEN    1250\r\rstruct ktext {\r    int     length;                                                /* Length of the text */\r    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */\r    unsigned long mbz;                                    /* zero to catch runaway strings */\r};\r\rtypedef struct ktext *KTEXT;\rtypedef struct ktext KTEXT_ST;\r\r\r/* Definitions for send_to_kdc */\r#define CLIENT_KRB_TIMEOUT      4       /* time between retries */\r#define CLIENT_KRB_RETRY     5       /* retry this many times */\r#define     CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */\r\r/* Definitions for ticket file utilities */\r#define      R_TKT_FIL       0\r#define       W_TKT_FIL       1\r\r/* Structure definition for rd_ap_req */\r\rstruct auth_dat {\r    unsigned char k_flags;               /* Flags from ticket */\r    char    pname[ANAME_SZ];    /* Principal's name */\r    char    pinst[INST_SZ];              /* His Instance */\r    char    prealm[REALM_SZ];        /* His Realm */\r    KRB_UINT32 checksum;                /* Data checksum (opt) */\r    C_Block session;                  /* Session Key */\r    int     life;                             /* Life of ticket */\r    KRB_UINT32 time_sec;           /* Time ticket issued */\r    KRB_UINT32 address;                        /* Address in ticket */\r    KTEXT_ST reply;                             /* Auth reply (opt) */\r};\r\rtypedef struct auth_dat AUTH_DAT;\r\r/* Structure definition for credentials returned by get_cred */\r\rstruct credentials {\r    char    service[ANAME_SZ];      /* Service name */\r    char    instance[INST_SZ];       /* Instance */\r    char    realm[REALM_SZ];     /* Auth domain */\r    C_Block session;                  /* Session key */\r    int     lifetime;                 /* Lifetime */\r    int     kvno;                                /* Key version number */\r    KTEXT_ST ticket_st;                        /* The ticket itself */\r    long    issue_date;                 /* The issue time */\r    char    pname[ANAME_SZ];       /* Principal's name */\r    char    pinst[INST_SZ];              /* Principal's instance */\r    KRB_UINT32 address;                      /* Address in ticket */\r    KRB_UINT32 stk_type;                /* string_to_key function needed */\r};\r\rtypedef struct credentials CREDENTIALS;\r\r/* Structure definition for rd_private_msg and rd_safe_msg */\r\rstruct msg_dat {\r    unsigned char *app_data;   /* pointer to appl data */\r    KRB_UINT32 app_length;           /* length of appl data */\r    unsigned long hash;                       /* hash to lookup replay */\r    int     swap;                           /* swap bytes? */\r    KRB_INT32    time_sec;            /* msg timestamp seconds */\r    unsigned char time_5ms;         /* msg timestamp 5ms units */\r};\r\rtypedef struct msg_dat MSG_DAT;\r\r\r/* Location of default ticket file for save_cred and get_cred */\r#ifndef    TKT_FILE\r#define        TKT_FILE                                tkt_string()\r#endif /* TKT_FILE */\r\r/* Defines for krb_sendauth, krb_mk_auth, krb_check_auth, and krb_recvauth */\r\r#define      KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */\r#define KOPT_DO_MUTUAL   0x00000002 /* do mutual auth */\r\r#define       KOPT_DONT_CANON  0x00000004 /*\r                              * don't canonicalize inst as\r                                   * a hostname\r                                   */\r\r#define        KRB_SENDAUTH_VLEN 8         /* length for version strings */\r\r#ifdef ATHENA_COMPAT\r#define      KOPT_DO_OLDSTYLE 0x00000008 /* use the old-style protocol */\r#endif /* ATHENA_COMPAT */\r\r/* Constants for KerberosProfileLib */\r#define         REALMS_V4_PROF_REALMS_SECTION           "v4 realms"\r#define             REALMS_V4_PROF_KDC                                      "kdc"\r#define           REALMS_V4_PROF_ADMIN_KDC                        "admin_server"\r#define          REALMS_V4_PROF_KPASSWD_KDC                      "kpasswd_server"\r#define                REALMS_V4_PROF_DOMAIN_SECTION           "v4 domain_realm"\r#define               REALMS_V4_PROF_LIBDEFAULTS_SECTION      "libdefaults"\r#define           REALMS_V4_PROF_LOCAL_REALM                      "default_realm"\r#define         REALMS_V4_PROF_STK                                      "string_to_key_type"\r#define            REALMS_V4_MIT_STK                                       "mit_string_to_key"\r#define             REALMS_V4_AFS_STK                                       "afs_string_to_key"\r#define             REALMS_V4_COLUMBIA_STK                          "columbia_string_to_key"\r#define                REALMS_V4_DEFAULT_REALM                         "default_realm"\r#define         REALMS_V4_NO_ADDRESSES                          "noaddresses"\r\r/* Define a couple of function types including parameters.  These\r   are needed on MS-Windows to convert arguments of the function pointers\r   to the proper types during calls.  */\rtypedef int (*key_proc_type) PROTOTYPE ((char *, char *, char *,\r                                        char *, C_Block));\rtypedef int (*decrypt_tkt_type) PROTOTYPE ((char *, char *, char *, char *,\r                                 key_proc_type, KTEXT *));\r#define  KEY_PROC_TYPE_DEFINED\r#define   DECRYPT_TKT_TYPE_DEFINED\r\r\r/******************************************/\r/*** EXPORTED FUNTIONS (by source file) ***/\r/******************************************/\r\r/* change_password.c */\rextern int INTERFACE\rkrb_change_password PROTOTYPE ((char *, char *, char *, char *, char *));\r\r/* decomp_tkt.c */ \rextern int INTERFACE\rdecomp_ticket PROTOTYPE ((KTEXT, unsigned char *, char *, char *, char *, KRB_UINT32 *, C_Block,\r   int *, KRB_UINT32 *, char *, char *, C_Block, Key_schedule));\r\r/* err_txt.c */\rextern const char * INTERFACE\rkrb_get_err_text PROTOTYPE ((int));\r\r/* g_ad_tkt.c */\rextern int INTERFACE\rget_ad_tkt PROTOTYPE ((char *service, char *sinstance, char *realm, int lifetime));\r\r/* g_in_tkt.c */\rextern int INTERFACE\rkrb_get_in_tkt PROTOTYPE ((char *, char *, char *, char *, char *, int,\r                        key_proc_type, decrypt_tkt_type, char *arg));\r\rextern int INTERFACE\rkrb_get_in_tkt_creds PROTOTYPE ((char *, char *, char *, char *, char *, int, \r          key_proc_type, decrypt_tkt_type, char *, CREDENTIALS *));\r\r/* g_phost.c */\rextern char * INTERFACE\rkrb_get_phost PROTOTYPE ((char  *));\r\r/* g_pw_in_tkt.c */\rextern int INTERFACE\rkrb_get_pw_in_tkt PROTOTYPE ((char *, char *, char *,\r                char *, char *, int, char *));\r\rextern int INTERFACE\rkrb_get_pw_in_tkt_creds PROTOTYPE ((char *, char *, char *, \r      char *, char *, int, char *, CREDENTIALS *));\r\r/* g_pw_tkt.c */\rextern int INTERFACE\rget_pw_tkt PROTOTYPE ((char *, char *, char *,\r    char *));\r\r/* g_svc_in_tkt.c */\rextern int INTERFACE\rkrb_get_svc_in_tkt PROTOTYPE ((char *, char *, char *,\r    char *, char *, int, char *));\r\r#if TARGET_OS_MAC\rextern int INTERFACE\rFSp_krb_get_svc_in_tkt PROTOTYPE ((char *, char *, char *, \r     char *, char *, int, const FSSpec *));\r#endif\r\r/* g_tkt_svc.c */\rextern int INTERFACE\rkrb_get_ticket_for_service PROTOTYPE ((char *, char *,\r   KRB_UINT32 *, int, des_cblock, Key_schedule,\r   char *, int));\r \r/* kname_parse.c */\rint k_isname (const char *s);\rint k_isinst (const char *s);\rint k_isrealm (const char *s);\rint kname_parse (char *, char *, char *, const char *);\rint kname_unparse (char *, const char *, const char *, const char *);\r\r/* lifetime.c */\rKRB5_DLLIMP UInt32 KRB5_CALLCONV krb_life_to_time\r      PROTOTYPE((UInt32 start, int life));\rKRB5_DLLIMP int KRB5_CALLCONV krb_time_to_life\r    PROTOTYPE((UInt32 start, UInt32 end));\r\r/* mk_auth.c */\rextern int INTERFACE\rkrb_check_auth PROTOTYPE ((KTEXT, KRB_UINT32, MSG_DAT *,\r          C_Block FAR, Key_schedule, struct sockaddr_in *,\r               struct sockaddr_in *));\r\rextern int INTERFACE\rkrb_mk_auth PROTOTYPE ((long, KTEXT, char *, char *, char *, \r            KRB_UINT32, char *, KTEXT));\r\r/* mk_err.c */\rextern long INTERFACE\rkrb_mk_err PROTOTYPE ((unsigned char *, KRB_INT32, char *));\r\r/* mk_priv.c */\rextern long INTERFACE\rkrb_mk_priv PROTOTYPE ((unsigned char *, unsigned char *, KRB_UINT32, \r  Key_schedule FAR, C_Block, struct sockaddr_in *, struct sockaddr_in *));\r\r/* mk_req.c */\rextern int INTERFACE\rkrb_mk_req PROTOTYPE ((KTEXT, char *, char *, char *, KRB_INT32));\r\rextern int INTERFACE\rkrb_mk_req_creds PROTOTYPE ((register KTEXT, CREDENTIALS *, KRB_INT32));\r\rint\rkrb_set_lifetime(int newval);\r\r/* mk_safe.c */\rextern long INTERFACE\rkrb_mk_safe PROTOTYPE ((unsigned char *, unsigned char *,\r    KRB_UINT32, C_Block, struct sockaddr_in *,\r     struct sockaddr_in *));\r\r/* rd_err.c */\rextern int INTERFACE\rkrb_rd_err PROTOTYPE ((unsigned char *, unsigned long, long *, MSG_DAT *));\r\r/* rd_priv.c */\rextern long INTERFACE\rkrb_rd_priv PROTOTYPE ((unsigned char *, KRB_UINT32,\r   Key_schedule FAR, C_Block, struct sockaddr_in *,\r       struct sockaddr_in *, MSG_DAT *));\r\r/* rd_req.c */\rextern int INTERFACE\rkrb_rd_req PROTOTYPE ((KTEXT, char *, char *,\r  KRB_UINT32, AUTH_DAT *, char *));\r\r/* rd_req_int.c */\rextern int INTERFACE\rkrb_rd_req_int PROTOTYPE ((KTEXT, char *, char *,\r   KRB_UINT32, AUTH_DAT *, C_Block));\r\r/* rd_svc_key.c */\rextern int INTERFACE\rread_service_key PROTOTYPE ((char *, char *, char *, int, char *, char *));\r\r#if TARGET_OS_MAC\rextern int INTERFACE\rFSp_read_service_key PROTOTYPE ((char *, char *, char *, int, const FSSpec*, char *));\r#endif\r\r/* rd_safe.c */\rextern long INTERFACE\rkrb_rd_safe PROTOTYPE ((unsigned char *, KRB_UINT32,\r      C_Block, struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *));\r\r/* recvauth.c */\rextern int INTERFACE\rkrb_recvauth PROTOTYPE ((long, int, KTEXT, char *, char *,\r    struct sockaddr_in *, struct sockaddr_in *,\r    AUTH_DAT *, char *, Key_schedule FAR, char *));\r\r/* sendauth.c */\rextern int INTERFACE \rkrb_sendauth PROTOTYPE ((long, int, KTEXT, char *, char *, char *, \r    KRB_UINT32, MSG_DAT *, CREDENTIALS *, Key_schedule, \r   struct sockaddr_in *, struct sockaddr_in *, char *));\r\r/* CCache-glue.c */\rextern int INTERFACE\rkrb_get_tf_realm PROTOTYPE ((const char *, char *));\r\rextern int INTERFACE\rkrb_get_tf_fullname PROTOTYPE ((char *, char *, char *,\r     char *));\r\rextern int INTERFACE\rkrb_get_cred PROTOTYPE ((char *, char *, char *, CREDENTIALS *));\r\rextern const char * INTERFACE \rtkt_string PROTOTYPE ((void));\r\rextern void INTERFACE\rkrb_set_tkt_string PROTOTYPE ((const char *));\r\rextern int INTERFACE\rdest_tkt PROTOTYPE ((void));\r\r#if TARGET_OS_MAC\r/* The following functions are not part of the standard Kerberos v4 API. \r * They were created for Mac implementation, and used by admin tools \r * such as CNS-Config. */\rextern int INTERFACE \rkrb_get_num_cred PROTOTYPE ((void));\r\rextern int INTERFACE\rkrb_get_nth_cred PROTOTYPE ((char *, char *, char *, int));\r\rextern int INTERFACE\rkrb_delete_cred PROTOTYPE ((char *, char *,char *));\r\rextern int INTERFACE\rdest_all_tkts PROTOTYPE ((void));\r\r#endif /* TARGET_OS_MAC */\r\r/* RealmConfig-glue.c */\rextern int INTERFACE\rkrb_get_profile PROTOTYPE ((profile_t* profile));\r\rextern int INTERFACE\rkrb_get_lrealm PROTOTYPE ((char *, int));\r\rextern int INTERFACE\rkrb_get_admhst PROTOTYPE ((char *, char *, int));\r\rextern int INTERFACE\rkrb_get_krbhst PROTOTYPE ((char *, const char *, int));\r\rextern char * INTERFACE\rkrb_realmofhost PROTOTYPE ((char *));\r\rextern int INTERFACE\rput_svc_key PROTOTYPE ((char *, char *, char *, char *, int, char *));\r\r#if TARGET_API_MAC_CARBON || TARGET_API_MAC_OS8\rextern int INTERFACE\rFSp_put_svc_key PROTOTYPE ((const FSSpec *, char *, char *, char *, int, char *));\r#endif\r\r\r#if TARGET_CPU_68K\r     #pragma fourbyteints reset\r#endif \r\r#if PRAGMA_ENUM_ALWAYSINT\r  #pragma enumsalwaysint reset\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r   #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#if PRAGMA_IMPORT\r#      pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif  /* !rez */\r#endif      /* KRB_H */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/Kerberos5.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/Kerberos5.h
new file mode 100755 (executable)
index 0000000..3ec31a5
--- /dev/null
@@ -0,0 +1 @@
+#include <Kerberos5/krb5.h>\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/krb5.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/krb5.h
new file mode 100755 (executable)
index 0000000..cfc6f20
--- /dev/null
@@ -0,0 +1,2912 @@
+/*
+ * include/krb5.h
+ *
+ * Copyright 1989,1990,1995 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * General definitions for Kerberos version 5.
+ */
+
+/*
+ * Copyright (C) 1998 by the FundsXpress, INC.
+ * 
+ * All rights reserved.
+ * 
+ * Export of this software from the United States of America may require
+ * a specific license from the United States Government.  It is the
+ * responsibility of any person or organization contemplating export to
+ * obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of FundsXpress. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  FundsXpress makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef KRB5_GENERAL__
+#define KRB5_GENERAL__
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+       #include <KerberosSupport/KerberosSupport.h>
+       
+       #if TARGET_API_MAC_OS8 || (TARGET_API_MAC_CARBON && !TARGET_API_MAC_OSX)
+               #include <Kerberos5/win-mac.h>
+       #endif
+#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
+#endif
+
+#ifndef KRB5_CONFIG__
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#define GSS_DLLIMP
+#define KRB5_EXPORTVAR
+#define FAR
+#define NEAR
+#endif /* !KRB5_CALLCONV */
+#endif /* !KRB5_CONFIG__ */
+
+#ifndef THREEPARAMOPEN
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
+#endif
+
+#define KRB5_OLD_CRYPTO
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <stdlib.h>
+
+/*
+ * begin "error_def.h"
+ */
+
+#if TARGET_OS_MAC
+    #include <KerberosProfile/KerberosProfile.h>
+#else
+    #include <profile.h>
+#endif
+
+#include <errno.h>
+
+/*
+ * end "error_def.h"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Macintoh CFM-68K magic incantation */
+#if PRAGMA_IMPORT
+#pragma import on
+#endif
+
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack(2)
+#endif
+
+/*
+ * begin wordsize.h
+ */
+
+/*
+ * Word-size related definition.
+ */
+
+typedef        unsigned char   krb5_octet;
+typedef        unsigned char   krb5_ui_1;
+
+#if (SIZEOF_INT == 2)
+typedef        int     krb5_int16;
+typedef        unsigned int    krb5_ui_2;
+#define VALID_INT_BITS   0x7fff
+#define VALID_UINT_BITS          0xffff
+#elif (SIZEOF_SHORT == 2)
+typedef        short   krb5_int16;
+typedef        unsigned short  krb5_ui_2;
+#else
+  ?==error: undefined 16 bit type
+#endif
+
+#if (SIZEOF_INT == 4)
+typedef        int     krb5_int32;
+typedef        unsigned int    krb5_ui_4;
+#define VALID_INT_BITS   0x7fffffff
+#define VALID_UINT_BITS          0xffffffff
+#elif (SIZEOF_LONG == 4)
+typedef        long    krb5_int32;
+typedef        unsigned long   krb5_ui_4;
+#elif (SIZEOF_SHORT == 4)
+typedef        short   krb5_int32;
+typedef        unsigned short  krb5_ui_4;
+#else
+ ?== error: undefined 32 bit type
+#endif
+
+#define KRB5_INT32_MAX 2147483647
+/* this strange form is necessary since - is a unary operator, not a sign
+   indicator */
+#define KRB5_INT32_MIN (-KRB5_INT32_MAX-1)
+
+#define KRB5_INT16_MAX 65535   
+/* this strange form is necessary since - is a unary operator, not a sign
+   indicator */
+#define KRB5_INT16_MIN (-KRB5_INT16_MAX-1)
+
+/*
+ * end wordsize.h
+ */
+
+/*
+ * begin "base-defs.h"
+ */
+
+/*
+ * Basic definitions for Kerberos V5 library
+ */
+
+#ifndef FALSE
+#define        FALSE   0
+#endif
+#ifndef TRUE
+#define        TRUE    1
+#endif
+
+typedef        unsigned int krb5_boolean;
+typedef        unsigned int krb5_msgtype;      
+typedef        unsigned int krb5_kvno; 
+
+typedef        krb5_int32 krb5_addrtype;
+typedef krb5_int32 krb5_enctype;
+typedef krb5_int32 krb5_cksumtype;
+typedef krb5_int32 krb5_authdatatype;
+typedef krb5_int32 krb5_keyusage;
+
+typedef krb5_int32     krb5_preauthtype; /* This may change, later on */
+typedef        krb5_int32      krb5_flags;
+typedef krb5_int32     krb5_timestamp;
+typedef        krb5_int32      krb5_error_code;
+typedef krb5_int32     krb5_deltat;
+
+typedef krb5_error_code        krb5_magic;
+
+typedef struct _krb5_data {
+       krb5_magic magic;
+       int length;
+       char FAR *data;
+} krb5_data;
+
+/* Define krb5_const as necessary */
+
+/*
+ * Hardcoded scrudge to deal with Ultrix; see note on NPROTOTYPE below
+ */
+
+#if defined(KRB5_NO_CONST) || (defined(__ultrix) && !defined(__GNUC__))
+#define krb5_const
+#else
+#define krb5_const const
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(HAS_VOID_TYPE)
+typedef        void FAR * krb5_pointer;
+typedef void krb5_const FAR * krb5_const_pointer;
+#else
+typedef char FAR * krb5_pointer;
+typedef char krb5_const FAR * krb5_const_pointer;
+#endif
+
+#if (defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32) || defined(KRB5_PROVIDE_PROTOTYPES)) && !defined(KRB5_NO_PROTOTYPES)
+#define KRB5_PROTOTYPE(x) x
+#if defined(__STDC__) || defined(__cplusplus) || defined(HAVE_STDARG_H) || defined(_MSDOS) || defined(_WIN32)
+#define        KRB5_STDARG_P(x) x
+#else
+#define KRB5_STDARG_P(x) ()
+#endif /* defined(__STDC__) || defined(__cplusplus) || defined(HAVE_STDARG_H) */
+#else
+#define KRB5_PROTOTYPE(x) ()
+#define KRB5_STDARG_P(x) ()
+#endif /* STDC or PROTOTYPES */
+
+/*
+ * This gross compiler dependency is in here because the stock Ultrix
+ * compiler defines __STDC__ but doesn't deal with nested prototypes
+ * properly.  The reason this isn't tested for is so that this header
+ * is actually useful when installed.
+ */
+#if defined(KRB5_NO_NESTED_PROTOTYPES) || (defined(__ultrix) && !defined(__GNUC__))
+#define        KRB5_NPROTOTYPE(x) ()
+#else
+#define        KRB5_NPROTOTYPE(x) KRB5_PROTOTYPE(x)
+#endif
+
+typedef struct krb5_principal_data {
+    krb5_magic magic;
+    krb5_data realm;
+    krb5_data FAR *data;               /* An array of strings */
+    krb5_int32 length;
+    krb5_int32 type;
+} krb5_principal_data;
+
+typedef        krb5_principal_data FAR * krb5_principal;
+
+/*
+ * Per V5 spec on definition of principal types
+ */
+
+/* Name type not known */
+#define KRB5_NT_UNKNOWN                0
+/* Just the name of the principal as in DCE, or for users */
+#define KRB5_NT_PRINCIPAL      1
+/* Service and other unique instance (krbtgt) */
+#define KRB5_NT_SRV_INST       2
+/* Service with host name as instance (telnet, rcommands) */
+#define KRB5_NT_SRV_HST                3
+/* Service with host as remaining components */
+#define KRB5_NT_SRV_XHST       4
+/* Unique ID */
+#define KRB5_NT_UID            5
+
+/* constant version thereof: */
+typedef krb5_const krb5_principal_data FAR *krb5_const_principal;
+
+#define krb5_princ_realm(context, princ) (&(princ)->realm)
+#define krb5_princ_set_realm(context, princ,value) ((princ)->realm = *(value))
+#define krb5_princ_set_realm_length(context, princ,value) (princ)->realm.length = (value)
+#define krb5_princ_set_realm_data(context, princ,value) (princ)->realm.data = (value)
+#define        krb5_princ_size(context, princ) (princ)->length
+#define        krb5_princ_type(context, princ) (princ)->type
+#define        krb5_princ_name(context, princ) (princ)->data
+#define        krb5_princ_component(context, princ,i) ((princ)->data + i)
+
+/*
+ * end "base-defs.h"
+ */
+
+/*
+ * begin "hostaddr.h"
+ */
+
+/* structure for address */
+typedef struct _krb5_address {
+    krb5_magic magic;
+    krb5_addrtype addrtype;
+    int length;
+    krb5_octet FAR *contents;
+} krb5_address;
+
+/* per Kerberos v5 protocol spec */
+#define        ADDRTYPE_INET           0x0002
+#define        ADDRTYPE_CHAOS          0x0005
+#define        ADDRTYPE_XNS            0x0006
+#define        ADDRTYPE_ISO            0x0007
+#define ADDRTYPE_DDP           0x0010
+#define ADDRTYPE_INET6         0x0018
+/* not yet in the spec... */
+#define ADDRTYPE_ADDRPORT      0x0100
+#define ADDRTYPE_IPPORT                0x0101
+
+/* macros to determine if a type is a local type */
+#define ADDRTYPE_IS_LOCAL(addrtype) (addrtype & 0x8000)
+
+/*
+ * end "hostaddr.h"
+ */
+
+
+struct _krb5_context;
+typedef struct _krb5_context FAR * krb5_context;
+
+struct _krb5_auth_context;
+typedef struct _krb5_auth_context FAR * krb5_auth_context;
+
+struct _krb5_cryptosystem_entry;
+
+/*
+ * begin "encryption.h"
+ */
+
+typedef struct _krb5_keyblock {
+    krb5_magic magic;
+    krb5_enctype enctype;
+    int length;
+    krb5_octet FAR *contents;
+} krb5_keyblock;
+
+#ifdef KRB5_OLD_CRYPTO
+typedef struct _krb5_encrypt_block {
+    krb5_magic magic;
+    krb5_enctype crypto_entry;         /* to call krb5_encrypt_size, you need
+                                          this.  it was a pointer, but it
+                                          doesn't have to be.  gross. */
+    krb5_keyblock FAR *key;
+} krb5_encrypt_block;
+#endif
+
+typedef struct _krb5_checksum {
+    krb5_magic magic;
+    krb5_cksumtype checksum_type;      /* checksum type */
+    int length;
+    krb5_octet FAR *contents;
+} krb5_checksum;
+
+typedef struct _krb5_enc_data {
+    krb5_magic magic;
+    krb5_enctype enctype;
+    krb5_kvno kvno;
+    krb5_data ciphertext;
+} krb5_enc_data;
+
+/* per Kerberos v5 protocol spec */
+#define        ENCTYPE_NULL            0x0000
+#define        ENCTYPE_DES_CBC_CRC     0x0001  /* DES cbc mode with CRC-32 */
+#define        ENCTYPE_DES_CBC_MD4     0x0002  /* DES cbc mode with RSA-MD4 */
+#define        ENCTYPE_DES_CBC_MD5     0x0003  /* DES cbc mode with RSA-MD5 */
+#define        ENCTYPE_DES_CBC_RAW     0x0004  /* DES cbc mode raw */
+/* XXX deprecated? */
+#define        ENCTYPE_DES3_CBC_SHA    0x0005  /* DES-3 cbc mode with NIST-SHA */
+#define        ENCTYPE_DES3_CBC_RAW    0x0006  /* DES-3 cbc mode raw */
+#define ENCTYPE_DES_HMAC_SHA1  0x0008
+#define ENCTYPE_DES3_CBC_SHA1  0x0010
+#define ENCTYPE_UNKNOWN                0x01ff
+/* local crud */
+/* marc's DES-3 with 32-bit length */
+#define ENCTYPE_LOCAL_DES3_HMAC_SHA1 0x7007
+
+#define        CKSUMTYPE_CRC32         0x0001
+#define        CKSUMTYPE_RSA_MD4       0x0002
+#define        CKSUMTYPE_RSA_MD4_DES   0x0003
+#define        CKSUMTYPE_DESCBC        0x0004
+/* des-mac-k */
+/* rsa-md4-des-k */
+#define        CKSUMTYPE_RSA_MD5       0x0007
+#define        CKSUMTYPE_RSA_MD5_DES   0x0008
+#define CKSUMTYPE_NIST_SHA     0x0009
+#define CKSUMTYPE_HMAC_SHA1_DES3       0x000c
+
+#ifndef krb5_roundup
+/* round x up to nearest multiple of y */
+#define krb5_roundup(x, y) ((((x) + (y) - 1)/(y))*(y))
+#endif /* roundup */
+
+/* macro function definitions to help clean up code */
+
+#if 1
+#define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1))
+#define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0))
+#else
+#define krb5_x(ptr,args) ((*(ptr)) args)
+#define krb5_xc(ptr,args) ((*(ptr)) args)
+#endif
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_encrypt
+    KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key,
+                   krb5_keyusage usage, krb5_const krb5_data *ivec,
+                   krb5_const krb5_data *input, krb5_enc_data *output));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_decrypt
+    KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_keyblock *key,
+                   krb5_keyusage usage, krb5_const krb5_data *ivec,
+                   krb5_const krb5_enc_data *input, krb5_data *output));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_encrypt_length
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype,
+                   size_t inputlen, size_t *length));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_block_size
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype,
+                   size_t *blocksize));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_make_random_key
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype,
+                   krb5_keyblock *random_key));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_random_make_octets
+    KRB5_PROTOTYPE((krb5_context context, krb5_data *data));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_random_seed
+    KRB5_PROTOTYPE((krb5_context context, krb5_data *data));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_string_to_key
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype,
+                   krb5_const krb5_data *string, krb5_const krb5_data *salt,
+                   krb5_keyblock *key));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_enctype_compare
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype e1, krb5_enctype e2,
+                   krb5_boolean *similar));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_make_checksum
+    KRB5_PROTOTYPE((krb5_context context, krb5_cksumtype cksumtype,
+                   krb5_const krb5_keyblock *key, krb5_keyusage usage,
+                   krb5_const krb5_data *input, krb5_checksum *cksum));
+    
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_verify_checksum
+    KRB5_PROTOTYPE((krb5_context context, 
+                   krb5_const krb5_keyblock *key, krb5_keyusage usage,
+                   krb5_const krb5_data *data,
+                   krb5_const krb5_checksum *cksum,
+                   krb5_boolean *valid));
+    
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_checksum_length
+    KRB5_PROTOTYPE((krb5_context context, krb5_cksumtype cksumtype,
+                   size_t *length));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+    krb5_c_keyed_checksum_types
+    KRB5_PROTOTYPE((krb5_context context, krb5_enctype enctype, 
+                   unsigned int *count, krb5_cksumtype **cksumtypes));
+
+#define KRB5_KEYUSAGE_AS_REQ_PA_ENC_TS         1
+#define KRB5_KEYUSAGE_KDC_REP_TICKET           2
+#define KRB5_KEYUSAGE_AS_REP_ENCPART           3
+#define KRB5_KEYUSAGE_TGS_REQ_AD_SESSKEY       4
+#define KRB5_KEYUSAGE_TGS_REQ_AD_SUBKEY                5
+#define KRB5_KEYUSAGE_TGS_REQ_AUTH_CKSUM       6
+#define KRB5_KEYUSAGE_TGS_REQ_AUTH             7
+#define KRB5_KEYUSAGE_TGS_REP_ENCPART_SESSKEY  8
+#define KRB5_KEYUSAGE_TGS_REP_ENCPART_SUBKEY   9
+#define KRB5_KEYUSAGE_AP_REQ_AUTH_CKSUM                10
+#define KRB5_KEYUSAGE_AP_REQ_AUTH              11
+#define KRB5_KEYUSAGE_AP_REP_ENCPART           12
+#define KRB5_KEYUSAGE_KRB_PRIV_ENCPART         13
+#define KRB5_KEYUSAGE_KRB_CRED_ENCPART         14
+#define KRB5_KEYUSAGE_KRB_SAFE_CKSUM           15
+#define KRB5_KEYUSAGE_APP_DATA_ENCRYPT         16
+#define KRB5_KEYUSAGE_APP_DATA_CKSUM           17
+#define KRB5_KEYUSAGE_KRB_ERROR_CKSUM          18
+#define KRB5_KEYUSAGE_AD_KDCISSUED_CKSUM       19
+#define KRB5_KEYUSAGE_AD_MTE                   20
+#define KRB5_KEYUSAGE_AD_ITE                   21
+
+/* XXX need to register these */
+
+#define KRB5_KEYUSAGE_GSS_TOK_MIC              22
+#define KRB5_KEYUSAGE_GSS_TOK_WRAP_INTEG       23
+#define KRB5_KEYUSAGE_GSS_TOK_WRAP_PRIV                24
+
+
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV valid_enctype
+       KRB5_PROTOTYPE((krb5_const krb5_enctype ktype));
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV valid_cksumtype
+       KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype));
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV is_coll_proof_cksum
+       KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype));
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV is_keyed_cksum
+       KRB5_PROTOTYPE((krb5_const krb5_cksumtype ctype));
+
+#ifdef KRB5_OLD_CRYPTO
+/*
+ * old cryptosystem routine prototypes.  These are now layered
+ * on top of the functions above.
+ */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_encrypt
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_pointer inptr,
+               krb5_pointer outptr,
+               krb5_const size_t size,
+               krb5_encrypt_block FAR * eblock,
+               krb5_pointer ivec));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_decrypt
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_pointer inptr,
+               krb5_pointer outptr,
+               krb5_const size_t size,
+               krb5_encrypt_block FAR * eblock,
+               krb5_pointer ivec));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_process_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_encrypt_block FAR * eblock,
+               krb5_const krb5_keyblock FAR * key));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_finish_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_encrypt_block FAR * eblock));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_encrypt_block FAR * eblock,
+               krb5_keyblock FAR * keyblock,
+               krb5_const krb5_data FAR * data,
+               krb5_const krb5_data FAR * salt));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_init_random_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_encrypt_block FAR * eblock,
+               krb5_const krb5_keyblock FAR * keyblock,
+               krb5_pointer FAR * ptr));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_finish_random_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_encrypt_block FAR * eblock,
+               krb5_pointer FAR * ptr));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_random_key
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_encrypt_block FAR * eblock,
+               krb5_pointer ptr,
+               krb5_keyblock FAR * FAR * keyblock));
+KRB5_DLLIMP krb5_enctype KRB5_CALLCONV krb5_eblock_enctype
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_encrypt_block FAR * eblock));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_use_enctype
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_encrypt_block FAR * eblock,
+               krb5_const krb5_enctype enctype));
+KRB5_DLLIMP size_t KRB5_CALLCONV krb5_encrypt_size
+       KRB5_PROTOTYPE((krb5_const size_t length,
+               krb5_enctype crypto));
+KRB5_DLLIMP size_t KRB5_CALLCONV krb5_checksum_size
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_cksumtype ctype));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_calculate_checksum
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_cksumtype ctype,
+               krb5_const krb5_pointer in, krb5_const size_t in_length,
+               krb5_const krb5_pointer seed, krb5_const size_t seed_length,
+               krb5_checksum FAR * outcksum));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_verify_checksum
+       KRB5_PROTOTYPE((krb5_context context,
+               krb5_const krb5_cksumtype ctype,
+               krb5_const krb5_checksum FAR * cksum,
+               krb5_const krb5_pointer in, krb5_const size_t in_length,
+               krb5_const krb5_pointer seed, krb5_const size_t seed_length));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_random_confounder
+       KRB5_PROTOTYPE((size_t, krb5_pointer));
+
+krb5_error_code krb5_encrypt_data
+       KRB5_PROTOTYPE((krb5_context context, krb5_keyblock *key, 
+               krb5_pointer ivec, krb5_data *data, 
+               krb5_enc_data *enc_data));
+
+krb5_error_code krb5_decrypt_data
+       KRB5_PROTOTYPE((krb5_context context, krb5_keyblock *key, 
+               krb5_pointer ivec, krb5_enc_data *data, 
+               krb5_data *enc_data));
+
+#endif /* KRB5_OLD_CRYPTO */
+
+/*
+ * end "encryption.h"
+ */
+
+/*
+ * begin "fieldbits.h"
+ */
+
+/* kdc_options for kdc_request */
+/* options is 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+/* #define     KDC_OPT_RESERVED        0x80000000 */
+#define        KDC_OPT_FORWARDABLE             0x40000000
+#define        KDC_OPT_FORWARDED               0x20000000
+#define        KDC_OPT_PROXIABLE               0x10000000
+#define        KDC_OPT_PROXY                   0x08000000
+#define        KDC_OPT_ALLOW_POSTDATE          0x04000000
+#define        KDC_OPT_POSTDATED               0x02000000
+/* #define     KDC_OPT_UNUSED          0x01000000 */
+#define        KDC_OPT_RENEWABLE               0x00800000
+/* #define     KDC_OPT_UNUSED          0x00400000 */
+/* #define     KDC_OPT_RESERVED        0x00200000 */
+/* #define     KDC_OPT_RESERVED        0x00100000 */
+/* #define     KDC_OPT_RESERVED        0x00080000 */
+/* #define     KDC_OPT_RESERVED        0x00040000 */
+/* #define     KDC_OPT_RESERVED        0x00020000 */
+/* #define     KDC_OPT_RESERVED        0x00010000 */
+/* #define     KDC_OPT_RESERVED        0x00008000 */
+/* #define     KDC_OPT_RESERVED        0x00004000 */
+/* #define     KDC_OPT_RESERVED        0x00002000 */
+/* #define     KDC_OPT_RESERVED        0x00001000 */
+/* #define     KDC_OPT_RESERVED        0x00000800 */
+/* #define     KDC_OPT_RESERVED        0x00000400 */
+/* #define     KDC_OPT_RESERVED        0x00000200 */
+/* #define     KDC_OPT_RESERVED        0x00000100 */
+/* #define     KDC_OPT_RESERVED        0x00000080 */
+/* #define     KDC_OPT_RESERVED        0x00000040 */
+/* #define     KDC_OPT_RESERVED        0x00000020 */
+#define        KDC_OPT_RENEWABLE_OK            0x00000010
+#define        KDC_OPT_ENC_TKT_IN_SKEY         0x00000008
+/* #define     KDC_OPT_UNUSED          0x00000004 */
+#define        KDC_OPT_RENEW                   0x00000002
+#define        KDC_OPT_VALIDATE                0x00000001
+
+/*
+ * Mask of ticket flags in the TGT which should be converted into KDC
+ * options when using the TGT to get derivitive tickets.
+ * 
+ *  New mask = KDC_OPT_FORWARDABLE | KDC_OPT_PROXIABLE |
+ *            KDC_OPT_ALLOW_POSTDATE | KDC_OPT_RENEWABLE
+ */
+#define KDC_TKT_COMMON_MASK            0x54800000
+
+/* definitions for ap_options fields */
+/* ap_options are 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+#define        AP_OPTS_RESERVED                0x80000000
+#define        AP_OPTS_USE_SESSION_KEY         0x40000000
+#define        AP_OPTS_MUTUAL_REQUIRED         0x20000000
+/* #define     AP_OPTS_RESERVED        0x10000000 */
+/* #define     AP_OPTS_RESERVED        0x08000000 */
+/* #define     AP_OPTS_RESERVED        0x04000000 */
+/* #define     AP_OPTS_RESERVED        0x02000000 */
+/* #define     AP_OPTS_RESERVED        0x01000000 */
+/* #define     AP_OPTS_RESERVED        0x00800000 */
+/* #define     AP_OPTS_RESERVED        0x00400000 */
+/* #define     AP_OPTS_RESERVED        0x00200000 */
+/* #define     AP_OPTS_RESERVED        0x00100000 */
+/* #define     AP_OPTS_RESERVED        0x00080000 */
+/* #define     AP_OPTS_RESERVED        0x00040000 */
+/* #define     AP_OPTS_RESERVED        0x00020000 */
+/* #define     AP_OPTS_RESERVED        0x00010000 */
+/* #define     AP_OPTS_RESERVED        0x00008000 */
+/* #define     AP_OPTS_RESERVED        0x00004000 */
+/* #define     AP_OPTS_RESERVED        0x00002000 */
+/* #define     AP_OPTS_RESERVED        0x00001000 */
+/* #define     AP_OPTS_RESERVED        0x00000800 */
+/* #define     AP_OPTS_RESERVED        0x00000400 */
+/* #define     AP_OPTS_RESERVED        0x00000200 */
+/* #define     AP_OPTS_RESERVED        0x00000100 */
+/* #define     AP_OPTS_RESERVED        0x00000080 */
+/* #define     AP_OPTS_RESERVED        0x00000040 */
+/* #define     AP_OPTS_RESERVED        0x00000020 */
+/* #define     AP_OPTS_RESERVED        0x00000010 */
+/* #define     AP_OPTS_RESERVED        0x00000008 */
+/* #define     AP_OPTS_RESERVED        0x00000004 */
+/* #define     AP_OPTS_RESERVED        0x00000002 */
+#define AP_OPTS_USE_SUBKEY     0x00000001
+
+#define AP_OPTS_WIRE_MASK      0xfffffff0
+
+/* definitions for ad_type fields. */
+#define        AD_TYPE_RESERVED        0x8000
+#define        AD_TYPE_EXTERNAL        0x4000
+#define        AD_TYPE_REGISTERED      0x2000
+
+#define AD_TYPE_FIELD_TYPE_MASK        0x1fff
+
+/* Ticket flags */
+/* flags are 32 bits; each host is responsible to put the 4 bytes
+   representing these bits into net order before transmission */
+/* #define     TKT_FLG_RESERVED        0x80000000 */
+#define        TKT_FLG_FORWARDABLE             0x40000000
+#define        TKT_FLG_FORWARDED               0x20000000
+#define        TKT_FLG_PROXIABLE               0x10000000
+#define        TKT_FLG_PROXY                   0x08000000
+#define        TKT_FLG_MAY_POSTDATE            0x04000000
+#define        TKT_FLG_POSTDATED               0x02000000
+#define        TKT_FLG_INVALID                 0x01000000
+#define        TKT_FLG_RENEWABLE               0x00800000
+#define        TKT_FLG_INITIAL                 0x00400000
+#define        TKT_FLG_PRE_AUTH                0x00200000
+#define        TKT_FLG_HW_AUTH                 0x00100000
+/* #define     TKT_FLG_RESERVED        0x00080000 */
+/* #define     TKT_FLG_RESERVED        0x00040000 */
+/* #define     TKT_FLG_RESERVED        0x00020000 */
+/* #define     TKT_FLG_RESERVED        0x00010000 */
+/* #define     TKT_FLG_RESERVED        0x00008000 */
+/* #define     TKT_FLG_RESERVED        0x00004000 */
+/* #define     TKT_FLG_RESERVED        0x00002000 */
+/* #define     TKT_FLG_RESERVED        0x00001000 */
+/* #define     TKT_FLG_RESERVED        0x00000800 */
+/* #define     TKT_FLG_RESERVED        0x00000400 */
+/* #define     TKT_FLG_RESERVED        0x00000200 */
+/* #define     TKT_FLG_RESERVED        0x00000100 */
+/* #define     TKT_FLG_RESERVED        0x00000080 */
+/* #define     TKT_FLG_RESERVED        0x00000040 */
+/* #define     TKT_FLG_RESERVED        0x00000020 */
+/* #define     TKT_FLG_RESERVED        0x00000010 */
+/* #define     TKT_FLG_RESERVED        0x00000008 */
+/* #define     TKT_FLG_RESERVED        0x00000004 */
+/* #define     TKT_FLG_RESERVED        0x00000002 */
+/* #define     TKT_FLG_RESERVED        0x00000001 */
+
+/* definitions for lr_type fields. */
+#define        LR_TYPE_THIS_SERVER_ONLY        0x8000
+
+#define LR_TYPE_INTERPRETATION_MASK    0x7fff
+
+/* definitions for ad_type fields. */
+#define        AD_TYPE_EXTERNAL        0x4000
+#define        AD_TYPE_REGISTERED      0x2000
+
+#define AD_TYPE_FIELD_TYPE_MASK        0x1fff
+#define AD_TYPE_INTERNAL_MASK  0x3fff
+
+/* definitions for msec direction bit for KRB_SAFE, KRB_PRIV */
+#define        MSEC_DIRBIT             0x8000
+#define        MSEC_VAL_MASK           0x7fff
+
+/*
+ * end "fieldbits.h"
+ */
+
+/*
+ * begin "proto.h"
+ */
+
+/* Protocol version number */
+#define        KRB5_PVNO       5
+
+/* Message types */
+
+#define        KRB5_AS_REQ     ((krb5_msgtype)10) /* Req for initial authentication */
+#define        KRB5_AS_REP     ((krb5_msgtype)11) /* Response to KRB_AS_REQ request */
+#define        KRB5_TGS_REQ    ((krb5_msgtype)12) /* TGS request to server */
+#define        KRB5_TGS_REP    ((krb5_msgtype)13) /* Response to KRB_TGS_REQ req */
+#define        KRB5_AP_REQ     ((krb5_msgtype)14) /* application request to server */
+#define        KRB5_AP_REP     ((krb5_msgtype)15) /* Response to KRB_AP_REQ_MUTUAL */
+#define        KRB5_SAFE       ((krb5_msgtype)20) /* Safe application message */
+#define        KRB5_PRIV       ((krb5_msgtype)21) /* Private application message */
+#define        KRB5_CRED       ((krb5_msgtype)22) /* Credential forwarding message */
+#define        KRB5_ERROR      ((krb5_msgtype)30) /* Error response */
+
+/* LastReq types */
+#define KRB5_LRQ_NONE                  0
+#define KRB5_LRQ_ALL_LAST_TGT          1
+#define KRB5_LRQ_ONE_LAST_TGT          (-1)
+#define KRB5_LRQ_ALL_LAST_INITIAL      2
+#define KRB5_LRQ_ONE_LAST_INITIAL      (-2)
+#define KRB5_LRQ_ALL_LAST_TGT_ISSUED   3
+#define KRB5_LRQ_ONE_LAST_TGT_ISSUED   (-3)
+#define KRB5_LRQ_ALL_LAST_RENEWAL      4
+#define KRB5_LRQ_ONE_LAST_RENEWAL      (-4)
+#define KRB5_LRQ_ALL_LAST_REQ          5
+#define KRB5_LRQ_ONE_LAST_REQ          (-5)
+
+/* PADATA types */
+#define KRB5_PADATA_NONE               0
+#define        KRB5_PADATA_AP_REQ              1
+#define        KRB5_PADATA_TGS_REQ             KRB5_PADATA_AP_REQ
+#define KRB5_PADATA_ENC_TIMESTAMP      2
+#define        KRB5_PADATA_PW_SALT             3
+#if 0                          /* Not used */
+#define KRB5_PADATA_ENC_ENCKEY         4  /* Key encrypted within itself */
+#endif
+#define KRB5_PADATA_ENC_UNIX_TIME      5  /* timestamp encrypted in key */
+#define KRB5_PADATA_ENC_SANDIA_SECURID 6  /* SecurId passcode */
+#define KRB5_PADATA_SESAME             7  /* Sesame project */
+#define KRB5_PADATA_OSF_DCE            8  /* OSF DCE */
+#define KRB5_CYBERSAFE_SECUREID                9  /* Cybersafe */
+#define        KRB5_PADATA_AFS3_SALT           10 /* Cygnus */
+#define KRB5_PADATA_ETYPE_INFO         11 /* Etype info for preauth */
+#define KRB5_PADATA_SAM_CHALLENGE      12 /* draft challenge system */
+#define KRB5_PADATA_SAM_RESPONSE       13 /* draft challenge system response */
+    
+#define        KRB5_SAM_USE_SAD_AS_KEY         0x80000000
+#define        KRB5_SAM_SEND_ENCRYPTED_SAD     0x40000000
+#define        KRB5_SAM_MUST_PK_ENCRYPT_SAD    0x20000000 /* currently must be zero */
+
+/* Reserved for SPX pre-authentication. */
+#define KRB5_PADATA_DASS               16
+
+/* Transited encoding types */
+#define        KRB5_DOMAIN_X500_COMPRESS       1
+
+/* alternate authentication types */
+#define        KRB5_ALTAUTH_ATT_CHALLENGE_RESPONSE     64
+
+/* authorization data types */
+#define        KRB5_AUTHDATA_OSF_DCE   64
+#define KRB5_AUTHDATA_SESAME   65
+
+/* password change constants */
+
+#define KRB5_KPASSWD_SUCCESS           0
+#define KRB5_KPASSWD_MALFORMED         1
+#define KRB5_KPASSWD_HARDERROR         2
+#define KRB5_KPASSWD_AUTHERROR         3
+#define KRB5_KPASSWD_SOFTERROR         4
+
+/*
+ * end "proto.h"
+ */
+
+/* Time set */
+typedef struct _krb5_ticket_times {
+    krb5_timestamp authtime; /* XXX ? should ktime in KDC_REP == authtime
+                               in ticket? otherwise client can't get this */ 
+    krb5_timestamp starttime;          /* optional in ticket, if not present,
+                                          use authtime */
+    krb5_timestamp endtime;
+    krb5_timestamp renew_till;
+} krb5_ticket_times;
+
+/* structure for auth data */
+typedef struct _krb5_authdata {
+    krb5_magic magic;
+    krb5_authdatatype ad_type;
+    int length;
+    krb5_octet FAR *contents;
+} krb5_authdata;
+
+/* structure for transited encoding */
+typedef struct _krb5_transited {
+    krb5_magic magic;
+    krb5_octet tr_type;
+    krb5_data tr_contents;
+} krb5_transited;
+
+typedef struct _krb5_enc_tkt_part {
+    krb5_magic magic;
+    /* to-be-encrypted portion */
+    krb5_flags flags;                  /* flags */
+    krb5_keyblock FAR *session;                /* session key: includes enctype */
+    krb5_principal client;             /* client name/realm */
+    krb5_transited transited;          /* list of transited realms */
+    krb5_ticket_times times;           /* auth, start, end, renew_till */
+    krb5_address FAR * FAR *caddrs;    /* array of ptrs to addresses */
+    krb5_authdata FAR * FAR *authorization_data; /* auth data */
+} krb5_enc_tkt_part;
+
+typedef struct _krb5_ticket {
+    krb5_magic magic;
+    /* cleartext portion */
+    krb5_principal server;             /* server name/realm */
+    krb5_enc_data enc_part;            /* encryption type, kvno, encrypted
+                                          encoding */
+    krb5_enc_tkt_part FAR *enc_part2;  /* ptr to decrypted version, if
+                                          available */
+} krb5_ticket;
+
+/* the unencrypted version */
+typedef struct _krb5_authenticator {
+    krb5_magic magic;
+    krb5_principal client;             /* client name/realm */
+    krb5_checksum FAR *checksum;       /* checksum, includes type, optional */
+    krb5_int32 cusec;                  /* client usec portion */
+    krb5_timestamp ctime;              /* client sec portion */
+    krb5_keyblock FAR *subkey;         /* true session key, optional */
+    krb5_int32 seq_number;             /* sequence #, optional */
+    krb5_authdata FAR * FAR *authorization_data; /* New add by Ari, auth data */
+} krb5_authenticator;
+
+typedef struct _krb5_tkt_authent {
+    krb5_magic magic;
+    krb5_ticket FAR *ticket;
+    krb5_authenticator FAR *authenticator;
+    krb5_flags ap_options;
+} krb5_tkt_authent;
+
+/* credentials:         Ticket, session key, etc. */
+typedef struct _krb5_creds {
+    krb5_magic magic;
+    krb5_principal client;             /* client's principal identifier */
+    krb5_principal server;             /* server's principal identifier */
+    krb5_keyblock keyblock;            /* session encryption key info */
+    krb5_ticket_times times;           /* lifetime info */
+    krb5_boolean is_skey;              /* true if ticket is encrypted in
+                                          another ticket's skey */
+    krb5_flags ticket_flags;           /* flags in ticket */
+    krb5_address FAR * FAR *addresses; /* addrs in ticket */
+    krb5_data ticket;                  /* ticket string itself */
+    krb5_data second_ticket;           /* second ticket, if related to
+                                          ticket (via DUPLICATE-SKEY or
+                                          ENC-TKT-IN-SKEY) */
+    krb5_authdata FAR * FAR *authdata; /* authorization data */
+} krb5_creds;
+
+/* Last request fields */
+typedef struct _krb5_last_req_entry {
+    krb5_magic magic;
+    krb5_octet lr_type;
+    krb5_timestamp value;
+} krb5_last_req_entry;
+
+/* pre-authentication data */
+typedef struct _krb5_pa_data {
+    krb5_magic magic;
+    krb5_preauthtype  pa_type;
+    int length;
+    krb5_octet FAR *contents;
+} krb5_pa_data;
+
+typedef struct _krb5_kdc_req {
+    krb5_magic magic;
+    krb5_msgtype msg_type;             /* AS_REQ or TGS_REQ? */
+    krb5_pa_data FAR * FAR *padata;    /* e.g. encoded AP_REQ */
+    /* real body */
+    krb5_flags kdc_options;            /* requested options */
+    krb5_principal client;             /* includes realm; optional */
+    krb5_principal server;             /* includes realm (only used if no
+                                          client) */
+    krb5_timestamp from;               /* requested starttime */
+    krb5_timestamp till;               /* requested endtime */
+    krb5_timestamp rtime;              /* (optional) requested renew_till */
+    krb5_int32 nonce;                  /* nonce to match request/response */
+    int nktypes;                       /* # of ktypes, must be positive */
+    krb5_enctype FAR *ktype;           /* requested enctype(s) */
+    krb5_address FAR * FAR *addresses; /* requested addresses, optional */
+    krb5_enc_data authorization_data;  /* encrypted auth data; OPTIONAL */
+    krb5_authdata FAR * FAR *unenc_authdata; /* unencrypted auth data,
+                                          if available */
+    krb5_ticket FAR * FAR *second_ticket;/* second ticket array; OPTIONAL */
+} krb5_kdc_req;
+
+typedef struct _krb5_enc_kdc_rep_part {
+    krb5_magic magic;
+    /* encrypted part: */
+    krb5_msgtype msg_type;             /* krb5 message type */
+    krb5_keyblock FAR *session;                /* session key */
+    krb5_last_req_entry FAR * FAR *last_req; /* array of ptrs to entries */
+    krb5_int32 nonce;                  /* nonce from request */
+    krb5_timestamp key_exp;            /* expiration date */
+    krb5_flags flags;                  /* ticket flags */
+    krb5_ticket_times times;           /* lifetime info */
+    krb5_principal server;             /* server's principal identifier */
+    krb5_address FAR * FAR *caddrs;    /* array of ptrs to addresses,
+                                          optional */
+} krb5_enc_kdc_rep_part;
+
+typedef struct _krb5_kdc_rep {
+    krb5_magic magic;
+    /* cleartext part: */
+    krb5_msgtype msg_type;             /* AS_REP or KDC_REP? */
+    krb5_pa_data FAR * FAR *padata;    /* preauthentication data from KDC */
+    krb5_principal client;             /* client's principal identifier */
+    krb5_ticket FAR *ticket;           /* ticket */
+    krb5_enc_data enc_part;            /* encryption type, kvno, encrypted
+                                          encoding */
+    krb5_enc_kdc_rep_part FAR *enc_part2;/* unencrypted version, if available */
+} krb5_kdc_rep;
+
+/* error message structure */
+typedef struct _krb5_error {
+    krb5_magic magic;
+    /* some of these may be meaningless in certain contexts */
+    krb5_timestamp ctime;              /* client sec portion; optional */
+    krb5_int32 cusec;                  /* client usec portion; optional */
+    krb5_int32 susec;                  /* server usec portion */
+    krb5_timestamp stime;              /* server sec portion */
+    krb5_ui_4 error;                   /* error code (protocol error #'s) */
+    krb5_principal client;             /* client's principal identifier;
+                                          optional */
+    krb5_principal server;             /* server's principal identifier */
+    krb5_data text;                    /* descriptive text */
+    krb5_data e_data;                  /* additional error-describing data */
+} krb5_error;
+
+typedef struct _krb5_ap_req {
+    krb5_magic magic;
+    krb5_flags ap_options;             /* requested options */
+    krb5_ticket FAR *ticket;           /* ticket */
+    krb5_enc_data authenticator;       /* authenticator (already encrypted) */
+} krb5_ap_req;
+
+typedef struct _krb5_ap_rep {
+    krb5_magic magic;
+    krb5_enc_data enc_part;
+} krb5_ap_rep;
+
+typedef struct _krb5_ap_rep_enc_part {
+    krb5_magic magic;
+    krb5_timestamp ctime;              /* client time, seconds portion */
+    krb5_int32 cusec;                  /* client time, microseconds portion */
+    krb5_keyblock FAR *subkey;         /* true session key, optional */
+    krb5_int32 seq_number;             /* sequence #, optional */
+} krb5_ap_rep_enc_part;
+
+typedef struct _krb5_response {
+    krb5_magic magic;
+    krb5_octet message_type;
+    krb5_data response;
+    krb5_int32 expected_nonce; /* The expected nonce for KDC_REP messages */
+    krb5_timestamp request_time;   /* When we made the request */
+} krb5_response;
+
+typedef struct _krb5_safe {
+    krb5_magic magic;
+    krb5_data user_data;               /* user data */
+    krb5_timestamp timestamp;          /* client time, optional */
+    krb5_int32 usec;                   /* microsecond portion of time,
+                                          optional */
+    krb5_int32 seq_number;             /* sequence #, optional */
+    krb5_address FAR *s_address;       /* sender address */
+    krb5_address FAR *r_address;       /* recipient address, optional */
+    krb5_checksum FAR *checksum;       /* data integrity checksum */
+} krb5_safe;
+
+typedef struct _krb5_priv {
+    krb5_magic magic;
+    krb5_enc_data enc_part;            /* encrypted part */
+} krb5_priv;
+
+typedef struct _krb5_priv_enc_part {
+    krb5_magic magic;
+    krb5_data user_data;               /* user data */
+    krb5_timestamp timestamp;          /* client time, optional */
+    krb5_int32 usec;                   /* microsecond portion of time, opt. */
+    krb5_int32 seq_number;             /* sequence #, optional */
+    krb5_address FAR *s_address;       /* sender address */
+    krb5_address FAR *r_address;       /* recipient address, optional */
+} krb5_priv_enc_part;
+
+typedef struct _krb5_cred_info {
+    krb5_magic magic;
+    krb5_keyblock FAR *session;                /* session key used to encrypt */
+                                       /* ticket */
+    krb5_principal client;             /* client name/realm, optional */
+    krb5_principal server;             /* server name/realm, optional */
+    krb5_flags flags;                  /* ticket flags, optional */
+    krb5_ticket_times times;           /* auth, start, end, renew_till, */
+                                       /* optional */
+    krb5_address FAR * FAR *caddrs;    /* array of ptrs to addresses */
+} krb5_cred_info;
+
+typedef struct _krb5_cred_enc_part {
+    krb5_magic magic;
+    krb5_int32 nonce;                  /* nonce, optional */
+    krb5_timestamp timestamp;          /* client time */
+    krb5_int32 usec;                   /* microsecond portion of time */
+    krb5_address FAR *s_address;       /* sender address, optional */
+    krb5_address FAR *r_address;       /* recipient address, optional */
+    krb5_cred_info FAR * FAR *ticket_info;
+} krb5_cred_enc_part;   
+
+typedef struct _krb5_cred {
+    krb5_magic magic;
+    krb5_ticket FAR * FAR *tickets;    /* tickets */
+    krb5_enc_data enc_part;            /* encrypted part */
+    krb5_cred_enc_part FAR *enc_part2; /* unencrypted version, if available*/
+} krb5_cred;
+
+/* Sandia password generation structures */
+typedef struct _passwd_phrase_element {
+    krb5_magic magic;
+    krb5_data FAR *passwd;
+    krb5_data FAR *phrase;
+} passwd_phrase_element;
+
+typedef struct _krb5_pwd_data {
+    krb5_magic magic;
+    int sequence_count;
+    passwd_phrase_element FAR * FAR *element;
+} krb5_pwd_data;
+
+/* these need to be here so the typedefs are available for the prototypes */
+
+/*
+ * begin "safepriv.h"
+ */
+
+#define KRB5_AUTH_CONTEXT_DO_TIME      0x00000001
+#define KRB5_AUTH_CONTEXT_RET_TIME     0x00000002
+#define KRB5_AUTH_CONTEXT_DO_SEQUENCE  0x00000004
+#define KRB5_AUTH_CONTEXT_RET_SEQUENCE 0x00000008
+#define KRB5_AUTH_CONTEXT_PERMIT_ALL   0x00000010
+typedef struct krb5_replay_data { 
+    krb5_timestamp     timestamp; 
+    krb5_int32         usec;
+    krb5_int32         seq; 
+} krb5_replay_data;
+
+/* flags for krb5_auth_con_genaddrs() */
+#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR          0x00000001
+#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR         0x00000002
+#define KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR     0x00000004
+#define KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR    0x00000008
+
+/*
+ * end "safepriv.h"
+ */
+
+
+/*
+ * begin "ccache.h"
+ */
+
+typedef        krb5_pointer    krb5_cc_cursor; /* cursor for sequential lookup */
+
+struct _krb5_ccache;
+typedef struct _krb5_ccache FAR *krb5_ccache;
+struct _krb5_cc_ops;
+typedef struct _krb5_cc_ops krb5_cc_ops;
+
+/* for retrieve_cred */
+#define        KRB5_TC_MATCH_TIMES             0x00000001
+#define        KRB5_TC_MATCH_IS_SKEY           0x00000002
+#define        KRB5_TC_MATCH_FLAGS             0x00000004
+#define        KRB5_TC_MATCH_TIMES_EXACT       0x00000008
+#define        KRB5_TC_MATCH_FLAGS_EXACT       0x00000010
+#define        KRB5_TC_MATCH_AUTHDATA          0x00000020
+#define        KRB5_TC_MATCH_SRV_NAMEONLY      0x00000040
+#define        KRB5_TC_MATCH_2ND_TKT           0x00000080
+#define        KRB5_TC_MATCH_KTYPE             0x00000100
+#define KRB5_TC_SUPPORTED_KTYPES       0x00000200
+
+/* for set_flags and other functions */
+#define KRB5_TC_OPENCLOSE              0x00000001
+
+KRB5_DLLIMP const char FAR * KRB5_CALLCONV
+krb5_cc_get_name (krb5_context context, krb5_ccache cache);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_gen_new (krb5_context context, krb5_ccache FAR *cache);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_initialize(krb5_context context, krb5_ccache cache,
+                  krb5_principal principal);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_destroy (krb5_context context, krb5_ccache cache);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_close (krb5_context context, krb5_ccache cache);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_store_cred (krb5_context context, krb5_ccache cache,
+                   krb5_creds FAR *creds);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_retrieve_cred (krb5_context context, krb5_ccache cache,
+                      krb5_flags flags, krb5_creds FAR *mcreds,
+                      krb5_creds FAR *creds);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_get_principal (krb5_context context, krb5_ccache cache,
+                      krb5_principal FAR *principal);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_start_seq_get (krb5_context context, krb5_ccache cache,
+                      krb5_cc_cursor FAR *cursor);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_next_cred (krb5_context context, krb5_ccache cache,
+                  krb5_cc_cursor FAR *cursor, krb5_creds FAR *creds);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_end_seq_get (krb5_context context, krb5_ccache cache,
+                    krb5_cc_cursor FAR *cursor);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_remove_cred (krb5_context context, krb5_ccache cache, krb5_flags flags,
+                    krb5_creds FAR *creds);
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_cc_set_flags (krb5_context context, krb5_ccache cache, krb5_flags flags);
+
+KRB5_DLLIMP const char FAR *
+krb5_cc_get_type (krb5_context context, krb5_ccache cache);
+
+/*
+ * end "ccache.h"
+ */
+
+/*
+ * begin "rcache.h"
+ */
+
+typedef struct krb5_rc_st {
+    krb5_magic magic;
+    struct _krb5_rc_ops FAR *ops;
+    krb5_pointer data;
+} FAR *krb5_rcache;
+
+typedef struct _krb5_donot_replay {
+    krb5_magic magic;
+    char FAR *server;                  /* null-terminated */
+    char FAR *client;                  /* null-terminated */
+    krb5_int32 cusec;
+    krb5_timestamp ctime;
+} krb5_donot_replay;
+
+typedef struct _krb5_rc_ops {
+    krb5_magic magic;
+    char FAR *type;
+    krb5_error_code (KRB5_CALLCONV *init)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache,krb5_deltat)); /* create */
+    krb5_error_code (KRB5_CALLCONV *recover)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache)); /* open */
+    krb5_error_code (KRB5_CALLCONV *destroy)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache));
+    krb5_error_code (KRB5_CALLCONV *close)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache));
+    krb5_error_code (KRB5_CALLCONV *store)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache,krb5_donot_replay FAR *));
+    krb5_error_code (KRB5_CALLCONV *expunge)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache));
+    krb5_error_code (KRB5_CALLCONV *get_span)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache,krb5_deltat FAR *));
+    char FAR *(KRB5_CALLCONV *get_name)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache));
+    krb5_error_code (KRB5_CALLCONV *resolve)
+       KRB5_NPROTOTYPE((krb5_context, krb5_rcache, char FAR *));
+} krb5_rc_ops;
+
+krb5_error_code krb5_rc_default 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_rcache FAR *));
+krb5_error_code krb5_rc_register_type 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_rc_ops FAR *));
+krb5_error_code krb5_rc_resolve_type 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_rcache FAR *,char FAR *));
+krb5_error_code krb5_rc_resolve_full 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_rcache FAR *,char FAR *));
+char FAR * krb5_rc_get_type 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_rcache));
+char FAR * krb5_rc_default_type 
+       KRB5_PROTOTYPE((krb5_context));
+char FAR * krb5_rc_default_name 
+       KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_auth_to_rep 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_tkt_authent FAR *,
+               krb5_donot_replay FAR *));
+
+
+#define krb5_rc_initialize(context, id, span) krb5_x((id)->ops->init,(context, id, span))
+#define krb5_rc_recover(context, id) krb5_x((id)->ops->recover,(context, id))
+#define krb5_rc_destroy(context, id) krb5_x((id)->ops->destroy,(context, id))
+#define krb5_rc_close(context, id) krb5_x((id)->ops->close,(context, id))
+#define krb5_rc_store(context, id, dontreplay) krb5_x((id)->ops->store,(context, id, dontreplay))
+#define krb5_rc_expunge(context, id) krb5_x((id)->ops->expunge,(context, id))
+#define krb5_rc_get_lifespan(context, id, spanp) krb5_x((id)->ops->get_span,(context, id, spanp))
+#define krb5_rc_get_name(context, id) krb5_xc((id)->ops->get_name,(context, id))
+#define krb5_rc_resolve(context, id, name) krb5_x((id)->ops->resolve,(context, id, name))
+
+extern krb5_rc_ops krb5_rc_dfl_ops;
+
+/*
+ * end "rcache.h"
+ */
+
+/*
+ * begin "keytab.h"
+ */
+
+
+/* XXX */
+#define MAX_KEYTAB_NAME_LEN 1100 /* Long enough for MAXPATHLEN + some extra */
+
+typedef krb5_pointer krb5_kt_cursor;   /* XXX */
+
+typedef struct krb5_keytab_entry_st {
+    krb5_magic magic;
+    krb5_principal principal;  /* principal of this key */
+    krb5_timestamp timestamp;  /* time entry written to keytable */
+    krb5_kvno vno;             /* key version number */
+    krb5_keyblock key;         /* the secret key */
+} krb5_keytab_entry;
+
+
+typedef struct _krb5_kt {
+    krb5_magic magic;
+    struct _krb5_kt_ops FAR *ops;
+    krb5_pointer data;
+} FAR *krb5_keytab;
+
+
+typedef struct _krb5_kt_ops {
+    krb5_magic magic;
+    char FAR *prefix;
+    /* routines always present */
+    krb5_error_code (KRB5_CALLCONV *resolve) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_const char FAR *,
+                krb5_keytab FAR *));
+    krb5_error_code (KRB5_CALLCONV *get_name) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                char FAR *,
+                int));
+    krb5_error_code (KRB5_CALLCONV *close) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab));
+    krb5_error_code (KRB5_CALLCONV *get) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                krb5_const_principal,
+                krb5_kvno,
+                krb5_enctype,
+                krb5_keytab_entry FAR *));
+    krb5_error_code (KRB5_CALLCONV *start_seq_get) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                krb5_kt_cursor FAR *));        
+    krb5_error_code (KRB5_CALLCONV *get_next) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                krb5_keytab_entry FAR *,
+                krb5_kt_cursor FAR *));
+    krb5_error_code (KRB5_CALLCONV *end_get) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                krb5_kt_cursor FAR *));
+    /* routines to be included on extended version (write routines) */
+    krb5_error_code (KRB5_CALLCONV *add) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                krb5_keytab_entry FAR *));
+    krb5_error_code (KRB5_CALLCONV *remove) 
+       KRB5_NPROTOTYPE((krb5_context,
+                krb5_keytab,
+                 krb5_keytab_entry FAR *));
+
+    /* Handle for serializer */
+    void * serializer;
+} krb5_kt_ops;
+
+#define krb5_kt_get_type(context, keytab) ((keytab)->ops->prefix)
+#define krb5_kt_get_name(context, keytab, name, namelen) krb5_x((keytab)->ops->get_name,(context, keytab,name,namelen))
+#define krb5_kt_close(context, keytab) krb5_x((keytab)->ops->close,(context, keytab))
+#define krb5_kt_get_entry(context, keytab, principal, vno, enctype, entry) krb5_x((keytab)->ops->get,(context, keytab, principal, vno, enctype, entry))
+#define krb5_kt_start_seq_get(context, keytab, cursor) krb5_x((keytab)->ops->start_seq_get,(context, keytab, cursor))
+#define krb5_kt_next_entry(context, keytab, entry, cursor) krb5_x((keytab)->ops->get_next,(context, keytab, entry, cursor))
+#define krb5_kt_end_seq_get(context, keytab, cursor) krb5_x((keytab)->ops->end_get,(context, keytab, cursor))
+/* remove and add are functions, so that they can return NOWRITE
+   if not a writable keytab */
+
+
+extern krb5_kt_ops krb5_kt_dfl_ops;
+
+/*
+ * end "keytab.h"
+ */
+
+/*
+ * begin "func-proto.h"
+ */
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_init_context
+       KRB5_PROTOTYPE((krb5_context FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_init_secure_context
+       KRB5_PROTOTYPE((krb5_context FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_context
+       KRB5_PROTOTYPE((krb5_context));
+
+krb5_error_code krb5_set_default_in_tkt_ktypes
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_enctype *));
+krb5_error_code krb5_get_default_in_tkt_ktypes
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_enctype **));
+
+krb5_error_code krb5_set_default_tgs_ktypes
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_enctype *));
+krb5_error_code KRB5_CALLCONV krb5_get_tgs_ktypes
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               krb5_enctype **));
+
+krb5_error_code krb5_get_permitted_enctypes
+       KRB5_PROTOTYPE((krb5_context, krb5_enctype **));
+void KRB5_CALLCONV krb5_free_ktypes
+       KRB5_PROTOTYPE ((krb5_context, krb5_enctype *));
+
+krb5_boolean krb5_is_permitted_enctype
+       KRB5_PROTOTYPE((krb5_context, krb5_enctype));
+
+/* libkrb.spec */
+krb5_error_code krb5_kdc_rep_decrypt_proc
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock *,
+               krb5_const_pointer,
+               krb5_kdc_rep * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_decrypt_tkt_part
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock FAR *,
+               krb5_ticket FAR * ));
+krb5_error_code krb5_get_cred_from_kdc
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_ccache,            /* not const, as reading may save
+                                          state */
+               krb5_creds *,
+               krb5_creds **,
+               krb5_creds *** ));
+krb5_error_code krb5_get_cred_from_kdc_validate
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_ccache,            /* not const, as reading may save
+                                          state */
+               krb5_creds *,
+               krb5_creds **,
+               krb5_creds *** ));
+krb5_error_code krb5_get_cred_from_kdc_renew
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_ccache,            /* not const, as reading may save
+                                          state */
+               krb5_creds *,
+               krb5_creds **,
+               krb5_creds *** ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_tgt_creds
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_creds FAR * FAR* )); /* XXX too hard to do with const */
+
+#define        KRB5_GC_USER_USER       1       /* want user-user ticket */
+#define        KRB5_GC_CACHED          2       /* want cached ticket only */
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_credentials
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_creds FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_credentials_validate
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_creds FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_credentials_renew
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_creds FAR * FAR *));
+krb5_error_code krb5_get_cred_via_tkt
+       KRB5_PROTOTYPE((krb5_context,
+                  krb5_creds *,
+                  krb5_const krb5_flags,
+                  krb5_address * krb5_const *,
+                  krb5_creds *,
+                  krb5_creds **));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_req
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_const krb5_flags,
+               char FAR *,
+               char FAR *,
+               krb5_data FAR *,
+               krb5_ccache,
+               krb5_data FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_req_extended
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_const krb5_flags,
+               krb5_data FAR *,
+               krb5_creds FAR *,
+               krb5_data FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_rep
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_data FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_rep
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_const krb5_data FAR *,
+               krb5_ap_rep_enc_part FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_error
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_error FAR *,
+               krb5_data FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_error
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_data FAR *,
+               krb5_error FAR * FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_safe
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_const krb5_data FAR *,
+               krb5_data FAR *,
+               krb5_replay_data FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_priv
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_const krb5_data FAR *,
+               krb5_data FAR *,
+               krb5_replay_data FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_parse_name
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const char FAR *,
+               krb5_principal FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_unparse_name
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               char FAR * FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_unparse_name_ext
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               char FAR * FAR *,
+               int FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_set_principal_realm
+       KRB5_PROTOTYPE((krb5_context, krb5_principal, const char FAR *));
+
+krb5_boolean krb5_address_search
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_address *,
+               krb5_address * krb5_const *));
+krb5_boolean krb5_address_compare
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_address *,
+               krb5_const krb5_address *));
+int krb5_address_order
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_address *,
+               krb5_const krb5_address *));
+krb5_boolean krb5_realm_compare
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               krb5_const_principal));
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV krb5_principal_compare
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               krb5_const_principal));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_keyblock
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock FAR *,
+               krb5_keyblock FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_keyblock_contents
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock FAR *,
+               krb5_keyblock FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_creds
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_creds FAR *,
+               krb5_creds FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_data
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_data FAR *,
+               krb5_data FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_principal
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               krb5_principal FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_addr
+       KRB5_PROTOTYPE((krb5_context,
+               const krb5_address FAR *,
+               krb5_address FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_addresses
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_address FAR * krb5_const FAR *,
+               krb5_address FAR * FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_ticket
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_ticket FAR *,
+               krb5_ticket FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_authdata
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_authdata FAR * krb5_const FAR *,
+               krb5_authdata FAR * FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_authenticator
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_authenticator FAR *,
+               krb5_authenticator FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_copy_checksum
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_checksum FAR *,
+               krb5_checksum FAR * FAR *));
+void krb5_init_ets
+       KRB5_PROTOTYPE((krb5_context));
+void krb5_free_ets
+       KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_generate_subkey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock *, krb5_keyblock **));
+krb5_error_code krb5_generate_seq_number
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_keyblock *, krb5_int32 *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_server_rcache
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_data *, krb5_rcache *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV_C krb5_build_principal_ext
+       KRB5_STDARG_P((krb5_context, krb5_principal FAR *, int, krb5_const char FAR *, ...));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV_C krb5_build_principal
+       KRB5_STDARG_P((krb5_context, krb5_principal FAR *, int, krb5_const char FAR *, ...));
+#ifdef va_start
+/* XXX depending on varargs include file defining va_start... */
+krb5_error_code krb5_build_principal_va
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_principal, int, krb5_const char *, va_list));
+#endif
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_425_conv_principal
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const char FAR *name,
+               krb5_const char FAR *instance, krb5_const char FAR *realm,
+               krb5_principal FAR *princ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_524_conv_principal
+       KRB5_PROTOTYPE((krb5_context context, krb5_const krb5_principal princ, 
+               char FAR *name, char FAR *inst, char FAR *realm));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_chpw_req
+       KRB5_PROTOTYPE((krb5_context context, krb5_auth_context auth_context,
+                       krb5_data *ap_req, char *passwd, krb5_data *packet));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_chpw_rep
+       KRB5_PROTOTYPE((krb5_context context, krb5_auth_context auth_context,
+                      krb5_data *packet, int *result_code,
+                      krb5_data *result_data));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_chpw_result_code_string
+       KRB5_PROTOTYPE((krb5_context context, int result_code,
+                       char **result_codestr));
+
+/* libkt.spec */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_register
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_kt_ops FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_resolve
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const char FAR *,
+               krb5_keytab FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_default_name
+       KRB5_PROTOTYPE((krb5_context,
+               char FAR *,
+               int ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_default
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_keytab FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_free_entry
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_keytab_entry FAR * ));
+/* remove and add are functions, so that they can return NOWRITE
+   if not a writable keytab */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_remove_entry
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_keytab,
+               krb5_keytab_entry FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_add_entry
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_keytab,
+               krb5_keytab_entry FAR * ));
+krb5_error_code krb5_principal2salt
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal, krb5_data *));
+krb5_error_code krb5_principal2salt_norealm
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal, krb5_data *));
+
+/* librc.spec--see rcache.h */
+
+/* libcc.spec */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_resolve
+       KRB5_PROTOTYPE((krb5_context,
+               const char FAR *,
+               krb5_ccache FAR * ));
+KRB5_DLLIMP const char FAR * KRB5_CALLCONV krb5_cc_default_name
+       KRB5_PROTOTYPE((krb5_context));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_set_default_name
+       KRB5_PROTOTYPE((krb5_context, const char *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_default
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_ccache FAR *));
+KRB5_DLLIMP unsigned int KRB5_CALLCONV krb5_get_notification_message
+       KRB5_PROTOTYPE((void));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_copy_creds
+       KRB5_PROTOTYPE((krb5_context context,
+                       krb5_ccache incc,
+                       krb5_ccache outcc));
+
+
+/* chk_trans.c */
+krb5_error_code krb5_check_transited_list
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_data *trans, krb5_data *realm1, krb5_data *realm2));
+
+/* free_rtree.c */
+void krb5_free_realm_tree
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_principal *));
+
+/* krb5_free.c */
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_principal
+       KRB5_PROTOTYPE((krb5_context, krb5_principal ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_authenticator
+       KRB5_PROTOTYPE((krb5_context, krb5_authenticator FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_authenticator_contents
+       KRB5_PROTOTYPE((krb5_context, krb5_authenticator FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_addresses
+       KRB5_PROTOTYPE((krb5_context, krb5_address FAR * FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_address
+       KRB5_PROTOTYPE((krb5_context, krb5_address FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_authdata
+       KRB5_PROTOTYPE((krb5_context, krb5_authdata FAR * FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_tkt_part
+       KRB5_PROTOTYPE((krb5_context, krb5_enc_tkt_part FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_ticket
+       KRB5_PROTOTYPE((krb5_context, krb5_ticket FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_tickets
+       KRB5_PROTOTYPE((krb5_context, krb5_ticket FAR * FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_kdc_req
+       KRB5_PROTOTYPE((krb5_context, krb5_kdc_req FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_kdc_rep
+       KRB5_PROTOTYPE((krb5_context, krb5_kdc_rep FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_last_req
+       KRB5_PROTOTYPE((krb5_context, krb5_last_req_entry FAR * FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_enc_kdc_rep_part
+       KRB5_PROTOTYPE((krb5_context, krb5_enc_kdc_rep_part FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_error
+       KRB5_PROTOTYPE((krb5_context, krb5_error FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_ap_req
+       KRB5_PROTOTYPE((krb5_context, krb5_ap_req FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_ap_rep
+       KRB5_PROTOTYPE((krb5_context, krb5_ap_rep FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_safe
+       KRB5_PROTOTYPE((krb5_context, krb5_safe FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_priv
+       KRB5_PROTOTYPE((krb5_context, krb5_priv FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_priv_enc_part
+       KRB5_PROTOTYPE((krb5_context, krb5_priv_enc_part FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred
+       KRB5_PROTOTYPE((krb5_context, krb5_cred FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_creds
+       KRB5_PROTOTYPE((krb5_context, krb5_creds FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred_contents
+       KRB5_PROTOTYPE((krb5_context, krb5_creds FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cred_enc_part
+       KRB5_PROTOTYPE((krb5_context, krb5_cred_enc_part FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_checksum
+       KRB5_PROTOTYPE((krb5_context, krb5_checksum FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_checksum_contents
+       KRB5_PROTOTYPE((krb5_context, krb5_checksum FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_keyblock
+       KRB5_PROTOTYPE((krb5_context, krb5_keyblock FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_keyblock_contents
+       KRB5_PROTOTYPE((krb5_context, krb5_keyblock FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_pa_data
+       KRB5_PROTOTYPE((krb5_context, krb5_pa_data FAR * FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_ap_rep_enc_part
+       KRB5_PROTOTYPE((krb5_context, krb5_ap_rep_enc_part FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_tkt_authent
+       KRB5_PROTOTYPE((krb5_context, krb5_tkt_authent FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_pwd_data
+       KRB5_PROTOTYPE((krb5_context, krb5_pwd_data FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_pwd_sequences
+       KRB5_PROTOTYPE((krb5_context, passwd_phrase_element FAR * FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_data
+       KRB5_PROTOTYPE((krb5_context, krb5_data FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_data_contents
+       KRB5_PROTOTYPE((krb5_context, krb5_data FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_unparsed_name
+       KRB5_PROTOTYPE((krb5_context, char FAR *));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_cksumtypes
+       KRB5_PROTOTYPE((krb5_context, krb5_cksumtype FAR *));
+
+/* From krb5/os but needed but by the outside world */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_us_timeofday
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_int32 FAR *,
+               krb5_int32 FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_timeofday
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_int32 FAR * ));
+                /* get all the addresses of this host */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_os_localaddr
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_address FAR * FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_default_realm
+       KRB5_PROTOTYPE((krb5_context,
+                char FAR * FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_set_default_realm
+       KRB5_PROTOTYPE((krb5_context,
+                  krb5_const char FAR * ));
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_default_realm
+       KRB5_PROTOTYPE((krb5_context,
+                  char FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_sname_to_principal
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const char FAR *,
+                  krb5_const char FAR *,
+                  krb5_int32,
+                  krb5_principal FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_change_password
+       KRB5_PROTOTYPE((krb5_context context, krb5_creds *creds, char *newpw,
+                       int *result_code, krb5_data *result_code_string,
+                       krb5_data *result_string));
+
+#ifndef macintosh
+krb5_error_code krb5_set_config_files
+       KRB5_PROTOTYPE ((krb5_context, krb5_const char FAR * FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_default_config_files
+       KRB5_PROTOTYPE((char ***filenames));
+
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_config_files
+       KRB5_PROTOTYPE((char **filenames));
+
+#endif
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_profile
+       KRB5_PROTOTYPE((krb5_context, profile_t *));
+
+krb5_error_code krb5_send_tgs
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_const krb5_ticket_times *,
+               krb5_const krb5_enctype *,
+               krb5_const_principal,
+               krb5_address * krb5_const *,
+               krb5_authdata * krb5_const *,
+               krb5_pa_data * krb5_const *,
+               krb5_const krb5_data *,
+               krb5_creds *,
+               krb5_response * ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_in_tkt
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_address FAR * krb5_const FAR *,
+               krb5_enctype FAR *,
+               krb5_preauthtype FAR *,
+               krb5_error_code ( FAR * )(krb5_context,
+                                       krb5_const krb5_enctype,
+                                       krb5_data FAR *,
+                                       krb5_const_pointer,
+                                       krb5_keyblock FAR * FAR *),
+               krb5_const_pointer,
+               krb5_error_code ( FAR * )(krb5_context,
+                                       krb5_const krb5_keyblock FAR *,
+                                       krb5_const_pointer,
+                                       krb5_kdc_rep FAR * ),
+               krb5_const_pointer,
+               krb5_creds FAR *,
+               krb5_ccache,
+               krb5_kdc_rep FAR * FAR * ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_password
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_address FAR * krb5_const FAR *,
+               krb5_enctype FAR *,
+               krb5_preauthtype FAR *,
+               krb5_const char FAR *,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_kdc_rep FAR * FAR * ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_skey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_address FAR * krb5_const FAR *,
+               krb5_enctype FAR *,
+               krb5_preauthtype FAR *,
+               krb5_const krb5_keyblock FAR *,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_kdc_rep FAR * FAR * ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_in_tkt_with_keytab
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_flags,
+               krb5_address FAR * krb5_const FAR *,
+               krb5_enctype FAR *,
+               krb5_preauthtype FAR *,
+               krb5_const krb5_keytab,
+               krb5_ccache,
+               krb5_creds FAR *,
+               krb5_kdc_rep FAR * FAR * ));
+
+
+krb5_error_code krb5_decode_kdc_rep
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_data *,
+               krb5_const krb5_keyblock *,
+               krb5_kdc_rep ** ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_req
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_const krb5_data FAR *,
+               krb5_const_principal,
+               krb5_keytab,
+               krb5_flags FAR *,
+               krb5_ticket FAR * FAR *));
+
+krb5_error_code krb5_rd_req_decoded
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context *,
+               krb5_const krb5_ap_req *,
+               krb5_const_principal,
+               krb5_keytab,
+               krb5_flags *,
+               krb5_ticket **));
+
+krb5_error_code krb5_rd_req_decoded_anyflag
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context *,
+               krb5_const krb5_ap_req *,
+               krb5_const_principal,
+               krb5_keytab,
+               krb5_flags *,
+               krb5_ticket **));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_kt_read_service_key
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_pointer,
+               krb5_principal,
+               krb5_kvno,
+               krb5_enctype,
+               krb5_keyblock FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_safe
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_const krb5_data FAR *,
+               krb5_data FAR *,
+               krb5_replay_data FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_priv
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_const krb5_data FAR *,
+               krb5_data FAR *,
+               krb5_replay_data FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cc_register
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_cc_ops FAR *,
+               krb5_boolean ));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_sendauth 
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_pointer,
+               char FAR *,
+               krb5_principal,
+               krb5_principal,
+               krb5_flags,
+               krb5_data FAR *,
+               krb5_creds FAR *,
+               krb5_ccache,
+               krb5_error FAR * FAR *,
+               krb5_ap_rep_enc_part FAR * FAR *,
+               krb5_creds FAR * FAR *));
+       
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_recvauth
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_pointer,
+               char FAR *,
+               krb5_principal,
+               krb5_int32, 
+               krb5_keytab,
+               krb5_ticket FAR * FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_recvauth_version
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *,
+               krb5_pointer,
+               krb5_principal,
+               krb5_int32, 
+               krb5_keytab,
+               krb5_ticket FAR * FAR *,
+               krb5_data FAR *));
+
+krb5_error_code krb5_walk_realm_tree
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const krb5_data *,
+               krb5_const krb5_data *,
+               krb5_principal **,
+               int));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_ncred
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_creds FAR * FAR *,
+               krb5_data FAR * FAR *,
+               krb5_replay_data FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_mk_1cred
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_creds FAR *,
+               krb5_data FAR * FAR *,
+               krb5_replay_data FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_rd_cred
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_data FAR *,
+               krb5_creds FAR * FAR * FAR *,
+               krb5_replay_data FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_fwd_tgt_creds
+       KRB5_PROTOTYPE((krb5_context, 
+               krb5_auth_context,
+               char FAR *,
+               krb5_principal, 
+               krb5_principal, 
+               krb5_ccache,
+               int forwardable,
+               krb5_data FAR *));      
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_init
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_free
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_setflags
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_int32));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getflags
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_int32 FAR *));
+
+krb5_error_code krb5_auth_con_setaddrs
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_address *,
+               krb5_address *));
+
+krb5_error_code krb5_auth_con_getaddrs
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_address **,
+               krb5_address **));
+
+krb5_error_code krb5_auth_con_setports
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_address *,
+               krb5_address *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_setuseruserkey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_keyblock FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getkey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_keyblock **));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getlocalsubkey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_keyblock FAR * FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_set_req_cksumtype
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_cksumtype));
+
+krb5_error_code krb5_auth_con_set_safe_cksumtype
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_cksumtype));
+
+krb5_error_code krb5_auth_con_getcksumtype
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_cksumtype *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getlocalseqnumber
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_int32 FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getremoteseqnumber
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_int32 FAR *));
+
+krb5_error_code krb5_auth_con_initivector
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context));
+
+krb5_error_code krb5_auth_con_setivector
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_pointer));
+
+krb5_error_code krb5_auth_con_getivector
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_pointer *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_setrcache
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_rcache));
+
+krb5_error_code krb5_auth_con_getrcache
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_rcache *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getauthenticator
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_authenticator FAR * FAR *));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_getremotesubkey
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               krb5_keyblock FAR * FAR *));
+
+#define KRB5_REALM_BRANCH_CHAR '.'
+
+/*
+ * end "func-proto.h"
+ */
+
+/*
+ * begin stuff from libos.h
+ */
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_read_password
+       KRB5_PROTOTYPE((krb5_context,
+               const char FAR *,
+               const char FAR *,
+               char FAR *,
+               int FAR * ));
+krb5_error_code krb5_aname_to_localname
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_const_principal,
+               const int,
+               char * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_host_realm
+       KRB5_PROTOTYPE((krb5_context,
+               const char FAR *,
+               char FAR * FAR * FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_free_host_realm
+       KRB5_PROTOTYPE((krb5_context,
+               char FAR * const FAR * ));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_get_realm_domain
+       KRB5_PROTOTYPE((krb5_context,
+               const char *,
+               char ** ));
+KRB5_DLLIMP krb5_boolean KRB5_CALLCONV krb5_kuserok
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_principal, const char *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_auth_con_genaddrs
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_auth_context,
+               int, int));
+krb5_error_code krb5_gen_portaddr
+       KRB5_PROTOTYPE((krb5_context,
+               const krb5_address *,
+               krb5_const_pointer,
+               krb5_address **));
+krb5_error_code krb5_make_fulladdr
+       KRB5_PROTOTYPE((krb5_context,
+               krb5_address *,
+               krb5_address *,
+               krb5_address *));
+
+krb5_error_code krb5_os_hostaddr
+       KRB5_PROTOTYPE((krb5_context, const char *, krb5_address ***));
+
+krb5_error_code krb5_set_real_time
+       KRB5_PROTOTYPE((krb5_context, krb5_int32, krb5_int32));
+krb5_error_code krb5_set_debugging_time
+       KRB5_PROTOTYPE((krb5_context, krb5_int32, krb5_int32));
+krb5_error_code krb5_use_natural_time
+       KRB5_PROTOTYPE((krb5_context));
+krb5_error_code krb5_get_time_offsets
+       KRB5_PROTOTYPE((krb5_context, krb5_int32 *, krb5_int32 *));
+krb5_error_code krb5_set_time_offsets
+       KRB5_PROTOTYPE((krb5_context, krb5_int32, krb5_int32));
+
+/* str_conv.c */
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_enctype
+       KRB5_PROTOTYPE((char FAR *, krb5_enctype FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_salttype
+       KRB5_PROTOTYPE((char FAR *, krb5_int32 FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_cksumtype
+       KRB5_PROTOTYPE((char FAR *, krb5_cksumtype FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_timestamp
+       KRB5_PROTOTYPE((char FAR *, krb5_timestamp FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_string_to_deltat
+       KRB5_PROTOTYPE((char FAR *, krb5_deltat FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_enctype_to_string
+       KRB5_PROTOTYPE((krb5_enctype, char FAR *, size_t));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_salttype_to_string
+       KRB5_PROTOTYPE((krb5_int32, char FAR *, size_t));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_cksumtype_to_string
+       KRB5_PROTOTYPE((krb5_cksumtype, char FAR *, size_t));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_timestamp_to_string
+       KRB5_PROTOTYPE((krb5_timestamp, char FAR *, size_t));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_timestamp_to_sfstring
+       KRB5_PROTOTYPE((krb5_timestamp, char FAR *, size_t, char FAR *));
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_deltat_to_string
+       KRB5_PROTOTYPE((krb5_deltat, char FAR *, size_t));
+
+
+
+/* The name of the Kerberos ticket granting service... and its size */
+#define        KRB5_TGS_NAME           "krbtgt"
+#define KRB5_TGS_NAME_SIZE     6
+
+/* flags for recvauth */
+#define KRB5_RECVAUTH_SKIP_VERSION     0x0001
+#define KRB5_RECVAUTH_BADAUTHVERS      0x0002
+/* initial ticket api functions */
+
+typedef struct _krb5_prompt {
+    char *prompt;
+    int hidden;
+    krb5_data *reply;
+} krb5_prompt;
+
+typedef krb5_error_code (KRB5_CALLCONV *krb5_prompter_fct)(krb5_context context,
+                                            void *data,
+                                            const char *name,
+                                            const char *banner,
+                                            int num_prompts,
+                                            krb5_prompt prompts[]);
+
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_prompter_posix
+KRB5_PROTOTYPE((krb5_context context,
+               void *data,
+               const char *name,
+               const char *banner,
+               int num_prompts,
+               krb5_prompt prompts[]));
+
+typedef struct _krb5_get_init_creds_opt {
+    krb5_flags flags;
+    krb5_deltat tkt_life;
+    krb5_deltat renew_life;
+    int forwardable;
+    int proxiable;
+    krb5_enctype *etype_list;
+    int etype_list_length;
+    krb5_address **address_list;
+    krb5_preauthtype *preauth_list;
+    int preauth_list_length;
+    krb5_data *salt;
+} krb5_get_init_creds_opt;
+
+#define KRB5_GET_INIT_CREDS_OPT_TKT_LIFE       0x0001
+#define KRB5_GET_INIT_CREDS_OPT_RENEW_LIFE     0x0002
+#define KRB5_GET_INIT_CREDS_OPT_FORWARDABLE    0x0004
+#define KRB5_GET_INIT_CREDS_OPT_PROXIABLE      0x0008
+#define KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST     0x0010
+#define KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST   0x0020
+#define KRB5_GET_INIT_CREDS_OPT_PREAUTH_LIST   0x0040
+#define KRB5_GET_INIT_CREDS_OPT_SALT           0x0080
+
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_init
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_tkt_life
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_deltat tkt_life));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_renew_life
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_deltat renew_life));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_forwardable
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               int forwardable));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_proxiable
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               int proxiable));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_etype_list
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_enctype *etype_list,
+               int etype_list_length));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_address_list
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_address **addresses));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_preauth_list
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_preauthtype *preauth_list,
+               int preauth_list_length));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_get_init_creds_opt_set_salt
+KRB5_PROTOTYPE((krb5_get_init_creds_opt *opt,
+               krb5_data *salt));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_password
+KRB5_PROTOTYPE((krb5_context context,
+               krb5_creds *creds,
+               krb5_principal client,
+               char *password,
+               krb5_prompter_fct prompter,
+               void *data,
+               krb5_deltat start_time,
+               char *in_tkt_service,
+               krb5_get_init_creds_opt *options));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_keytab
+KRB5_PROTOTYPE((krb5_context context,
+               krb5_creds *creds,
+               krb5_principal client,
+               krb5_keytab arg_keytab,
+               krb5_deltat start_time,
+               char *in_tkt_service,
+               krb5_get_init_creds_opt *options));
+
+typedef struct _krb5_verify_init_creds_opt {
+    krb5_flags flags;
+    int ap_req_nofail;
+} krb5_verify_init_creds_opt;
+
+#define KRB5_VERIFY_INIT_CREDS_OPT_AP_REQ_NOFAIL       0x0001
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_verify_init_creds_opt_init
+KRB5_PROTOTYPE((krb5_verify_init_creds_opt *options));
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_verify_init_creds_opt_set_ap_req_nofail
+KRB5_PROTOTYPE((krb5_verify_init_creds_opt *options,
+               int ap_req_nofail));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_verify_init_creds
+KRB5_PROTOTYPE((krb5_context context,
+               krb5_creds *creds,
+               krb5_principal ap_req_server,
+               krb5_keytab ap_req_keytab,
+               krb5_ccache *ccache,
+               krb5_verify_init_creds_opt *options));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_validated_creds
+KRB5_PROTOTYPE((krb5_context context,
+               krb5_creds *creds,
+               krb5_principal client,
+               krb5_ccache ccache,
+               char *in_tkt_service));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_renewed_creds
+KRB5_PROTOTYPE((krb5_context context,
+               krb5_creds *creds,
+               krb5_principal client,
+               krb5_ccache ccache,
+               char *in_tkt_service));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_decode_ticket
+KRB5_PROTOTYPE((const krb5_data *code, 
+               krb5_ticket **rep));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_appdefault_string
+KRB5_PROTOTYPE((krb5_context context,
+               const char *appname,  
+               const krb5_data *realm,
+               const char *option,
+               const char *default_value,
+               char ** ret_value));
+
+KRB5_DLLIMP void KRB5_CALLCONV
+krb5_appdefault_boolean
+KRB5_PROTOTYPE((krb5_context context,
+               const char *appname,  
+               const krb5_data *realm,
+               const char *option,
+               int default_value,
+               int *ret_value));
+
+/*
+ * The realm iterator functions
+ */
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_realm_iterator_create
+       KRB5_PROTOTYPE((krb5_context context, void **iter_p));
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV krb5_realm_iterator
+       KRB5_PROTOTYPE((krb5_context context, void **iter_p, char **ret_realm));
+
+KRB5_DLLIMP void KRB5_CALLCONV krb5_realm_iterator_free
+       KRB5_PROTOTYPE((krb5_context context, void **iter_p));
+
+KRB5_DLLIMP void KRB5_CALLCONV krb5_free_realm_string
+       KRB5_PROTOTYPE((krb5_context context, char *str));
+
+/*
+ * Prompter enhancements
+ */
+
+#define KRB5_PROMPT_TYPE_PASSWORD            0x1
+#define KRB5_PROMPT_TYPE_NEW_PASSWORD        0x2
+#define KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN  0x3
+#define KRB5_PROMPT_TYPE_PREAUTH             0x4
+
+typedef krb5_int32 krb5_prompt_type;
+
+KRB5_DLLIMP krb5_prompt_type* KRB5_CALLCONV krb5_get_prompt_types
+       KRB5_PROTOTYPE((krb5_context context));
+
+/* Macintosh CFM-68K magic incantation */
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack()
+#endif
+
+#ifdef PRAGMA_IMPORT_OFF
+#pragma import off
+#elif PRAGMA_IMPORT
+#pragma import reset
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* KRB5_GENERAL__ */
+
+/*
+ * :::MITKerberosLib:GSSKerberos5Sources_9:include:krb5_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <KerberosComErr/KerberosComErr.h>
+#else
+#include <com_err.h>
+#endif
+
+#define KRB5KDC_ERR_NONE                         (-1765328384L)
+#define KRB5KDC_ERR_NAME_EXP                     (-1765328383L)
+#define KRB5KDC_ERR_SERVICE_EXP                  (-1765328382L)
+#define KRB5KDC_ERR_BAD_PVNO                     (-1765328381L)
+#define KRB5KDC_ERR_C_OLD_MAST_KVNO              (-1765328380L)
+#define KRB5KDC_ERR_S_OLD_MAST_KVNO              (-1765328379L)
+#define KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN          (-1765328378L)
+#define KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN          (-1765328377L)
+#define KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE         (-1765328376L)
+#define KRB5KDC_ERR_NULL_KEY                     (-1765328375L)
+#define KRB5KDC_ERR_CANNOT_POSTDATE              (-1765328374L)
+#define KRB5KDC_ERR_NEVER_VALID                  (-1765328373L)
+#define KRB5KDC_ERR_POLICY                       (-1765328372L)
+#define KRB5KDC_ERR_BADOPTION                    (-1765328371L)
+#define KRB5KDC_ERR_ETYPE_NOSUPP                 (-1765328370L)
+#define KRB5KDC_ERR_SUMTYPE_NOSUPP               (-1765328369L)
+#define KRB5KDC_ERR_PADATA_TYPE_NOSUPP           (-1765328368L)
+#define KRB5KDC_ERR_TRTYPE_NOSUPP                (-1765328367L)
+#define KRB5KDC_ERR_CLIENT_REVOKED               (-1765328366L)
+#define KRB5KDC_ERR_SERVICE_REVOKED              (-1765328365L)
+#define KRB5KDC_ERR_TGT_REVOKED                  (-1765328364L)
+#define KRB5KDC_ERR_CLIENT_NOTYET                (-1765328363L)
+#define KRB5KDC_ERR_SERVICE_NOTYET               (-1765328362L)
+#define KRB5KDC_ERR_KEY_EXP                      (-1765328361L)
+#define KRB5KDC_ERR_PREAUTH_FAILED               (-1765328360L)
+#define KRB5KDC_ERR_PREAUTH_REQUIRED             (-1765328359L)
+#define KRB5KDC_ERR_SERVER_NOMATCH               (-1765328358L)
+#define KRB5PLACEHOLD_27                         (-1765328357L)
+#define KRB5PLACEHOLD_28                         (-1765328356L)
+#define KRB5PLACEHOLD_29                         (-1765328355L)
+#define KRB5PLACEHOLD_30                         (-1765328354L)
+#define KRB5KRB_AP_ERR_BAD_INTEGRITY             (-1765328353L)
+#define KRB5KRB_AP_ERR_TKT_EXPIRED               (-1765328352L)
+#define KRB5KRB_AP_ERR_TKT_NYV                   (-1765328351L)
+#define KRB5KRB_AP_ERR_REPEAT                    (-1765328350L)
+#define KRB5KRB_AP_ERR_NOT_US                    (-1765328349L)
+#define KRB5KRB_AP_ERR_BADMATCH                  (-1765328348L)
+#define KRB5KRB_AP_ERR_SKEW                      (-1765328347L)
+#define KRB5KRB_AP_ERR_BADADDR                   (-1765328346L)
+#define KRB5KRB_AP_ERR_BADVERSION                (-1765328345L)
+#define KRB5KRB_AP_ERR_MSG_TYPE                  (-1765328344L)
+#define KRB5KRB_AP_ERR_MODIFIED                  (-1765328343L)
+#define KRB5KRB_AP_ERR_BADORDER                  (-1765328342L)
+#define KRB5KRB_AP_ERR_ILL_CR_TKT                (-1765328341L)
+#define KRB5KRB_AP_ERR_BADKEYVER                 (-1765328340L)
+#define KRB5KRB_AP_ERR_NOKEY                     (-1765328339L)
+#define KRB5KRB_AP_ERR_MUT_FAIL                  (-1765328338L)
+#define KRB5KRB_AP_ERR_BADDIRECTION              (-1765328337L)
+#define KRB5KRB_AP_ERR_METHOD                    (-1765328336L)
+#define KRB5KRB_AP_ERR_BADSEQ                    (-1765328335L)
+#define KRB5KRB_AP_ERR_INAPP_CKSUM               (-1765328334L)
+#define KRB5PLACEHOLD_51                         (-1765328333L)
+#define KRB5PLACEHOLD_52                         (-1765328332L)
+#define KRB5PLACEHOLD_53                         (-1765328331L)
+#define KRB5PLACEHOLD_54                         (-1765328330L)
+#define KRB5PLACEHOLD_55                         (-1765328329L)
+#define KRB5PLACEHOLD_56                         (-1765328328L)
+#define KRB5PLACEHOLD_57                         (-1765328327L)
+#define KRB5PLACEHOLD_58                         (-1765328326L)
+#define KRB5PLACEHOLD_59                         (-1765328325L)
+#define KRB5KRB_ERR_GENERIC                      (-1765328324L)
+#define KRB5KRB_ERR_FIELD_TOOLONG                (-1765328323L)
+#define KRB5PLACEHOLD_62                         (-1765328322L)
+#define KRB5PLACEHOLD_63                         (-1765328321L)
+#define KRB5PLACEHOLD_64                         (-1765328320L)
+#define KRB5PLACEHOLD_65                         (-1765328319L)
+#define KRB5PLACEHOLD_66                         (-1765328318L)
+#define KRB5PLACEHOLD_67                         (-1765328317L)
+#define KRB5PLACEHOLD_68                         (-1765328316L)
+#define KRB5PLACEHOLD_69                         (-1765328315L)
+#define KRB5PLACEHOLD_70                         (-1765328314L)
+#define KRB5PLACEHOLD_71                         (-1765328313L)
+#define KRB5PLACEHOLD_72                         (-1765328312L)
+#define KRB5PLACEHOLD_73                         (-1765328311L)
+#define KRB5PLACEHOLD_74                         (-1765328310L)
+#define KRB5PLACEHOLD_75                         (-1765328309L)
+#define KRB5PLACEHOLD_76                         (-1765328308L)
+#define KRB5PLACEHOLD_77                         (-1765328307L)
+#define KRB5PLACEHOLD_78                         (-1765328306L)
+#define KRB5PLACEHOLD_79                         (-1765328305L)
+#define KRB5PLACEHOLD_80                         (-1765328304L)
+#define KRB5PLACEHOLD_81                         (-1765328303L)
+#define KRB5PLACEHOLD_82                         (-1765328302L)
+#define KRB5PLACEHOLD_83                         (-1765328301L)
+#define KRB5PLACEHOLD_84                         (-1765328300L)
+#define KRB5PLACEHOLD_85                         (-1765328299L)
+#define KRB5PLACEHOLD_86                         (-1765328298L)
+#define KRB5PLACEHOLD_87                         (-1765328297L)
+#define KRB5PLACEHOLD_88                         (-1765328296L)
+#define KRB5PLACEHOLD_89                         (-1765328295L)
+#define KRB5PLACEHOLD_90                         (-1765328294L)
+#define KRB5PLACEHOLD_91                         (-1765328293L)
+#define KRB5PLACEHOLD_92                         (-1765328292L)
+#define KRB5PLACEHOLD_93                         (-1765328291L)
+#define KRB5PLACEHOLD_94                         (-1765328290L)
+#define KRB5PLACEHOLD_95                         (-1765328289L)
+#define KRB5PLACEHOLD_96                         (-1765328288L)
+#define KRB5PLACEHOLD_97                         (-1765328287L)
+#define KRB5PLACEHOLD_98                         (-1765328286L)
+#define KRB5PLACEHOLD_99                         (-1765328285L)
+#define KRB5PLACEHOLD_100                        (-1765328284L)
+#define KRB5PLACEHOLD_101                        (-1765328283L)
+#define KRB5PLACEHOLD_102                        (-1765328282L)
+#define KRB5PLACEHOLD_103                        (-1765328281L)
+#define KRB5PLACEHOLD_104                        (-1765328280L)
+#define KRB5PLACEHOLD_105                        (-1765328279L)
+#define KRB5PLACEHOLD_106                        (-1765328278L)
+#define KRB5PLACEHOLD_107                        (-1765328277L)
+#define KRB5PLACEHOLD_108                        (-1765328276L)
+#define KRB5PLACEHOLD_109                        (-1765328275L)
+#define KRB5PLACEHOLD_110                        (-1765328274L)
+#define KRB5PLACEHOLD_111                        (-1765328273L)
+#define KRB5PLACEHOLD_112                        (-1765328272L)
+#define KRB5PLACEHOLD_113                        (-1765328271L)
+#define KRB5PLACEHOLD_114                        (-1765328270L)
+#define KRB5PLACEHOLD_115                        (-1765328269L)
+#define KRB5PLACEHOLD_116                        (-1765328268L)
+#define KRB5PLACEHOLD_117                        (-1765328267L)
+#define KRB5PLACEHOLD_118                        (-1765328266L)
+#define KRB5PLACEHOLD_119                        (-1765328265L)
+#define KRB5PLACEHOLD_120                        (-1765328264L)
+#define KRB5PLACEHOLD_121                        (-1765328263L)
+#define KRB5PLACEHOLD_122                        (-1765328262L)
+#define KRB5PLACEHOLD_123                        (-1765328261L)
+#define KRB5PLACEHOLD_124                        (-1765328260L)
+#define KRB5PLACEHOLD_125                        (-1765328259L)
+#define KRB5PLACEHOLD_126                        (-1765328258L)
+#define KRB5PLACEHOLD_127                        (-1765328257L)
+#define KRB5_ERR_RCSID                           (-1765328256L)
+#define KRB5_LIBOS_BADLOCKFLAG                   (-1765328255L)
+#define KRB5_LIBOS_CANTREADPWD                   (-1765328254L)
+#define KRB5_LIBOS_BADPWDMATCH                   (-1765328253L)
+#define KRB5_LIBOS_PWDINTR                       (-1765328252L)
+#define KRB5_PARSE_ILLCHAR                       (-1765328251L)
+#define KRB5_PARSE_MALFORMED                     (-1765328250L)
+#define KRB5_CONFIG_CANTOPEN                     (-1765328249L)
+#define KRB5_CONFIG_BADFORMAT                    (-1765328248L)
+#define KRB5_CONFIG_NOTENUFSPACE                 (-1765328247L)
+#define KRB5_BADMSGTYPE                          (-1765328246L)
+#define KRB5_CC_BADNAME                          (-1765328245L)
+#define KRB5_CC_UNKNOWN_TYPE                     (-1765328244L)
+#define KRB5_CC_NOTFOUND                         (-1765328243L)
+#define KRB5_CC_END                              (-1765328242L)
+#define KRB5_NO_TKT_SUPPLIED                     (-1765328241L)
+#define KRB5KRB_AP_WRONG_PRINC                   (-1765328240L)
+#define KRB5KRB_AP_ERR_TKT_INVALID               (-1765328239L)
+#define KRB5_PRINC_NOMATCH                       (-1765328238L)
+#define KRB5_KDCREP_MODIFIED                     (-1765328237L)
+#define KRB5_KDCREP_SKEW                         (-1765328236L)
+#define KRB5_IN_TKT_REALM_MISMATCH               (-1765328235L)
+#define KRB5_PROG_ETYPE_NOSUPP                   (-1765328234L)
+#define KRB5_PROG_KEYTYPE_NOSUPP                 (-1765328233L)
+#define KRB5_WRONG_ETYPE                         (-1765328232L)
+#define KRB5_PROG_SUMTYPE_NOSUPP                 (-1765328231L)
+#define KRB5_REALM_UNKNOWN                       (-1765328230L)
+#define KRB5_SERVICE_UNKNOWN                     (-1765328229L)
+#define KRB5_KDC_UNREACH                         (-1765328228L)
+#define KRB5_NO_LOCALNAME                        (-1765328227L)
+#define KRB5_MUTUAL_FAILED                       (-1765328226L)
+#define KRB5_RC_TYPE_EXISTS                      (-1765328225L)
+#define KRB5_RC_MALLOC                           (-1765328224L)
+#define KRB5_RC_TYPE_NOTFOUND                    (-1765328223L)
+#define KRB5_RC_UNKNOWN                          (-1765328222L)
+#define KRB5_RC_REPLAY                           (-1765328221L)
+#define KRB5_RC_IO                               (-1765328220L)
+#define KRB5_RC_NOIO                             (-1765328219L)
+#define KRB5_RC_PARSE                            (-1765328218L)
+#define KRB5_RC_IO_EOF                           (-1765328217L)
+#define KRB5_RC_IO_MALLOC                        (-1765328216L)
+#define KRB5_RC_IO_PERM                          (-1765328215L)
+#define KRB5_RC_IO_IO                            (-1765328214L)
+#define KRB5_RC_IO_UNKNOWN                       (-1765328213L)
+#define KRB5_RC_IO_SPACE                         (-1765328212L)
+#define KRB5_TRANS_CANTOPEN                      (-1765328211L)
+#define KRB5_TRANS_BADFORMAT                     (-1765328210L)
+#define KRB5_LNAME_CANTOPEN                      (-1765328209L)
+#define KRB5_LNAME_NOTRANS                       (-1765328208L)
+#define KRB5_LNAME_BADFORMAT                     (-1765328207L)
+#define KRB5_CRYPTO_INTERNAL                     (-1765328206L)
+#define KRB5_KT_BADNAME                          (-1765328205L)
+#define KRB5_KT_UNKNOWN_TYPE                     (-1765328204L)
+#define KRB5_KT_NOTFOUND                         (-1765328203L)
+#define KRB5_KT_END                              (-1765328202L)
+#define KRB5_KT_NOWRITE                          (-1765328201L)
+#define KRB5_KT_IOERR                            (-1765328200L)
+#define KRB5_NO_TKT_IN_RLM                       (-1765328199L)
+#define KRB5DES_BAD_KEYPAR                       (-1765328198L)
+#define KRB5DES_WEAK_KEY                         (-1765328197L)
+#define KRB5_BAD_ENCTYPE                         (-1765328196L)
+#define KRB5_BAD_KEYSIZE                         (-1765328195L)
+#define KRB5_BAD_MSIZE                           (-1765328194L)
+#define KRB5_CC_TYPE_EXISTS                      (-1765328193L)
+#define KRB5_KT_TYPE_EXISTS                      (-1765328192L)
+#define KRB5_CC_IO                               (-1765328191L)
+#define KRB5_FCC_PERM                            (-1765328190L)
+#define KRB5_FCC_NOFILE                          (-1765328189L)
+#define KRB5_FCC_INTERNAL                        (-1765328188L)
+#define KRB5_CC_WRITE                            (-1765328187L)
+#define KRB5_CC_NOMEM                            (-1765328186L)
+#define KRB5_CC_FORMAT                           (-1765328185L)
+#define KRB5_CC_NOT_KTYPE                        (-1765328184L)
+#define KRB5_INVALID_FLAGS                       (-1765328183L)
+#define KRB5_NO_2ND_TKT                          (-1765328182L)
+#define KRB5_NOCREDS_SUPPLIED                    (-1765328181L)
+#define KRB5_SENDAUTH_BADAUTHVERS                (-1765328180L)
+#define KRB5_SENDAUTH_BADAPPLVERS                (-1765328179L)
+#define KRB5_SENDAUTH_BADRESPONSE                (-1765328178L)
+#define KRB5_SENDAUTH_REJECTED                   (-1765328177L)
+#define KRB5_PREAUTH_BAD_TYPE                    (-1765328176L)
+#define KRB5_PREAUTH_NO_KEY                      (-1765328175L)
+#define KRB5_PREAUTH_FAILED                      (-1765328174L)
+#define KRB5_RCACHE_BADVNO                       (-1765328173L)
+#define KRB5_CCACHE_BADVNO                       (-1765328172L)
+#define KRB5_KEYTAB_BADVNO                       (-1765328171L)
+#define KRB5_PROG_ATYPE_NOSUPP                   (-1765328170L)
+#define KRB5_RC_REQUIRED                         (-1765328169L)
+#define KRB5_ERR_BAD_HOSTNAME                    (-1765328168L)
+#define KRB5_ERR_HOST_REALM_UNKNOWN              (-1765328167L)
+#define KRB5_SNAME_UNSUPP_NAMETYPE               (-1765328166L)
+#define KRB5KRB_AP_ERR_V4_REPLY                  (-1765328165L)
+#define KRB5_REALM_CANT_RESOLVE                  (-1765328164L)
+#define KRB5_TKT_NOT_FORWARDABLE                 (-1765328163L)
+#define KRB5_FWD_BAD_PRINCIPAL                   (-1765328162L)
+#define KRB5_GET_IN_TKT_LOOP                     (-1765328161L)
+#define KRB5_CONFIG_NODEFREALM                   (-1765328160L)
+#define KRB5_SAM_UNSUPPORTED                     (-1765328159L)
+#define KRB5_KT_NAME_TOOLONG                     (-1765328158L)
+#define KRB5_KT_KVNONOTFOUND                     (-1765328157L)
+#define KRB5_APPL_EXPIRED                        (-1765328156L)
+#define KRB5_LIB_EXPIRED                         (-1765328155L)
+#define KRB5_CHPW_PWDNULL                        (-1765328154L)
+#define KRB5_CHPW_FAIL                           (-1765328153L)
+#define KRB5_KT_FORMAT                           (-1765328152L)
+#define KRB5_NOPERM_ETYPE                        (-1765328151L)
+#define KRB5_CONFIG_ETYPE_NOSUPP                 (-1765328150L)
+#define KRB5_OBSOLETE_FN                         (-1765328149L)
+#define ERROR_TABLE_BASE_krb5 (-1765328384L)
+
+extern struct error_table et_krb5_error_table;
+
+#if (defined(unix) || defined(_AIX)) && !(defined(__MACH__) && defined(__APPLE__))
+/* for compatibility with older versions... */
+extern void initialize_krb5_error_table ();
+#define init_krb5_err_tbl initialize_krb5_error_table
+#define krb5_err_base ERROR_TABLE_BASE_krb5
+#else
+#define initialize_krb5_error_table()
+#endif
+/*
+ * :::MITKerberosLib:GSSKerberos5Sources_9:include:kdb5_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <KerberosComErr/KerberosComErr.h>
+#else
+#include <com_err.h>
+#endif
+
+#define KRB5_KDB_RCSID                           (-1780008448L)
+#define KRB5_KDB_INUSE                           (-1780008447L)
+#define KRB5_KDB_UK_SERROR                       (-1780008446L)
+#define KRB5_KDB_UK_RERROR                       (-1780008445L)
+#define KRB5_KDB_UNAUTH                          (-1780008444L)
+#define KRB5_KDB_NOENTRY                         (-1780008443L)
+#define KRB5_KDB_ILL_WILDCARD                    (-1780008442L)
+#define KRB5_KDB_DB_INUSE                        (-1780008441L)
+#define KRB5_KDB_DB_CHANGED                      (-1780008440L)
+#define KRB5_KDB_TRUNCATED_RECORD                (-1780008439L)
+#define KRB5_KDB_RECURSIVELOCK                   (-1780008438L)
+#define KRB5_KDB_NOTLOCKED                       (-1780008437L)
+#define KRB5_KDB_BADLOCKMODE                     (-1780008436L)
+#define KRB5_KDB_DBNOTINITED                     (-1780008435L)
+#define KRB5_KDB_DBINITED                        (-1780008434L)
+#define KRB5_KDB_ILLDIRECTION                    (-1780008433L)
+#define KRB5_KDB_NOMASTERKEY                     (-1780008432L)
+#define KRB5_KDB_BADMASTERKEY                    (-1780008431L)
+#define KRB5_KDB_INVALIDKEYSIZE                  (-1780008430L)
+#define KRB5_KDB_CANTREAD_STORED                 (-1780008429L)
+#define KRB5_KDB_BADSTORED_MKEY                  (-1780008428L)
+#define KRB5_KDB_CANTLOCK_DB                     (-1780008427L)
+#define KRB5_KDB_DB_CORRUPT                      (-1780008426L)
+#define KRB5_KDB_BAD_VERSION                     (-1780008425L)
+#define KRB5_KDB_BAD_SALTTYPE                    (-1780008424L)
+#define KRB5_KDB_BAD_ENCTYPE                     (-1780008423L)
+#define KRB5_KDB_BAD_CREATEFLAGS                 (-1780008422L)
+#define ERROR_TABLE_BASE_kdb5 (-1780008448L)
+
+extern struct error_table et_kdb5_error_table;
+
+#if (defined(unix) || defined(_AIX)) && !(defined(__MACH__) && defined(__APPLE__))
+/* for compatibility with older versions... */
+extern void initialize_kdb5_error_table ();
+#define init_kdb5_err_tbl initialize_kdb5_error_table
+#define kdb5_err_base ERROR_TABLE_BASE_kdb5
+#else
+#define initialize_kdb5_error_table()
+#endif
+/*
+ * :::MITKerberosLib:GSSKerberos5Sources_9:include:kv5m_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <KerberosComErr/KerberosComErr.h>
+#else
+#include <com_err.h>
+#endif
+
+#define KV5M_NONE                                (-1760647424L)
+#define KV5M_PRINCIPAL                           (-1760647423L)
+#define KV5M_DATA                                (-1760647422L)
+#define KV5M_KEYBLOCK                            (-1760647421L)
+#define KV5M_CHECKSUM                            (-1760647420L)
+#define KV5M_ENCRYPT_BLOCK                       (-1760647419L)
+#define KV5M_ENC_DATA                            (-1760647418L)
+#define KV5M_CRYPTOSYSTEM_ENTRY                  (-1760647417L)
+#define KV5M_CS_TABLE_ENTRY                      (-1760647416L)
+#define KV5M_CHECKSUM_ENTRY                      (-1760647415L)
+#define KV5M_AUTHDATA                            (-1760647414L)
+#define KV5M_TRANSITED                           (-1760647413L)
+#define KV5M_ENC_TKT_PART                        (-1760647412L)
+#define KV5M_TICKET                              (-1760647411L)
+#define KV5M_AUTHENTICATOR                       (-1760647410L)
+#define KV5M_TKT_AUTHENT                         (-1760647409L)
+#define KV5M_CREDS                               (-1760647408L)
+#define KV5M_LAST_REQ_ENTRY                      (-1760647407L)
+#define KV5M_PA_DATA                             (-1760647406L)
+#define KV5M_KDC_REQ                             (-1760647405L)
+#define KV5M_ENC_KDC_REP_PART                    (-1760647404L)
+#define KV5M_KDC_REP                             (-1760647403L)
+#define KV5M_ERROR                               (-1760647402L)
+#define KV5M_AP_REQ                              (-1760647401L)
+#define KV5M_AP_REP                              (-1760647400L)
+#define KV5M_AP_REP_ENC_PART                     (-1760647399L)
+#define KV5M_RESPONSE                            (-1760647398L)
+#define KV5M_SAFE                                (-1760647397L)
+#define KV5M_PRIV                                (-1760647396L)
+#define KV5M_PRIV_ENC_PART                       (-1760647395L)
+#define KV5M_CRED                                (-1760647394L)
+#define KV5M_CRED_INFO                           (-1760647393L)
+#define KV5M_CRED_ENC_PART                       (-1760647392L)
+#define KV5M_PWD_DATA                            (-1760647391L)
+#define KV5M_ADDRESS                             (-1760647390L)
+#define KV5M_KEYTAB_ENTRY                        (-1760647389L)
+#define KV5M_CONTEXT                             (-1760647388L)
+#define KV5M_OS_CONTEXT                          (-1760647387L)
+#define KV5M_ALT_METHOD                          (-1760647386L)
+#define KV5M_ETYPE_INFO_ENTRY                    (-1760647385L)
+#define KV5M_DB_CONTEXT                          (-1760647384L)
+#define KV5M_AUTH_CONTEXT                        (-1760647383L)
+#define KV5M_KEYTAB                              (-1760647382L)
+#define KV5M_RCACHE                              (-1760647381L)
+#define KV5M_CCACHE                              (-1760647380L)
+#define KV5M_PREAUTH_OPS                         (-1760647379L)
+#define KV5M_SAM_CHALLENGE                       (-1760647378L)
+#define KV5M_SAM_KEY                             (-1760647377L)
+#define KV5M_ENC_SAM_RESPONSE_ENC                (-1760647376L)
+#define KV5M_SAM_RESPONSE                        (-1760647375L)
+#define KV5M_PREDICTED_SAM_RESPONSE              (-1760647374L)
+#define KV5M_PASSWD_PHRASE_ELEMENT               (-1760647373L)
+#define KV5M_GSS_OID                             (-1760647372L)
+#define KV5M_GSS_QUEUE                           (-1760647371L)
+#define ERROR_TABLE_BASE_kv5m (-1760647424L)
+
+extern struct error_table et_kv5m_error_table;
+
+#if (defined(unix) || defined(_AIX)) && !(defined(__MACH__) && defined(__APPLE__))
+/* for compatibility with older versions... */
+extern void initialize_kv5m_error_table ();
+#define init_kv5m_err_tbl initialize_kv5m_error_table
+#define kv5m_err_base ERROR_TABLE_BASE_kv5m
+#else
+#define initialize_kv5m_error_table()
+#endif
+/*
+ * :::MITKerberosLib:GSSKerberos5Sources_9:include:asn1_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <KerberosComErr/KerberosComErr.h>
+#else
+#include <com_err.h>
+#endif
+
+#define ASN1_BAD_TIMEFORMAT                      (1859794432L)
+#define ASN1_MISSING_FIELD                       (1859794433L)
+#define ASN1_MISPLACED_FIELD                     (1859794434L)
+#define ASN1_TYPE_MISMATCH                       (1859794435L)
+#define ASN1_OVERFLOW                            (1859794436L)
+#define ASN1_OVERRUN                             (1859794437L)
+#define ASN1_BAD_ID                              (1859794438L)
+#define ASN1_BAD_LENGTH                          (1859794439L)
+#define ASN1_BAD_FORMAT                          (1859794440L)
+#define ASN1_PARSE_ERROR                         (1859794441L)
+#define ASN1_BAD_GMTIME                          (1859794442L)
+#define ASN1_MISMATCH_INDEF                      (1859794443L)
+#define ASN1_MISSING_EOC                         (1859794444L)
+#define ERROR_TABLE_BASE_asn1 (1859794432L)
+
+extern struct error_table et_asn1_error_table;
+
+#if (defined(unix) || defined(_AIX)) && !(defined(__MACH__) && defined(__APPLE__))
+/* for compatibility with older versions... */
+extern void initialize_asn1_error_table ();
+#define init_asn1_err_tbl initialize_asn1_error_table
+#define asn1_err_base ERROR_TABLE_BASE_asn1
+#else
+#define initialize_asn1_error_table()
+#endif
diff --git a/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/win-mac.h b/mac/CommonKClient/mac_kclient3/Headers/Kerberos5/win-mac.h
new file mode 100755 (executable)
index 0000000..ef5c8cc
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * type functions split out of here to make things look nicer in the
+ * various include files which need these definitions, as well as in
+ * the util/ directories.
+ */
+
+#ifndef _KRB5_WIN_MAC_H
+#define _KRB5_WIN_MAC_H
+
+#if (defined(_MSDOS) || defined(_WIN32))
+/* 
+ * Machine-type definitions: PC Clone 386 running Microloss Windows
+ */
+
+#define ID_READ_PWD_DIALOG  10000
+#define ID_READ_PWD_PROMPT  10001
+#define ID_READ_PWD_PROMPT2 10002
+#define ID_READ_PWD_PWD     10003
+
+#ifdef RES_ONLY
+
+#define APSTUDIO_HIDDEN_SYMBOLS
+#include <windows.h>
+
+#else
+
+#if defined(_MSDOS)
+       /* Windows 16 specific */
+#define BITS16
+#define SIZEOF_INT      2
+#define SIZEOF_SHORT    2
+#define SIZEOF_LONG     4
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV __far __export __pascal
+#define KRB5_CALLCONV_C __far __export __cdecl
+#define KRB5_EXPORTVAR __far __export
+#define KRB5_DLLIMP
+#endif /* !KRB5_CALLCONV */
+
+#include <windows.h>
+       
+/*
+ * The following defines are needed to make <windows.h> work
+ * in stdc mode (/Za flag). Winsock.h needs <windows.h>.
+ */
+#ifndef FAR
+#define FAR     __far
+#define NEAR    __near
+#endif
+
+#ifndef _far
+#define _far    __far
+#define _near   __near
+#define _pascal __pascal
+#define _cdecl  __cdecl
+#define _huge   __huge
+#endif
+
+#else
+       /* Windows 32 specific */
+#define SIZEOF_INT      4
+#define SIZEOF_SHORT    2
+#define SIZEOF_LONG     4
+
+#include <windows.h>   /* always include this here, to get correct FAR and NEAR */
+
+#define HAVE_LABS
+
+#ifndef KRB5_CALLCONV
+#  ifdef _MSC_VER
+#    ifdef KRB5_DLL_FILE
+#      define KRB5_DLLIMP __declspec(dllexport)
+#    else
+#      define KRB5_DLLIMP __declspec(dllimport)
+#    endif
+#    ifdef GSS_DLL_FILE
+#      define GSS_DLLIMP __declspec(dllexport)
+#    else
+#      define GSS_DLLIMP __declspec(dllimport)
+#    endif
+#  else /* !_MSC_VER */
+#    define KRB5_DLLIMP
+#    define GSS_DLLIMP
+#  endif
+#  define KRB5_CALLCONV __stdcall
+#  define KRB5_CALLCONV_C __cdecl
+#  define KRB5_EXPORTVAR
+#endif /* !KRB5_CALLCONV */
+
+#endif /* _MSDOS */
+
+#ifndef KRB5_SYSTYPES__
+#define KRB5_SYSTYPES__
+#include <sys/types.h>
+typedef unsigned long  u_long;      /* Not part of sys/types.h on the pc */
+typedef unsigned int   u_int;
+typedef unsigned short u_short;
+typedef unsigned char  u_char;
+#endif /* KRB5_SYSTYPES__ */
+
+#define MAXHOSTNAMELEN  512
+#ifndef MAXPATHLEN
+#define MAXPATHLEN      256            /* Also for Windows temp files */
+#endif
+
+#define HAVE_NETINET_IN_H
+#define MSDOS_FILESYSTEM
+#define HAVE_STRING_H 
+#define HAVE_SRAND
+#define HAVE_ERRNO
+#define HAVE_STRDUP
+#define NO_USERID
+#define NO_PASSWORD
+
+#define WM_KERBEROS5_CHANGED "Kerberos5 Changed"
+#ifdef KRB4
+#define WM_KERBEROS_CHANGED "Kerberos Changed"
+#endif
+
+/* Kerberos Windows initialization file */
+#define KERBEROS_INI    "kerberos.ini"
+#ifdef CYGNUS
+#define KERBEROS_HLP    "kerbnet.hlp"
+#else
+#define KERBEROS_HLP   "krb5clnt.hlp"
+#endif
+#define INI_DEFAULTS    "Defaults"
+#define   INI_USER        "User"          /* Default user */
+#define   INI_INSTANCE    "Instance"      /* Default instance */
+#define   INI_REALM       "Realm"         /* Default realm */
+#define   INI_POSITION    "Position"
+#define   INI_OPTIONS     "Options"
+#define   INI_DURATION    "Duration"   /* Ticket duration in minutes */
+#define INI_EXPIRATION  "Expiration" /* Action on expiration (alert or beep) */
+#define   INI_ALERT       "Alert"
+#define   INI_BEEP        "Beep"
+#define   INI_FILES       "Files"
+#ifdef KRB4
+#define   INI_KRB_CONF    "krb.conf"     /* Location of krb.conf file */
+#define   DEF_KRB_CONF    "krb.conf"      /* Default name for krb.conf file */
+#else
+#define INI_KRB5_CONF   "krb5.ini"     /* From k5-config.h */
+#define INI_KRB_CONF    INI_KRB5_CONF  /* Location of krb.conf file */
+#define DEF_KRB_CONF    INI_KRB5_CONF  /* Default name for krb.conf file */
+#define INI_TICKETOPTS  "TicketOptions" /* Ticket options */
+#define   INI_FORWARDABLE  "Forwardable" /* get forwardable tickets */
+#define INI_KRB_CCACHE  "krb5cc"               /* From k5-config.h */
+#endif
+#define INI_KRB_REALMS  "krb.realms"    /* Location of krb.realms file */
+#define DEF_KRB_REALMS  "krb.realms"    /* Default name for krb.realms file */
+#define INI_RECENT_LOGINS "Recent Logins"    
+#define INI_LOGIN       "Login"
+
+#define HAS_ANSI_VOLATILE
+#define HAS_VOID_TYPE
+#define KRB5_PROVIDE_PROTOTYPES
+#define HAVE_STDARG_H
+#define HAVE_SYS_TYPES_H
+#define HAVE_STDLIB_H
+
+/* This controls which encryption routines libcrypto will provide */
+#define PROVIDE_DES_CBC_MD5
+#define PROVIDE_DES_CBC_CRC
+#define PROVIDE_DES_CBC_RAW
+#define PROVIDE_DES_CBC_CKSUM
+#define PROVIDE_CRC32
+#define PROVIDE_RSA_MD4
+#define PROVIDE_RSA_MD5
+/* #define PROVIDE_DES3_CBC_SHA */
+/* #define PROVIDE_DES3_CBC_RAW */
+/* #define PROVIDE_NIST_SHA */
+
+/* Ugly. Microsoft, in stdc mode, doesn't support the low-level i/o
+ * routines directly. Rather, they only export the _<function> version.
+ * The following defines works around this problem. 
+ */
+#include <sys\types.h>
+#include <sys\stat.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
+#ifndef _WIN32
+#define O_RDONLY        _O_RDONLY
+#define O_WRONLY        _O_WRONLY
+#define O_RDWR          _O_RDWR
+#define O_APPEND        _O_APPEND
+#define O_CREAT         _O_CREAT
+#define O_TRUNC         _O_TRUNC
+#define O_EXCL          _O_EXCL
+#define O_TEXT          _O_TEXT
+#define O_BINARY        _O_BINARY
+#define O_NOINHERIT     _O_NOINHERIT
+#define stat            _stat
+#define unlink          _unlink
+#define lseek           _lseek
+#define write           _write
+#define open            _open
+#define close           _close
+#define read            _read
+#define fstat           _fstat
+#define mktemp          _mktemp
+#define dup             _dup
+
+#define getpid          _getpid
+#endif
+
+#ifdef NEED_SYSERROR
+/* Only needed by util/et/error_message.c but let's keep the source clean */
+#define sys_nerr        _sys_nerr
+#define sys_errlist     _sys_errlist
+#endif
+
+/*
+ * Functions with slightly different names on the PC
+ */
+#define strcasecmp   stricmp
+#define strncasecmp  strnicmp
+
+HINSTANCE get_lib_instance(void);
+
+#endif /* !RES_ONLY */
+
+#endif /* _MSDOS || _WIN32 */
+
+#ifdef macintosh
+
+#include <KerberosSupport/KerberosConditionalMacros.h>
+
+#define USE_LOGIN_LIBRARY
+
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#define GSS_DLLIMP
+#ifndef FAR
+#define FAR
+#endif
+#ifndef NEAR
+#define NEAR
+#endif
+
+#define SIZEOF_INT 4
+#define SIZEOF_SHORT 2
+#define HAVE_SRAND
+#define NO_PASSWORD
+#define HAVE_LABS
+/*#define ENOMEM 12*/
+#include <ctype.h>
+
+/*
+ * Which encryption routines libcrypto will provide is controlled by
+ * mac/libraries/KerberosHeaders.h.
+ */
+
+/* there is no <stat.h> for mpw */
+#ifndef __MWERKS__
+typedef unsigned long size_t;
+typedef unsigned long  mode_t;
+typedef unsigned long  ino_t;
+typedef unsigned long  dev_t;
+typedef short                  nlink_t;
+typedef unsigned long  uid_t;
+typedef unsigned long  gid_t;
+typedef long                   off_t;
+
+struct stat
+{
+       mode_t          st_mode;        /* File mode; see #define's below */
+       ino_t           st_ino;         /* File serial number */
+       dev_t           st_dev;         /* ID of device containing this file */
+       nlink_t         st_nlink;       /* Number of links */
+       uid_t           st_uid;         /* User ID of the file's owner */
+       gid_t           st_gid;         /* Group ID of the file's group */
+       dev_t           st_rdev;        /* Device type */
+       off_t           st_size;        /* File size in bytes */
+       unsigned long   st_atime;       /* Time of last access */
+       unsigned long   st_mtime;       /* Time of last data modification */
+       unsigned long   st_ctime;       /* Time of last file status change */
+       long            st_blksize;     /* Optimal blocksize */
+       long            st_blocks;      /* blocks allocated for file */
+};
+
+int stat(const char *path, struct stat *buf);
+#endif
+
+int fstat(int fildes, struct stat *buf);
+
+#define EFBIG 1000
+
+#define NOFCHMOD 1
+#define NOCHMOD 1
+#define _MACSOCKAPI_
+
+#define THREEPARAMOPEN(x,y,z) open(x,y)
+#else /* macintosh */
+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
+#endif /* macintosh */
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#endif
+#ifndef FAR
+#define FAR
+#endif
+#ifndef NEAR
+#define NEAR
+#endif
+
+#endif /* _KRB5_WIN_MAC_H */
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/KerberosComErr.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/KerberosComErr.h
new file mode 100755 (executable)
index 0000000..ec4aa66
--- /dev/null
@@ -0,0 +1 @@
+#include <KerberosComErr/com_err.h>\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/com_err.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosComErr/com_err.h
new file mode 100755 (executable)
index 0000000..7e8b030
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Header file for common error description library.
+ *
+ * Copyright 1988, Student Information Processing Board of the
+ * Massachusetts Institute of Technology.
+ *
+ * Copyright 1995 by Cygnus Support.
+ *
+ * For copyright and distribution info, see the documentation supplied
+ * with this package.
+ */
+
+#ifndef __COM_ERR_H
+
+#if defined(_MSDOS) || defined(_WIN32) || defined(macintosh)
+#include <Kerberos5/win-mac.h>
+#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
+#pragma import on
+#endif
+#endif
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#define GSS_DLLIMP
+#define KRB5_EXPORTVAR
+#endif
+
+#ifndef FAR
+#define FAR
+#define NEAR
+#endif
+
+#if defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32) || defined(macintosh)
+
+/* End-user programs may need this -- oh well */
+#ifndef HAVE_STDARG_H
+#define HAVE_STDARG_H 1
+#endif
+
+#define ET_P(x) x
+
+#else
+#define ET_P(x) ()
+#endif /* __STDC__ */
+
+#ifdef HAVE_STDARG_H
+#include <stdarg.h>
+#define        ET_STDARG_P(x) x
+#else
+#include <varargs.h>
+#define ET_STDARG_P(x) ()
+#define ET_VARARGS
+#endif
+
+typedef long errcode_t;
+typedef void (*et_old_error_hook_func) ET_P((const char FAR *, errcode_t,
+                                            const char FAR *, va_list ap));
+       
+struct error_table {
+       char const FAR * const FAR * msgs;
+       unsigned long base;
+       unsigned int n_msgs;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+KRB5_DLLIMP extern void KRB5_CALLCONV_C com_err
+       ET_STDARG_P((const char FAR *, errcode_t, const char FAR *, ...));
+KRB5_DLLIMP extern void KRB5_CALLCONV com_err_va
+       ET_P((const char FAR *whoami, errcode_t code, const char FAR *fmt,
+             va_list ap));
+KRB5_DLLIMP extern const char FAR * KRB5_CALLCONV error_message
+       ET_P((errcode_t));
+KRB5_DLLIMP extern errcode_t KRB5_CALLCONV add_error_table
+       ET_P((const struct error_table FAR *));
+KRB5_DLLIMP extern errcode_t KRB5_CALLCONV remove_error_table
+       ET_P((const struct error_table FAR *));
+
+#if !defined(_MSDOS) && !defined(_WIN32) && !defined(macintosh) && !defined(__MACH__)
+/*
+ * The display routine should be application specific.  A global hook,
+ * may cause inappropriate display procedures to be called between
+ * applications under non-Unix environments.
+ */
+
+extern et_old_error_hook_func set_com_err_hook
+       ET_P((et_old_error_hook_func));
+extern et_old_error_hook_func reset_com_err_hook
+       ET_P((void));
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(macintosh) && defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
+#pragma import reset
+#endif
+
+#define __COM_ERR_H
+#endif /* ! defined(__COM_ERR_H) */
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosDES/KerberosDES.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosDES/KerberosDES.h
new file mode 100755 (executable)
index 0000000..29e71b8
--- /dev/null
@@ -0,0 +1 @@
+/*\r * KerberosDES.h\r *\r * Copyright (C) 1987, 1988, 1989 by the Massachusetts Institute of Technology.\r * \r * Export of this software from the United States of America is assumed\r * to require a specific license from the United States Government.\r * It is the responsibility of any person or organization contemplating\r * export to obtain such a license before exporting.\r * \r * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r * distribute this software and its documentation for any purpose and\r * without fee is hereby granted, provided that the above copyright\r * notice appear in all copies and that both that copyright notice and\r * this permission notice appear in supporting documentation, and that\r * the name of M.I.T. not be used in advertising or publicity pertaining\r * to distribution of the software without specific, written prior\r * permission.  M.I.T. makes no representations about the suitability of\r * this software for any purpose.  It is provided "as is" without express\r * or implied warranty.\r * \r * Include file for the Data Encryption Standard library.\r */\r\r#ifndef __KERBEROSDES__\r#define __KERBEROSDES__\r\r#include <KerberosDES/des.h>\r\r#endif /* __KERBEROSDES__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosDES/des.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosDES/des.h
new file mode 100755 (executable)
index 0000000..04284d4
--- /dev/null
@@ -0,0 +1 @@
+/*\r * des.h\r *\r * Copyright (C) 1987, 1988, 1989 by the Massachusetts Institute of Technology.\r * \r * Export of this software from the United States of America is assumed\r * to require a specific license from the United States Government.\r * It is the responsibility of any person or organization contemplating\r * export to obtain such a license before exporting.\r * \r * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and\r * distribute this software and its documentation for any purpose and\r * without fee is hereby granted, provided that the above copyright\r * notice appear in all copies and that both that copyright notice and\r * this permission notice appear in supporting documentation, and that\r * the name of M.I.T. not be used in advertising or publicity pertaining\r * to distribution of the software without specific, written prior\r * permission.  M.I.T. makes no representations about the suitability of\r * this software for any purpose.  It is provided "as is" without express\r * or implied warranty.\r * \r * Include file for the Data Encryption Standard library.\r */\r\r/* only do the whole thing once       */\r#ifndef DES_H\r#define DES_H\r\r#include <stdio.h>\r\r#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))\r       #include <KerberosSupport/KerberosSupport.h>\r#endif\r\r#if TARGET_API_MAC_OSX\r    #include <machine/types.h>\r\r    #ifndef DES_INT32\r        #define DES_INT32 int32_t\r    #endif\r    #ifndef DES_UINT32\r        #define DES_UINT32 u_int32_t\r    #endif\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <MacTypes.h>\r\r    #ifndef DES_INT32\r        #define DES_INT32 SInt32\r    #endif\r    #ifndef DES_UINT32\r        #define DES_UINT32 UInt32\r    #endif\r#endif\r\r#if !defined(DES_INT32) || !defined(DES_UINT32)\r    #error "Unsupported platform.  Need definitions for UInt32 and SInt32."\r#endif\r\r/* There are some declarations in the system-specific header files which\r   can't be done until DES_INT32 is defined.  So they are in a macro,\r   which we expand here if defined.  */\r\r#ifdef     DECL_THAT_NEEDS_DES_INT32\rDECL_THAT_NEEDS_DES_INT32\r#endif\r\rtypedef unsigned char des_cblock[8];        /* crypto-block size */\r/* Key schedule */\rtypedef struct des_ks_struct { union { DES_INT32 pad; des_cblock _;} __; } des_key_schedule[16];\r\r#define DES_KEY_SZ         (sizeof(des_cblock))\r#define DES_ENCRYPT        1\r#define DES_DECRYPT   0\r\r#ifndef NCOMPAT\r#define C_Block des_cblock\r#define Key_schedule des_key_schedule\r#define ENCRYPT DES_ENCRYPT\r#define DECRYPT DES_DECRYPT\r#define KEY_SZ DES_KEY_SZ\r#define mit_string_to_key des_string_to_key\r#define string_to_key des_string_to_key\r#define read_pw_string des_read_pw_string\r#define random_key des_random_key\r#define pcbc_encrypt des_pcbc_encrypt\r#define key_sched des_key_sched\r#define cbc_encrypt des_cbc_encrypt\r#define cbc_cksum des_cbc_cksum\r#define C_Block_print des_cblock_print\r#define quad_cksum des_quad_cksum\rtypedef struct des_ks_struct bit_64;\r#endif\r\r#define des_cblock_print(x) des_cblock_print_file(x, stdout)\r\r/* Function declarations */\r\r#ifdef __cplusplus\rextern "C" {\r#endif /* __cplusplus */\r\r/* Macintosh CFM-68K magic incantation */\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r       #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r#if TARGET_RT_MAC_CFM\r# define DESLibraryIsPresent() ((Ptr) (des_cbc_encrypt) != (Ptr) (kUnresolvedCFragSymbolAddress))\r#elif TARGET_CPU_68K\r#   pragma d0_pointers on\r#endif\r\rint des_cbc_encrypt(des_cblock *in, \r                    des_cblock *out, \r                    long length, \r                    des_key_schedule schedule, \r                    des_cblock ivec, \r                    int encrypt);\r\rvoid des_3cbc_encrypt(des_cblock *in,\r                      des_cblock *out,\r                      long length,\r                      des_key_schedule ks1, \r                      des_key_schedule ks2, \r                      des_key_schedule ks3, \r                      des_cblock ivec, \r                      int encrypt);\r                    \runsigned long des_cbc_cksum(des_cblock *in, \r                            des_cblock *out, \r                            long length, \r                            des_key_schedule schedule, \r                            des_cblock *ivec);\r\rint des_ecb_encrypt(des_cblock *in, \r                    des_cblock *out, \r                    des_key_schedule schedule, \r                    int encrypt);\r\rvoid des_3ecb_encrypt(des_cblock *in, \r                      des_cblock *out, \r                      des_key_schedule ks1, \r                      des_key_schedule ks2, \r                      des_key_schedule ks3, \r                      int encrypt);\r                      \rvoid des_fixup_key_parity(register des_cblock key);\rint des_check_key_parity(register des_cblock key);\r\rint des_pcbc_encrypt(des_cblock *in, \r                     des_cblock *out, \r                     long length, \r                     des_key_schedule schedule, \r                     des_cblock ivec, \r                     int encrypt);\r\rint make_key_sched(des_cblock *key, des_key_schedule schedule);\r\rint des_key_sched(des_cblock k, des_key_schedule schedule);\r\rint des_new_random_key(des_cblock key);\rvoid des_init_random_number_generator(des_cblock key);\rvoid des_set_random_generator_seed(des_cblock key);\rvoid des_set_sequence_number(des_cblock new_sequence_number);\rvoid des_generate_random_block(des_cblock block);\r\runsigned long des_quad_cksum(unsigned char *in,\r                             unsigned long *out,\r                             long length,\r                             int out_count,\r                             des_cblock *c_seed);\r\rint des_random_key(des_cblock *key);\r\rint des_read_password(des_cblock *k, char *prompt, int verify);\rint des_read_pw_string(char *s, int max, char *prompt, int verify);\r\rint  des_string_to_key(char *str, des_cblock key);\rvoid afs_string_to_key(char *str, char *cell, des_cblock key);\r\rvoid des_cblock_print_file(des_cblock *x, FILE *fp);\r\rint des_is_weak_key(des_cblock key);\r\rchar *des_crypt(const char *buf, const char *salt);\rchar *des_fcrypt(const char *buf, const char *salt, char *ret);\r\rint des_set_key(des_cblock *key, des_key_schedule schedule);\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers reset\r#endif\r\r/* Macintosh CFM-68K magic incantation */\r#if PRAGMA_STRUCT_ALIGN\r    #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif /* __cplusplus */\r\r#endif /* DES_H */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLLoginLogoutNotification.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLLoginLogoutNotification.h
new file mode 100755 (executable)
index 0000000..96346b8
--- /dev/null
@@ -0,0 +1 @@
+/*\r * API for Kerberos Login and Logout Notification plugins\r */\r \r#ifndef KLLoginLogoutNotification_h_\r#define KLLoginLogoutNotification_h_\r\r#include <KerberosLogin/KerberosLogin.h>\r\r/* API Versions */\r\renum {\r    kKLN_APIVersion_1                               = 1,\r   kKLN_APIVersion_Current                 = kKLN_APIVersion_1\r};\r\r/* File types */\r\rconst OSType kKLN_PluginFileType = FOUR_CHAR_CODE ('LNot');\r\r/* Login types */\r\renum {\r       kKLN_DialogLogin                                = 1,\r   kKLN_PasswordLogin                              = 2\r};\r\r/* Types */\r\rtypedef UInt32 KLN_APIVersion;\rtypedef UInt32 KLN_LoginType;\r\r/* Function prototypes */\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#pragma export on\r\rKLStatus KerberosLoginNotification_InitializePlugin (\r KLN_APIVersion          inAPIVersion);\r\rKLStatus KerberosLoginNotification_Login (\r     KLN_LoginType           inLoginType,\r   const char*                     inCredentialsCache);\r\rvoid KerberosLoginNotification_Logout (\r  const char*                     inCredentialsCache);\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* KLLoginLogoutNotification_h_ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLPrincipalTranslation.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KLPrincipalTranslation.h
new file mode 100755 (executable)
index 0000000..6023e93
--- /dev/null
@@ -0,0 +1 @@
+/*\r * API for Kerberos Login Principal Translation plugins\r */\r \r#include <KerberosLogin/KerberosLogin.h>\r \r#ifndef KLPrincipalTranslation_h_\r#define KLPrincipalTranslation_h_\r\r/* API Versions */\r\renum {\r   kKLPT_APIVersion_1                              = 1,\r   kKLPT_APIVersion_Current                = kKLPT_APIVersion_1\r};\r\r/* File types */\r\rconst OSType kKLPT_PluginFileType = FOUR_CHAR_CODE ('PTrn');\r\r/* Types */\r\rtypedef UInt32    KLPT_APIVersion;\r\r/* Function prototypes */\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#pragma export on\r\rKLStatus KerberosLoginPrincipalTranslation_InitializePlugin (\r  KLPT_APIVersion         inAPIVersion);\r\rKLStatus KerberosLoginPrincipalTranslation_TranslatePrincipal (\r        const char*             inName,\r        const char*             inInstance,\r    const char*             inRealm,\r       const char**    outName,\r       const char**    outInstance,\r   const char**    outRealm,\r      KLBoolean*              outChanged);\r\rvoid KerberosLoginPrincipalTranslation_ReleasePrincipal (\r        char*   inName,\r        char*   inInstance,\r    char*   inRealm);\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* KLPrincipalTranslation_h_ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KerberosLogin.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KerberosLogin.h
new file mode 100755 (executable)
index 0000000..6255abf
--- /dev/null
@@ -0,0 +1 @@
+/*\r * KerberosLogin.h\r *\r * $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosLogin/KerberosLogin.h,v 1.2 2001/12/04 02:05:52 rjs3 Exp $\r *\r */\r \r/* \r * This file contains part of the login library API. See\r * <http://web.mit.edu/macdev/mit/lib/Login/doc/API.html>\r * for API documentation\r */\r\r#ifndef __KERBEROSLOGIN__\r#define __KERBEROSLOGIN__\r\r\r/*\r *\r * Constants\r *\r */\r\r/* Kerberos versions */\renum KLEKerberosVersion {\r       kerberosVersion_Any             = 0,\r   kerberosVersion_V4              = 1,\r   kerberosVersion_V5              = 2,\r   kerberosVersion_All             = 0xFFFFFFFF\r};\r\r/* dialog identifier constants */\renum KLEDialogIdentifiers {\r loginLibrary_LoginDialog,\r      loginLibrary_OptionsDialog,\r    loginLibrary_ChangePasswordDialog,\r     loginLibrary_ProgressDialog,\r   loginLibrary_PrompterDialog\r};\r\r/* Login dialog items */\renum KLELoginDialogItems {\r    loginDialog_Username,\r  loginDialog_Password,\r  loginDialog_Realm,\r     loginDialog_TicketLifetime,\r    loginDialog_ForwardableTicket\r};\r\r/* Password dialog items */\renum KLEChangePasswordDialogItems {\r      changePasswordDialog_OldPassword,\r      changePasswordDialog_NewPassword,\r      changePasswordDialog_VerifyPassword\r};\r\r/* Option identifier constants */\renum KLEDefaultLoginOptions {\r        /* Dialog state options */\r     loginOption_LoginName                    = 'name',\r     loginOption_LoginInstance                = 'inst',\r     loginOption_AdvancedLoginMode            = 'adv ',\r     loginOption_ShowTicketLifetime           = 'life',\r     loginOption_ShowForwardableTicket        = 'forw',\r     loginOption_ShowProxiableTicket          = 'prox',\r     \r       /* Initial values and ranges */\r        loginOption_RememberPrincipal            = 'prin',\r     loginOption_RememberExtras               = 'extr',\r     \r       loginOption_MinimalTicketLifetime        = '-lif',\r     loginOption_MaximalTicketLifetime        = '+lif',\r     loginOption_DefaultTicketLifetime        = '0lif',\r     loginOption_LongTicketLifetimeDisplay    = 'hms ',\r     \r       loginOption_DefaultForwardableTicket     = '0fwd',\r     loginOption_DefaultProxiableTicket               = '0prx'\r};\r\r/* Login mode identifier constants (for loginOption_AdvancedLoginMode) */\renum KLELoginMode {\r    loginMode_Basic                                                  = 1,\r  loginMode_Advanced                                               = 2\r};\r\r/* Realm list constants */\renum KLERealmListIndexes {\r realmList_Start         = 0,\r   realmList_End           = 0xFFFF\r};\r\r#define klFirstError       19276\r#define klLastError               19876\r\r/* Error codes */\renum KLEStatus {\r      klNoErr                                                                         =       0,\r\r    /* parameter errors */\r klParameterErr                                                          =       19276,\r klBadPrincipalErr,\r     klBadPasswordErr,\r      klBadLoginOptionsErr,\r  klInvalidVersionErr,\r   \r       /* Runtime Login errors */\r     klUserCanceledErr                                                       =       19476,\r klMemFullErr,\r  klPreferencesReadErr,\r  klPreferencesWriteErr,\r klV5InitializationFailedErr,\r   klPrincipalDoesNotExistErr,\r    klSystemDefaultDoesNotExistErr,\r        klCredentialsExpiredErr,\r       klNoRealmsErr,\r klRealmDoesNotExistErr,\r        klNoCredentialsErr,\r    klCredentialsBadAddressErr,\r    klCacheDoesNotExistErr,\r        \r       /* Get/SetKerberosOption errors */\r     klBufferTooSmallErr                                                     =       19376,\r klBufferTooLargeErr,\r   klInvalidOptionErr,\r    klBadOptionValueErr,\r   \r       /* Password changing errors */\r klPasswordMismatchErr                                           =       19576,\r klInsecurePasswordErr,\r klPasswordChangeFailedErr,\r     \r       /* Dialog errors */\r    klDialogDoesNotExistErr                                         =       19676,\r klDialogAlreadyExistsErr,\r      klNotInForegroundErr,\r  klNoAppearanceErr,\r     klFatalDialogErr,\r      klCarbonUnavailableErr,\r        \r       /* Login IPC errors */\r klCantContactServerErr                                          =       19776\r\r};\r\r#ifndef rez  /* This stuff will confuse rez */\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <Carbon/Carbon.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON \r    #include <Dialogs.h>\r    #include <Events.h>\r    #include <MacTypes.h>\r#else\r  #error "Unknown OS"\r#endif\r\r#if PRAGMA_ONCE\r#pragma once\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r   #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r\r/*\r *\r * Types\r *\r */\r \rtypedef        OSStatus        KLStatus;                                       /* one of KLEStatus                                                                                                                                     */\rtypedef      UInt32          KLKerberosVersion;                      /* one of KLEKerberosVersion                                                                                                                    */\rtypedef      UInt32          KLDefaultLoginOption;           /* one of KLEDefaultLoginOptions                                                                                                                */\rtypedef      UInt32          KLLoginMode;                            /* one of KLELoginMode                                                                                                                                  */\rtypedef      UInt32          KLDialogIdentifier;                     /* one of KLEDialogIdentifiers                                                                                                                  */\rtypedef      UInt32          KLIndex;                                        /* index (used for the realm list)                                                                                                              */\rtypedef      UInt32          KLLifetime;                                     /* Lifetime in seconds                                                                                                                                  */\rtypedef      UInt32          KLTime;                                         /* Unix time (seconds since 1/1/1970 00:00:00 GMT)                                                                              */\rtypedef      UInt32          KLSize;                                         /* size of a buffer (KLG/SetDefaultLoginOptions) or realm list (CountKerberosRealms)    */\rtypedef      UInt32          KLRefCon;                                       /* application ref con                                                                                                                                  */\rtypedef      Boolean         KLBoolean;                                      /* true or false!                                                                                                                                               */\rtypedef      SInt16          KLSInt16;                                       /* used for Darwin-compat for KLApplicationOptions                                                                              */\r\r/* Callback API for Kerberos Login event filter */\r/* Must be the same as an Idle Library event filter */\r/* Callback API for Event handler proc for idle loop */\rtypedef CALLBACK_API (Boolean, KLEventFilterProcPtr) (const EventRecord *theEvent, KLRefCon appData);\r\r/* Procinfo for Login Library event filter */\renum {\r      uppKLEventFilterProcInfo = kPascalStackBased |\r         RESULT_SIZE (sizeof (Boolean)) |\r               STACK_ROUTINE_PARAMETER (1, SIZE_CODE (sizeof (const EventRecord *))) |\r                STACK_ROUTINE_PARAMETER (2, SIZE_CODE (sizeof (KLRefCon)))\r};\r\r#if !TARGET_API_MAC_CARBON\r      /* UPP for Kerberos Login event filter */\r      typedef STACK_UPP_TYPE (KLEventFilterProcPtr) KLEventFilterUPP;\r        \r       #define NewKLEventFilterProc(userRoutine)                       \\r              (KLEventFilterUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppKLEventFilterProcInfo, GetCurrentArchitecture())\r\r   /* How to call the event Handler UPPs */\r       #define CallKLEventFilterProc(userRoutine, theEvent, appData)                   \\r              ((Boolean)CALL_TWO_PARAMETER_UPP ((userRoutine), uppKLEventFilterProcInfo, theEvent, appData))\r\r#else\r  typedef KLEventFilterProcPtr KLEventFilterUPP;\r \r       #define NewKLEventFilterProc(userRoutine)                       \\r              userRoutine\r\r   #define CallKLEventFilterProc(userRoutine, theEvent, appData)                   \\r              ((userRoutine) (theEvent, appData))\r#endif\r\r/* Application options */\rtypedef struct {\r KLEventFilterUPP        eventFilter;\r   KLRefCon                        eventFilterAppData;\r    KLSInt16                        realmsPopupMenuID;\r     KLSInt16                        loginModeMenuID;\r} KLApplicationOptions;\r\r/* Principal information */\rstruct OpaqueKLPrincipal;\rtypedef struct OpaqueKLPrincipal        * KLPrincipal;\r\r/* Login Options */\rstruct OpaqueKLLoginOptions;\rtypedef struct OpaqueKLLoginOptions    * KLLoginOptions;\r\r\r/*\r *\r * Functions\r *\r */\r\r/* Kerberos Login high-level API */\rKLStatus KLAcquireTickets (                          \r               KLPrincipal               inPrincipal, \r                KLPrincipal              *outPrincipal, \r               char                    **outCredCacheName);\r\rKLStatus KLAcquireNewTickets (\r           KLPrincipal       inPrincipal, \r                KLPrincipal      *outPrincipal, \r               char                    **outCredCacheName);\r\rKLStatus KLDestroyTickets (KLPrincipal inPrincipal);\r\rKLStatus KLChangePassword (KLPrincipal inPrincipal);\r\r\r/* Kerberos Login dialog low level functions */\r\rKLStatus KLAcquireTicketsWithPassword (\r            KLPrincipal               inPrincipal,\r         KLLoginOptions    inLoginOptions,\r              const char               *inPassword,\r          char                    **outCredCacheName);\r\rKLStatus KLAcquireNewTicketsWithPassword (\r               KLPrincipal               inPrincipal,\r         KLLoginOptions    inLoginOptions,\r              const char               *inPassword,\r          char                    **outCredCacheName);\r\rKLStatus KLLastChangedTime (KLTime        *outLastChangedTime);\r\rKLStatus KLCacheHasValidTickets (\r               KLPrincipal                       inPrincipal,\r         KLKerberosVersion         inKerberosVersion,\r           KLBoolean                        *outFoundValidTickets,\r                KLPrincipal                      *outPrincipal,\r                char                            **outCredCacheName);\r\rKLStatus KLTicketStartTime (\r             KLPrincipal                                      inPrincipal,\r          KLKerberosVersion                        inKerberosVersion,\r            KLTime                                          *outStartTime);\r\rKLStatus KLTicketExpirationTime (\r             KLPrincipal                      inPrincipal,\r          KLKerberosVersion        inKerberosVersion,\r            KLTime                          *outExpirationTime);\r     \rKLStatus KLSetSystemDefaultCache (KLPrincipal inPrincipal);\r\rKLStatus KLHandleError (\r               KLStatus                                inError,\r               KLDialogIdentifier              inDialogIdentifier,\r            Boolean                                 inShowAlert);\r\rKLStatus KLGetErrorString (\r             KLStatus                  inError,\r             char                    **outErrorString);\r\rKLStatus KLCancelAllDialogs (void);\r\r/* Kerberos change password dialog low level functions */\r\rKLStatus KLChangePasswordWithPasswords (\r           KLPrincipal              inPrincipal,\r          const char              *inOldPassword,\r                const char              *inNewPassword);\r\r/* Application Configuration functions */\r\rKLStatus KLSetApplicationOptions (const KLApplicationOptions *inAppOptions);\r\rKLStatus KLGetApplicationOptions (KLApplicationOptions *outAppOptions);\r\r\r/* Library configuration functions */\rKLStatus KLGetDefaultLoginOption (     \r             const KLDefaultLoginOption       inOption,\r             void                                            *ioBuffer,\r             KLSize                                          *ioBufferSize);\r\rKLStatus KLSetDefaultLoginOption (\r            const KLDefaultLoginOption       inOption,\r             const void                                      *inBuffer,\r             const KLSize                             inBufferSize);\r\r/* Realm configuration functions */\r\rKLStatus KLFindKerberosRealmByName (\r             const char              *inRealmName,\r          KLIndex                 *outIndex);\r\rKLStatus KLGetKerberosRealm (\r             KLIndex                   inIndex,\r             char                    **outRealmName);\r\rKLStatus KLSetKerberosRealm (\r                KLIndex                  inIndex,\r              const char              *inRealmName);\r\rKLStatus KLRemoveKerberosRealm (UInt32 inIndex);\r\rKLStatus KLInsertKerberosRealm (\r             KLIndex                  inInsertBeforeIndex,\r          const char              *inRealmName);\r         \rKLStatus KLRemoveAllKerberosRealms (void);\r            \rKLSize KLCountKerberosRealms (void);\r        \rKLStatus KLGetKerberosDefaultRealm(KLIndex *outIndex);\r     \rKLStatus KLGetKerberosDefaultRealmByName (char **outRealmName);\r        \rKLStatus KLSetKerberosDefaultRealm (KLIndex inIndex);\r        \rKLStatus KLSetKerberosDefaultRealmByName (const char *inRealm);\r\r/* KLPrincipal functions */\r\rKLStatus KLCreatePrincipalFromTriplet(\r               const char              *inName,\r               const char              *inInstance,\r           const char              *inRealm,\r              KLPrincipal     *outPrincipal);\r\rKLStatus KLCreatePrincipalFromString(\r         const char                              *inFullPrincipal,\r              KLKerberosVersion                inKerberosVersion,\r            KLPrincipal                             *outPrincipal);\r    \rKLStatus KLGetTripletFromPrincipal(\r               KLPrincipal               inPrincipal,\r         char                    **outName,\r             char                    **outInstance,\r         char                    **outRealm);\r\rKLStatus KLGetStringFromPrincipal(\r               KLPrincipal                       inPrincipal,\r         KLKerberosVersion         inKerberosVersion,\r           char                            **outFullPrincipal);\r\rKLStatus KLGetDisplayStringFromPrincipal(\r                KLPrincipal                       inPrincipal,\r         KLKerberosVersion         inKerberosVersion,\r           char                            **outFullPrincipal);\r\rKLStatus KLComparePrincipal(\r             KLPrincipal              inFirstPrincipal,\r             KLPrincipal              inSecondPrincipal,\r            KLBoolean               *outAreEquivalent);\r\rKLStatus KLDisposePrincipal(KLPrincipal inPrincipal);\r\r/* KLLoginOptions functions */\r\rKLStatus KLCreateLoginOptions (KLLoginOptions       *outOptions);\r\rKLStatus KLLoginOptionsSetTicketLifetime (\r              KLLoginOptions  ioOptions,\r             KLLifetime              inTicketLifetime);\r\rKLStatus KLLoginOptionsSetForwardable (\r            KLLoginOptions  ioOptions,\r             KLBoolean               inForwardable);\r                \rKLStatus KLLoginOptionsSetProxiable (\r         KLLoginOptions  ioOptions,\r             KLBoolean               inProxiable);\r          \rKLStatus KLDisposeLoginOptions(KLLoginOptions ioOptions);\r\r\r/* Misc function */\r\rKLStatus KLDisposeString(char *inStringToDispose);\r\r#if PRAGMA_STRUCT_ALIGN\r  #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* Rez */       \r\r#endif /* __KERBEROSLOGIN__ */\r\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosManager/KerberosManagerLib.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosManager/KerberosManagerLib.h
new file mode 100755 (executable)
index 0000000..d390200
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Export of this software from the United States of America may require a\r * specific license from the United States Government.  It is the\r * responsibility of any person or organization contemplating export to\r * obtain such a license before exporting.\r * \r * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute\r * this software and its documentation for any purpose and without fee is\r * hereby granted, provided that the above copyright notice appear in all\r * copies and that both that copyright notice and this permission notice\r * appear in supporting documentation, and that the name of M.I.T. not be\r * used in advertising or publicity pertaining to distribution of the\r * software without specific, written prior permission.  Furthermore if you\r * modify this software you must label your software as modified software\r * and not distribute it in such a fashion that it might be confused with\r * the original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosManager/KerberosManagerLib.h,v 1.2 2001/12/04 02:05:53 rjs3 Exp $ */\r\r#pragma once\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <Carbon/Carbon.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <MacTypes.h>\r    #include <Files.h>\r    #include <Processes.h>\r#else\r    #error "Unknown OS"\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r/*\r * KMAE_SendQuitApplication\r *\r * Send quit event to Kerberos Manager.\r *\r */\r\rOSStatus\rKMAE_SendQuitApplication (Boolean waitForAEReply);\r\r/*\r * KMAE_SendOpenApplication\r *\r * Send open event to Kerberos Manager. This will launch Kerberos Manager.  Kerberos\r * Manager could display an error dialog that requires the user's response if Kerb for\r * the Mac isn't installed properly, but no AE reply is sent about this.\r */\r \rOSStatus\rKMAE_SendOpenApplication (Boolean waitForAEReply);\r\r/*\r * KMAE_SendOpenApplicationFSSpec\r *\r * Send open event to Kerberos Manager specified by inKMFileSpec.\r * This will launch Kerberos Manager.  Kerberos Manager could display\r * an error dialog that requires the user's response if Kerb for\r * the Mac isn't installed properly, but no AE reply is sent about this.\r */\r \rOSStatus\rKMAE_SendOpenApplicationFSSpec (FSSpec *inKMFileSpec, Boolean waitForAEReply);\r\r/*\r * KMAE_SendLogin\r *\r * Tell Kerberos Manager to display login dialog (no AE replies right now).\r * Kerberos Manager will be launched if necessary.\r */\r\rOSStatus\rKMAE_SendLogin (Boolean waitForAEReply);\r\r/*\r * IsKerberosManagerRunning\r *\r * Determine if Kerberos Manager is running\r */\r\r/*\r * KMAE_SendLoginFSSpec\r *\r * Tell Kerberos Manager specified by inKmFileSpec to display login dialog \r * (no AE replies right now) Kerberos Manager will be launched if necessary.\r *\r */\r\rOSStatus\rKMAE_SendLoginFSSpec (FSSpec *inKMFileSpec, Boolean waitForAEReply);\r\r/*\r   IsKerberosManagerRunning()\r\r   Return true if KM is running, and fills out outPSN if the pointer is non-null.\r   Return false if KM is not running, and outPSN is unchanged.\r*/\r\rBoolean\rIsKerberosManagerRunning (ProcessSerialNumber *outPSN);\r\r/*\r   FindKerberosManagerInControlPanels()\r   \r   Uses IterateDirectory from MoreFiles to search the Control\r   Panels folder for copies of Kerberos Manager.  If it finds one, returns true and\r   fills out *kmSpec.  If it doesn't find one or an error occurs, returns false\r   and *kmSpec is unchanged.\r\r */\r\rBoolean\rFindKerberosManagerInControlPanels(FSSpec *kmSpec);\r\r/*\r   KMAE_FindTargetKerberosManager()\r   \r   Searches the startup volume to find the Kerberos Manager that would receive\r   AppleEvents if any of the KerberosManagerLib functions that send AEs were called.\r   First checks to see if KM is running, and returns the FSSpec of that one if it is.\r   Next looks in the Control Panels Folder.  Finally it searches the drive for\r   a copy.\r   \r   If a Kerberos Manager is found, returns true and fills out *kmSpec. \r   If it doesn't find one or an error occurs, returns false and *kmSpec is unchanged.\r   \r   If the hard drive catalog changes during the search, continues anyway.\r*/\r\rBoolean\rKMAE_FindTargetKerberosManager(FSSpec *kmSpec);\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r/*\r * Constants\r */\r\renum {\r     kKerberosManagerClass           = FOUR_CHAR_CODE ('KrbM')\r};\r\renum {\r   kKerberosManagerSignature       = FOUR_CHAR_CODE ('KrbM')\r};\r\renum {\r   kAELogin                        = FOUR_CHAR_CODE ('Lgin')\r};\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosPreferences/KerberosPreferences.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosPreferences/KerberosPreferences.h
new file mode 100755 (executable)
index 0000000..5446b07
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright Â© 2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosPreferences/KerberosPreferences.h,v 1.2 2001/12/04 02:05:54 rjs3 Exp $ */\r\r/* \r *\r * PreferenceLib.h -- Functions to handle Kerberos Preference file access.\r *\r */\r\r\r#ifndef __KERBEROSPREFERENCES__\r#define __KERBEROSPREFERENCES__\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON\r    #include <CoreServices/CoreServices.h>\r#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON\r    #include <MacTypes.h>\r    #include <Files.h>\r#else\r #error "Unknown OS"\r#endif\r\r#if PRAGMA_ONCE\r#pragma once\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r   #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r/* ************************************************ */\r/* Locations for where to look for preference files */\r/* ************************************************ */\renum\r{\r    kpUserPreferences                               = 0x00000001,\r  kpSystemPreferences                             = 0x00000002\r};\r\r/* ********************** */\r/* Name, Creator and Type */\r/* ********************** */\r\r#define kerberosPreferences_FileType   FOUR_CHAR_CODE ('pref')\r#define kerberosPreferences_Creator             FOUR_CHAR_CODE ('Krb ')\r#define kerberosPreferences_FileName    "\pKerberos Preferences"\r\r/* ******************* */\r/* Function prototypes */\r/* ******************* */\r\r/* ********************************************************* */\r/* Creates a valid preference file at the location specified */\r/* ********************************************************* */\rOSErr KPInitializeWithDefaultKerberosLibraryPreferences (\r     const FSSpec* prefLocation);\r\r/* ****************************************************************************** */\r/* File the array with list of preferences that match the options provided        */\r/* ****************************************************************************** */\rOSErr KPGetListOfPreferencesFiles (\r       UInt32 userSystemFlags,\r        FSSpecPtr* thePrefFiles,\r       UInt32* outNumberOfFiles);\r\r/* ********************************************************* */\r/* Free the array containing the list of preference files    */\r/* ********************************************************* */\rvoid KPFreeListOfPreferencesFiles (\r        FSSpecPtr thePrefFiles);\r\r/* ********************************************************* */\r/* Check if file exists and is readable                      */\r/* ********************************************************* */\rOSErr KPPreferencesFileIsReadable (\r  const FSSpec*   inPrefsFile);\r\r/* ********************************************************* */\r/* Check if file is writable                                 */\r/* ********************************************************* */\rOSErr KPPreferencesFileIsWritable (\r     const FSSpec*   inPrefsFile);\r\r/* ********************************************************* */\r/* Create an empty file                                      */\r/* ********************************************************* */\rOSErr KPCreatePreferencesFile (\r const FSSpec*   inPrefsFile);\r\r\r#if PRAGMA_STRUCT_ALIGN\r        #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* __KERBEROSPREFERENCES__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/KerberosProfile.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/KerberosProfile.h
new file mode 100755 (executable)
index 0000000..23f75cf
--- /dev/null
@@ -0,0 +1 @@
+#include <KerberosProfile/profile.h>\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/profile.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosProfile/profile.h
new file mode 100755 (executable)
index 0000000..af8f252
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * profile.h
+ */
+
+#ifndef _KRB5_PROFILE_H
+#define _KRB5_PROFILE_H
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+       #include <KerberosSupport/KerberosSupport.h>
+       
+       #if TARGET_API_MAC_OS8 || (TARGET_API_MAC_CARBON && !TARGET_API_MAC_OSX)
+               #include <Kerberos5/win-mac.h>
+       #endif
+#endif
+
+#if TARGET_API_MAC_OSX && TARGET_API_MAC_CARBON
+       #include <CoreServices/CoreServices.h>
+#elif TARGET_API_MAC_OS8 || TARGET_API_MAC_CARBON
+       #include <Files.h>
+#else
+       #error "Unknown OS"
+#endif
+
+#if defined(_MSDOS) || defined(_WIN32)
+#include <win-mac.h>
+#endif
+
+#ifndef KRB5_CALLCONV
+#define KRB5_CALLCONV
+#define KRB5_CALLCONV_C
+#define KRB5_DLLIMP
+#define GSS_DLLIMP
+#define KRB5_EXPORTVAR
+#define FAR
+#define NEAR
+#endif
+
+typedef struct _profile_t *profile_t;
+
+#if !defined(PROTOTYPE)
+#if defined(__STDC__) || defined(__cplusplus) || defined(_MSDOS) || defined(_WIN32)
+#define PROTOTYPE(x) x
+#else
+#define PROTOTYPE(x) ()
+#endif
+#endif
+
+/*
+ * Used by the profile iterator in prof_get.c
+ */
+#define PROFILE_ITER_LIST_SECTION      0x0001
+#define PROFILE_ITER_SECTIONS_ONLY     0x0002
+#define PROFILE_ITER_RELATIONS_ONLY    0x0004
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Macintoh CFM-68K magic incantation */
+#if PRAGMA_IMPORT
+#pragma import on
+#endif
+
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=mac68k
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(push, 2)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack(2)
+#endif
+
+/* We use file paths as unique file identifiers except Mac OS 8 and 9*/
+#if TARGET_API_MAC_OS8 || (TARGET_API_MAC_CARBON && !TARGET_API_MAC_OSX)
+    /* On CFM MacOS, we use native file specifiers as unique file identifiers */
+    typedef FSSpec profile_filespec_t;
+    typedef FSSpec* profile_filespec_list_t;
+    /* array should be terminated with {0, 0, ""} */
+    typedef FSSpec const_profile_filespec_t;
+    typedef FSSpec* const_profile_filespec_list_t;     
+#else
+    #define PROFILE_USES_PATHS
+
+    typedef char* profile_filespec_t;  /* path as C string */
+    typedef char* profile_filespec_list_t;     /* list of : separated paths, C string */
+    typedef const char* const_profile_filespec_t;      /* path as C string */
+    typedef const char* const_profile_filespec_list_t; /* list of : separated paths, C string */
+#endif
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_init
+       PROTOTYPE ((const_profile_filespec_t *files, profile_t *ret_profile));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_init_path
+       PROTOTYPE ((const_profile_filespec_list_t filelist, profile_t *ret_profile));
+
+/* On Mac Carbon, also provide FSSpec variants */
+#if TARGET_OS_MAC
+KRB5_DLLIMP long KRB5_CALLCONV FSp_profile_init
+       PROTOTYPE ((const FSSpec* files, profile_t *ret_profile));
+
+KRB5_DLLIMP long KRB5_CALLCONV FSp_profile_init_path
+       PROTOTYPE ((const FSSpec* files, profile_t *ret_profile));
+#endif
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_flush
+       PROTOTYPE ((profile_t profile));
+
+KRB5_DLLIMP void KRB5_CALLCONV profile_abandon
+       PROTOTYPE ((profile_t profile));
+
+KRB5_DLLIMP void KRB5_CALLCONV profile_release
+       PROTOTYPE ((profile_t profile));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_values
+       PROTOTYPE ((profile_t profile, const char **names, char ***ret_values));
+
+KRB5_DLLIMP void KRB5_CALLCONV profile_free_list
+       PROTOTYPE ((char **list));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_string
+       PROTOTYPE((profile_t profile, const char *name, const char *subname, 
+                       const char *subsubname, const char *def_val,
+                       char **ret_string));
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_integer
+       PROTOTYPE((profile_t profile, const char *name, const char *subname,
+                       const char *subsubname, int def_val,
+                       int *ret_default));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_boolean
+       PROTOTYPE((profile_t profile, const char *name, const char *subname,
+                       const char *subsubname, int def_val,
+                       int *ret_default));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_relation_names
+       PROTOTYPE((profile_t profile, const char **names, char ***ret_names));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_get_subsection_names
+       PROTOTYPE((profile_t profile, const char **names, char ***ret_names));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_iterator_create
+       PROTOTYPE((profile_t profile, const char **names,
+                  int flags, void **ret_iter));
+
+KRB5_DLLIMP void KRB5_CALLCONV profile_iterator_free
+       PROTOTYPE((void **iter_p));
+       
+KRB5_DLLIMP long KRB5_CALLCONV profile_iterator
+       PROTOTYPE((void **iter_p, char **ret_name, char **ret_value));
+
+KRB5_DLLIMP void KRB5_CALLCONV profile_release_string PROTOTYPE((char *str));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_update_relation
+       PROTOTYPE((profile_t profile, const char **names, 
+                  const char *old_value, const char *new_value));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_clear_relation
+       PROTOTYPE((profile_t profile, const char **names));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_rename_section
+       PROTOTYPE((profile_t profile, const char **names, 
+                  const char *new_name));
+
+KRB5_DLLIMP long KRB5_CALLCONV profile_add_relation
+       PROTOTYPE((profile_t profile, const char **names, 
+                  const char *new_value));
+
+/* Macintosh CFM-68K magic incantation */
+#if PRAGMA_STRUCT_ALIGN
+       #pragma options align=reset
+#elif PRAGMA_STRUCT_PACKPUSH
+       #pragma pack(pop)
+#elif PRAGMA_STRUCT_PACK
+       #pragma pack()
+#endif
+
+#ifdef PRAGMA_IMPORT_OFF
+#pragma import off
+#elif PRAGMA_IMPORT
+#pragma import reset
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _KRB5_PROFILE_H */
+/*
+ * :::MITKerberosLib:GSSKerberos5Sources_9:util:profile:prof_err.h:
+ * This file is automatically generated; please do not edit it.
+ */
+
+#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
+#include <KerberosComErr/KerberosComErr.h>
+#else
+#include <com_err.h>
+#endif
+
+#define PROF_VERSION                             (-1429577728L)
+#define PROF_MAGIC_NODE                          (-1429577727L)
+#define PROF_NO_SECTION                          (-1429577726L)
+#define PROF_NO_RELATION                         (-1429577725L)
+#define PROF_ADD_NOT_SECTION                     (-1429577724L)
+#define PROF_SECTION_WITH_VALUE                  (-1429577723L)
+#define PROF_BAD_LINK_LIST                       (-1429577722L)
+#define PROF_BAD_GROUP_LVL                       (-1429577721L)
+#define PROF_BAD_PARENT_PTR                      (-1429577720L)
+#define PROF_MAGIC_ITERATOR                      (-1429577719L)
+#define PROF_SET_SECTION_VALUE                   (-1429577718L)
+#define PROF_EINVAL                              (-1429577717L)
+#define PROF_READ_ONLY                           (-1429577716L)
+#define PROF_SECTION_NOTOP                       (-1429577715L)
+#define PROF_SECTION_SYNTAX                      (-1429577714L)
+#define PROF_RELATION_SYNTAX                     (-1429577713L)
+#define PROF_EXTRA_CBRACE                        (-1429577712L)
+#define PROF_MISSING_OBRACE                      (-1429577711L)
+#define PROF_MAGIC_PROFILE                       (-1429577710L)
+#define PROF_MAGIC_SECTION                       (-1429577709L)
+#define PROF_TOPSECTION_ITER_NOSUPP              (-1429577708L)
+#define PROF_INVALID_SECTION                     (-1429577707L)
+#define PROF_END_OF_SECTIONS                     (-1429577706L)
+#define PROF_BAD_NAMESET                         (-1429577705L)
+#define PROF_NO_PROFILE                          (-1429577704L)
+#define PROF_MAGIC_FILE                          (-1429577703L)
+#define PROF_MAGIC_FILE_DATA                     (-1429577702L)
+#define PROF_FAIL_OPEN                           (-1429577701L)
+#define PROF_EXISTS                              (-1429577700L)
+#define PROF_BAD_BOOLEAN                         (-1429577699L)
+#define PROF_BAD_INTEGER                         (-1429577698L)
+#define ERROR_TABLE_BASE_prof (-1429577728L)
+
+extern struct error_table et_prof_error_table;
+
+#if (defined(unix) || defined(_AIX)) && !(defined(__MACH__) && defined(__APPLE__))
+/* for compatibility with older versions... */
+extern void initialize_prof_error_table ();
+#define init_prof_err_tbl initialize_prof_error_table
+#define prof_err_base ERROR_TABLE_BASE_prof
+#else
+#define initialize_prof_error_table()
+#endif
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorLib.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorLib.h
new file mode 100755 (executable)
index 0000000..46c18b2
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorLib.h,v 1.2 2001/12/04 02:05:56 rjs3 Exp $ */\r\r/* \r *\r * errorlib.h -- Functions to handle socket/dns lib errors.\r *\r */\r\r\r#ifndef __ERRORLIB__\r#define __ERRORLIB__\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_RT_MAC_CFM\r    #if TARGET_API_MAC_CARBON\r        #include <CoreServices.h>\r    #endif\r\r    #include <MacTypes.h>\r    #include <Files.h>\r#else\r    #include <CoreServices/CoreServices.h>\r#endif\r\r#include <errno.h>\r\r#if PRAGMA_ONCE\r#pragma once\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r     #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r\r/* ********************* */\r/* The global error code */\r/* ********************* */\rextern OSStatus gMITLibError;\r\r\r/* ****************************************************** */\r/* length the buffer passed to GetErrorString() should be */\r/* ****************************************************** */\r#define kMaxErrorLength 512\r\r\r/* ******************* */\r/* type of error table */\r/* ******************* */\r#define kErrorTableResType 'ErrT'\r\r\r/* *********************************************** */\r/* Format of the error string for GetErrorString() */\r/* *********************************************** */\renum ErrorFormat \r{\r  kErrorLongFormat,\r  kErrorShortFormat,\r  kErrorManager,\r  kErrorShortString,\r  kErrorLongString\r};\rtypedef enum ErrorFormat ErrorFormat;\r\r/* ******************* */\r/* Function prototypes */\r/* ******************* */\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers on\r#else\r#   define ErrorLibraryIsPresent() ((Ptr) (RegisterErrorTable) != (Ptr) (kUnresolvedCFragSymbolAddress))\r#endif\r\rextern OSStatus GetMITLibError(void);\rextern void SetMITLibError(OSStatus theError);\rextern void ClearMITLibError(void);\r\rextern OSStatus RegisterErrorTable(const FSSpec* inResFile, SInt16 inResID);\r#if TARGET_API_MAC_CARBON\rextern OSStatus RegisterErrorTableForBundle(CFStringRef inBundleID, SInt16 inResID);\r#endif\r\rextern OSStatus GetErrorLongFormat(OSStatus error, char *message, long messageLength);\rextern OSStatus GetErrorShortFormat(OSStatus error, char *message, long messageLength);\rextern OSStatus GetErrorManager(OSStatus error, char *message, long messageLength);\rextern OSStatus GetErrorShortString(OSStatus error, char *message, long messageLength);\rextern OSStatus GetErrorLongString(OSStatus error, char *message, long messageLength);\r\rextern OSStatus GetErrorString(OSStatus error, char *message, long messageLength, ErrorFormat format);\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers reset\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r      #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* __ERRORLIB__ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorList.r b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorList.r
new file mode 100755 (executable)
index 0000000..8a45d12
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ErrorList.r,v 1.2 2001/12/04 02:05:56 rjs3 Exp $ */\r\rtype 'ErrT' {\r      integer = $$CountOf (ErrorTable);               //      Number of errors in the table\r  align long;\r\r   wide array ErrorTable {\rEntryStart:\r                                                                                    //      Calculate the length of this\r                                                                                   //      array element (in bytes)\r               integer = (EntryEnd [$$ArrayIndex (ErrorTable)] -\r                                      EntryStart [$$ArrayIndex (ErrorTable)]) / 8;\r           align long;\r\r           longint;                                                        //      ErrorCode\r\r             cstring;                                                        //      Short error string\r             align long;\r\r           cstring;                                                        //      Long error string\r              align long;\r\rEntryEnd:\r };\r};\r\r\r/* sample\r\rformat: error number, short error string, long error string\rerror numbers don't have to be consecutive\r\rresource 'ErrT' (129, "Manager Name")\r{\r     {\r              -1, "Short 1", "Long 1",\r               -2, "Short 2", "Long 2"\r        }\r};\r\r*/
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Idle.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Idle.h
new file mode 100755 (executable)
index 0000000..b9d2d8e
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Idle.h,v 1.2 2001/12/04 02:05:56 rjs3 Exp $ */\r\r/* \r *\r * Idle.h -- Main external header file for the Idle library.\r *\r */\r\r#ifndef _IDLELIB_\r#define _IDLELIB_\r\r#include <Events.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#       pragma import on\r#endif\r\r\r/****************************/\r/* API Structures and Types */\r/****************************/\r\r/* Callback API for Event handler proc for idle loop */\rtypedef CALLBACK_API (Boolean, IdleEventHandlerProcPtr) (const EventRecord *theEvent, UInt32 refCon);\r\r/* UPP for Idle Library event filter */\r#if !TARGET_API_MAC_CARBON\r      typedef STACK_UPP_TYPE (IdleEventHandlerProcPtr) IdleEventHandlerUPP;\r  \r       #define NewIdleEventHandlerProc(userRoutine)                    \\r              (IdleEventHandlerUPP) NewRoutineDescriptor((ProcPtr)(userRoutine), uppIdleEventHandlerProcInfo, GetCurrentArchitecture())\r#else\r        typedef IdleEventHandlerProcPtr IdleEventHandlerUPP;\r   \r       #define NewIdleEventHandlerProc(userRoutine)                    \\r              userRoutine\r#endif\r\r\r/* Procinfo for Idle Library event filter */\renum {\r       uppIdleEventHandlerProcInfo = kPascalStackBased |\r              RESULT_SIZE (sizeof (Boolean)) |\r               STACK_ROUTINE_PARAMETER (1, SIZE_CODE (sizeof (const EventRecord *))) |\r                STACK_ROUTINE_PARAMETER (2, SIZE_CODE (sizeof (UInt32)))\r};\r\r\r/***********************/\r/* Function Prototypes */\r/***********************/\r\r#define IdleLibIsPresent_ ((Ptr) Idle != (Ptr) kUnresolvedCFragSymbolAddress)\r\r/* IdleLib API calls */\rOSStatus IdleAddEventHandler(IdleEventHandlerUPP eventHandlerUPP, Boolean isApplication, \r                                                   UInt16 mask, UInt32 refCon);\rOSStatus IdleRemoveEventHandler(IdleEventHandlerUPP eventHandlerUPP);\r\rvoid IdleSetActive(IdleEventHandlerUPP eventHandlerUPP);\rvoid IdleSetInactive(IdleEventHandlerUPP eventHandlerUPP);\r\rvoid   IdleSetIdleFrequency(UInt32 idleFrequency);\rUInt32 IdleGetIdleFrequency(void);\r\rvoid   IdleSetEventSleepTime(UInt32 eventSleepTime);\rUInt32 IdleGetEventSleepTime(void);\r\rvoid    IdleSetThreaded(Boolean isThreaded);\rBoolean IdleGetThreaded(void);\r\rvoid    IdleSetShouldIdle(Boolean shouldIdle);\rBoolean IdleGetShouldIdle(void);\r\rBoolean  IdleHandleEvent (const EventRecord    *theEvent);\rOSStatus Idle(void);\r\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r# pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* _IDLELIB_ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosConditionalMacros.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosConditionalMacros.h
new file mode 100755 (executable)
index 0000000..c71b7ac
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Shim header file to get the functionality of ConditionalMacros.h\r * in all environments\r */\r \r#ifndef KERBEROSCONDITIONALMACROS_H\r#define KERBEROSCONDITIONALMACROS_H\r\r#if defined(macintosh) && !(defined(__MACH__) && defined(__APPLE__))\r\r    /* Mac OS 8 and 9 */\r    #include <ConditionalMacros.h>\r\r#elif defined(__GNUC__) && ( defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__))\r    \r    /* Mac OS X compilers we support */\r    #include <TargetConditionals.h>                   /* Darwin macros: TARGET_OS_*, TARGET_CPU_*, TARGET_RT_* */\r\r    /* Things we use which are not defined by Darwin's conditional macros */\r    #define TARGET_API_MAC_CARBON                                     1       /* Currently we require Carbon */\r    #define TARGET_API_MAC_OSX                                                1       /* This is a Mac OS X box */\r    #define BAGEL_STAPLING                                                 1   /* We love Mac OS X */\r    #define ALL_YOUR_KERBEROS_ARE_BELONG_TO_US               1       /* We love Kerberos */\r\r#else\r    #error "Unsupported environment"\r#endif\r\r#endif /* KERBEROSCONDITIONALMACROS_H */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosSupport.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/KerberosSupport.h
new file mode 100755 (executable)
index 0000000..836f235
--- /dev/null
@@ -0,0 +1 @@
+#ifndef __KERBEROSSUPPORT__\r#define __KERBEROSSUPPORT__\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r/*\r * I don't want to export any of these to the general public\r * If you need them, you should be including them directly,\r * using the paths as below:\r\r\r#include <KerberosSupport/DirectoryCopy.h>\r#include <KerberosSupport/FSpCompat.h>\r#include <KerberosSupport/FileCopy.h>\r#include <KerberosSupport/FullPOSIXPath.h>\r#include <KerberosSupport/FullPath.h>\r#include <KerberosSupport/IterateDirectory.h>\r#include <KerberosSupport/KerberosDebug.h>\r#include <KerberosSupport/KerberosFullPath.h>\r#include <KerberosSupport/MoreDesktopMgr.h>\r#include <KerberosSupport/MoreFiles.h>\r#include <KerberosSupport/MoreFilesExtras.h>\r#include <KerberosSupport/Optimization.h>\r#include <KerberosSupport/OptimizationEnd.h>\r#include <KerberosSupport/Search.h>\r#include <KerberosSupport/UH3.2.Hack.h>\r\r */\r\r#endif /* __KERBEROSSUPPORT__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ShlibDriver.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/ShlibDriver.h
new file mode 100755 (executable)
index 0000000..8c0316f
--- /dev/null
@@ -0,0 +1 @@
+#pragma once\r\r#include <ConditionalMacros.h>\r#include <Processes.h>\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\renum {\r       kShlibDriverOffendingProcessGestalt     = FOUR_CHAR_CODE ('hl¿Ä')\r};\r\r#define kShlibDriverFragmentName "\pMIT SupportÂ¥ShlibDriverLib"\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\rOSErr LoadSharedLibraryDriver (\r Str31                                   inDriverName,\r  Str255                                  inDispatchLibraryName);\r        \rOSErr UnloadSharedLibraryDriver (\r     Str31                                   inDriverName,\r  ProcessSerialNumber*    outOffendingProcess);\r  \rOSErr RegisterFileWithCodeFragmentManager (\r   const FSSpec*                   inFile);\r\r#ifdef __cplusplus\r}\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/SocketErrors.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/SocketErrors.h
new file mode 100755 (executable)
index 0000000..326d3fc
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/SocketErrors.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/* \r *\r * SocketErrors.h -- Error codes for socket errors.\r *\r */\r\r/* NOTE: Before you add a new error code, check the other libraries to make sure that you\r   have not taken an error code range designated for another library. */\r\r\r#ifndef _SOCKET_ERRORS_\r#define _SOCKET_ERRORS_\r\r\r/* New error definitions */\r#define kSocketsFirstErr   200                                             /*  The beginning of the sockets errors */\r#define kENOTDIRErr                  201                                             /*      Not a directory                                         */\r#define kEISDIRErr                   202                                             /*      Is a directory                                          */\r#define kEPFNOSUPPORTErr     203                                             /*      Protocol family not supported           */\r#define kEAFNOSUPPORTErr     204                                             /*      Address family not supported            */\r#define kSockNotInitErr              205                                             /*      Sockets lib is not initialized          */\r#define kSockAlreadyInitErr  206                                             /*      Sockets lib is already initialized      */\r#define kNoOTErr                     207                                             /*      Open Transport is unavailable           */\r#define kSocketIsIdleErr     208                                             /*  No operation in progress on socket  */\r#define kEMFILEErr                   209                                             /*  Too many sockets open                               */\r#define kENOSPCErr                   210                                             /*  Not enough space to write output    */\r#define kEBADDOMAINNAMEErr   211                                             /*  Bad domain name in TCP/IP settings  */\r#define kEBADNAMESERVERSErr  212                                             /*  Bad name servers in TCP/IP settings */\r#define kENONETWORKErr               213                                             /*  No network: check TCP/IP settings   */\r#define kSocketsLastErr              299                                             /*  The last sockets error      */\r\r#ifndef rez  /* This part cannot be included by a rez file */\r\r#include <OpenTptInternet.h>\r#include <errno.h>\r\r#undef ERANGE  /* defined by errno.h -- but we want the OT definition */\r\r/* Mappings from errno.h errors to OT LibC errors */\renum OTCompatErrors\r{\r/*  EPERM                                      = kEPERMErr,                            /*  Permission denied                                   */\r/*  ENOENT                           = kENOENTErr,                           /*  No such file or directory                   */\r  ESRCH                                      = kESRCHErr,                            /*      No such process                                         */\r  ENORSRC                            = kENORSRCErr,                          /*  No such resource                                    */\r  EINTR                                      = kEINTRErr,                            /*  Interrupted system service                  */\r/*  EIO                                      = kEIOErr,                                      /*  I/O error                                                   */\r  ENXIO                                      = kENXIOErr,                            /*  No such device or address                   */\r/*  EBADF                                    = kEBADFErr,                            /*  Bad file number                                             */\r  EAGAIN                             = kEAGAINErr,                           /*  Try operation again later                   */\r/*  ENOMEM                           = kENOMEMErr,                           /*  Not enough space                                    */\r/*  EACCES                           = kEACCESErr,                           /*  Permission denied                                   */\r  EFAULT                             = kEFAULTErr,                           /*  Bad address                                                 */\r  EBUSY                                      = kEBUSYErr,                            /*  Device or resource busy                             */\r/*  EEXIST                           = kEEXISTErr,                           /*  File exists                                                 */\r  ENODEV                             = kENODEVErr,                           /*  No such device                                              */\r  ENOTDIR                            = kENOTDIRErr,                          /*      Not a directory                                         */\r/*  EISDIR                           = kEISDIRErr,                           /*      Is a directory                                          */\r/*  EMFILE                           = kEMFILEErr,                           /*  Too many sockets open                               */\r/*  EINVAL                           = kEINVALErr,                           /*  Invalid argument                                    */\r  ENOTTY                             = kENOTTYErr,                           /*  Not a character device                              */\r  EPIPE                                      = kEPIPEErr,                            /*  Broken pipe                                                 */\r/*  ENOSPC                           = kENOSPCErr,                           /*  Not enough space to write output    */\r\r  ERANGE                            = kERANGEErr,                           /*  Message size too large for STREAM   */\r  EDEADLK                            = kEDEADLKErr,                          /*  or a deadlock would occur                   */\r\r  EPROTO                            = kEPROTOErr,                           /*      Protocol error                                          */\r  EBADMSG                            = kEBADMSGErr,                          /*      Trying to read unreadable message       */\r  ECANCEL                            = kECANCELErr,                          /*      Operation cancelled                                     */\r  ENOMSG                             = kENOMSGErr,                           /*      No message of desired type                      */\r\r  ENOSTR                            = kENOSTRErr,                           /*      Device not a stream                                     */\r  ENODATA                            = kENODATAErr,                          /*      No data (for no delay I/O)                      */\r  ETIME                                      = kETIMEErr,                            /*      Timer expired                                           */\r  ENOSR                                      = kENOSRErr,                            /*      Out of streams resources                        */\r\r  ENOTSOCK                          = kENOTSOCKErr,                         /*  Socket operation on non-socket              */\r  EDESTADDRREQ                       = kEDESTADDRREQErr,                     /*  Destination address required                */\r  EMSGSIZE                           = kEMSGSIZEErr,                         /*  Message too long                                    */\r  EPROTOTYPE                 = kEPROTOTYPEErr,                       /*  Protocol wrong type for socket              */\r  ENOPROTOOPT                        = kENOPROTOOPTErr,                      /*  Protocol not available                              */\r  EPROTONOSUPPORT            = kEPROTONOSUPPORTErr,          /*  Protocol not supported                              */\r  ESOCKTNOSUPPORT            = kESOCKTNOSUPPORTErr,          /*  Socket type not supported                   */\r  EOPNOTSUPP                 = kEOPNOTSUPPErr,                       /*  Operation not supported on socket   */\r  EPFNOSUPPORT                       = kEPFNOSUPPORTErr,                     /*      Protocol family not supported           */\r  EAFNOSUPPORT                       = kEAFNOSUPPORTErr,                     /*      Address family not supported            */\r\r  EADDRINUSE                        = kEADDRINUSEErr,                       /*  Address already in use                              */\r  EADDRNOTAVAIL                      = kEADDRNOTAVAILErr,            /*  Can't assign requested address              */\r  ENETDOWN                           = kENETDOWNErr,                         /*  No network, check TCP/IP settings   */\r  ENETUNREACH                        = kENETUNREACHErr,                      /*  Network is unreachable                              */\r  ENETRESET                          = kENETRESETErr,                        /*  Network dropped connection on reset */\r\r  ECONNABORTED                      = kECONNABORTEDErr,                     /*  Software caused connection abort    */\r  ECONNRESET                 = kECONNRESETErr,                       /*  Connection reset by peer                    */\r  ENOBUFS                            = kENOBUFSErr,                          /*  No buffer space available                   */\r  EISCONN                            = kEISCONNErr,                          /*  Socket is already connected                 */\r  ENOTCONN                           = kENOTCONNErr,                         /*  Socket is not connected                             */\r  ESHUTDOWN                          = kESHUTDOWNErr,                        /*  Can't send after socket shutdown    */\r  ETOOMANYREFS                       = kETOOMANYREFSErr,                     /*  Too many references: can't splice   */\r  ETIMEDOUT                          = kETIMEDOUTErr,                        /*  Connection timed out                                */\r  ECONNREFUSED                       = kECONNREFUSEDErr,                     /*  Connection refused                                  */\r  EHOSTDOWN                          = kEHOSTDOWNErr,                        /*  Host is down                                                */\r  EHOSTUNREACH                       = kEHOSTUNREACHErr,                     /*  No route to host                                    */\r  EWOULDBLOCK                        = kEWOULDBLOCKErr,                      /*  Call would block, so was aborted    */\r  EALREADY                           = kEALREADYErr,                         /*      Operation already in progress           */\r  EINPROGRESS                        = kEINPROGRESSErr,                      /*      Operation now in progress                       */\r\r  EBADDOMAINNAME            = kEBADDOMAINNAMEErr,           /*  Bad domain name in TCP/IP settings  */\r  EBADNAMESERVERS            = kEBADNAMESERVERSErr,          /*  Bad name servers in TCP/IP settings */\r  ENONETWORK                 = kENONETWORKErr                        /*  No network: check TCP/IP settings   */\r};\r\r#endif /* !rez */\r\r#endif /* _SOCKET_ERRORS_ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Sockets.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Sockets.h
new file mode 100755 (executable)
index 0000000..5f6a6c3
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Sockets.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/* \r *\r * Sockets.h -- Main external header file for the sockets library.\r *\r */\r\r\r#include <KerberosSupport/ErrorLib.h>\r#include <KerberosSupport/Utilities.h>\r#include <KerberosSupport/SocketErrors.h>\r#include <unix.h>\r\r#include <MacTypes.h>\r#include <Events.h>\r#include <OpenTptInternet.h>\r\r#ifndef _SOCKETS_\r#define _SOCKETS_\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#        pragma import on\r#endif\r\r/*******************/\r/* API Definitions */\r/*******************/\r\r#define FD_SETSIZE          256     /*      The maximum # of sockets -- cannot be changed   */\r\r/* socket types */\r#define SOCK_STREAM              0               /*      stream socket -- connection oriented                    */\r#define SOCK_DGRAM           1               /*      datagram socket -- connectionless                               */\r#define SOCK_RAW             2               /*      raw socket                                                                              */\r#define SOCK_SEQPACKET       3               /*      sequenced packet socket                                                 */\r#define SOCK_RDM             4               /*      reliably delivered message socket                               */\r\r/* address families  -- get AF_INET from OpenTptInternet.h */\r#define AF_UNSPEC             0               /*      Unspecified                                                                             */\r#define AF_UNIX                      1               /*      Unix internal protocols                                                 */\r\r/* protocol families */\r#define PF_UNSPEC   AF_UNSPEC       /*      Unspecified                                                                             */\r#define PF_UNIX              AF_UNIX         /*      Unix internal protocols                                                 */\r#define PF_INET              AF_INET         /*      Internet protocols                                                              */\r\r/* IP Address Wildcard */\r#define INADDR_ANY      kOTAnyInetAddress\r#define INADDR_NONE             0xffffffff\r\r/* recv and send flags */\r#define MSG_DONTROUTE     1\r#define MSG_DONTWAIT  2\r#define MSG_OOB                       4\r#define MSG_PEEK              8\r#define MSG_WAITALL           16\r\r#define NUMBITSPERBYTE      8               /*      Number of bits per byte                                                 */\r\r/* socket_fnctl() requests */\r#define F_GETFL                       3               /* Get file flags                                                                       */\r#define F_SETFL                      4               /* Set file flags                                                                       */\r\r/* shutdown() flags */\r#define SHUT_RD                      0               /* Shutdown read side of the connection                         */\r#define SHUT_WR                      1               /* Shutdown write side of the connection                        */\r#define SHUT_RDWR            2               /* Shutdown read and write sides of the connection      */\r\r/* IP address sizes */\r#define INET_ADDRSTRLEN              16      /* for IPv4 dotted decimal                                                      */\r#define INET6_ADDRSTRLEN     46      /* for IPv6 dhex string                                                         */\r#define INADDRSZ                     4       /* size of IPv4 addr in bytes                                           */\r#define IN6ADDRSZ                    16      /* size of IPv6 addr in bytes                                           */\r\r/* host name size */\r#define MAXHOSTNAMESIZE                kMaxHostNameLen\r#define MAXHOSTNAMELEN          kMaxHostNameLen\r\r#ifdef USE_STREAMS\r/* Constants for poll() */\r#define POLLIN          0x001   /* A non-priority message is available */\r#define POLLPRI         0x002   /* A high priority message is available */\r#define POLLOUT         0x004   /* The stream is writable for non-priority messages */\r#define POLLERR         0x008   /* A error message has arrived */\r#define POLLHUP         0x010   /* A hangup has occurred */\r#define POLLNVAL        0x020   /* This fd is bogus */\r#define POLLRDNORM      0x040   /* A non-priority message is available */\r#define POLLRDBAND      0x080   /* A priority message (band > 0) message is available */\r#define POLLWRNORM      0x100   /* Same as POLLOUT */\r#define POLLWRBAND      0x200   /* A priority band exists and is writable */\r#define POLLMSG         0x400   /* A signal message has reached the front of the queue */\r#endif /* USE_STREAMS */\r\r/**********/\r/* Macros */\r/**********/\r\r/* network byte order conversion [none since we're already big-endian] */\r#define     ntohl(x)                (x)\r#define     ntohs(x)                (x)\r#define     htonl(x)                (x)\r#define     htons(x)                (x)\r\r/* macros for select */\r#define FD_SET(fd, fdset)  ((fdset)->fds_bits[(fd) / NFDBITS] |= ((unsigned)1 << ((fd) % NFDBITS)))\r#define FD_CLR(fd, fdset)      ((fdset)->fds_bits[(fd) / NFDBITS] &= ~((unsigned)1 << ((fd) % NFDBITS)))\r#define FD_ISSET(fd, fdset)   ((fdset)->fds_bits[(fd) / NFDBITS] & ((unsigned)1 << ((fd) % NFDBITS)))\r#define FD_ZERO(fdset)          memset((char *)(fdset), 0, sizeof(*(fdset)))\r\r\r/****************************/\r/* API Structures and Types */\r/****************************/\r\r/* An internet address */\rtypedef UInt32  in_addr_t; \r\r/* size of address structures */\rtypedef UInt32 socklen_t;\r\r/* structure used to store addresses */\rstruct sockaddr {\r      u_short sa_family;\r     char    sa_data[14];\r};\r\r/* INET protocol structures */\rstruct in_addr {\r       in_addr_t       s_addr;\r};\r\r/* A TCP address -- the same as a OT InetAddress */\rstruct sockaddr_in {                            /* struct InetAddress {                         */\r     u_short                 sin_family;             /* OTAddressType        fAddressType    */\r     u_short                 sin_port;               /* InetPort                     fPort                   */\r     struct in_addr  sin_addr;               /* InetHost                     fHost                   */\r     char                    sin_zero[8];    /* UInt8                        fUnused                 */\r};                                                                   /* };                                                           */\r\r/* structures for select */\rtypedef long fd_mask;\r#define NFDBITS                   (sizeof(fd_mask) * NUMBITSPERBYTE)      /* bits per mask */\r\rtypedef struct fd_set {\r  fd_mask fds_bits[(FD_SETSIZE + NFDBITS - 1) / NFDBITS];\r} fd_set;\r\r/* Structure for non-contiguous data */\rstruct iovec {\r  struct iovec *next;                  /* For compatibility with Open Transport */\r  void         *iov_base;           /* Starting address of buffer */\r  size_t        iov_len;               /* size of buffer */\r};\r\r/* For poll() */\rstruct pollfd {\r  int   fd;\r  short events;\r  short revents;\r};\r\r/***********************/\r/* Function Prototypes */\r/***********************/\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers on\r#else\r#   define SocketsLibraryIsPresent() ((Ptr) (socket) != (Ptr) (kUnresolvedCFragSymbolAddress))\r#endif\r\r/* Sockets Control API calls */\rOSStatus                           AbortSocketOperation(int sockFD);\rOSStatus                      AbortAllDNSOperations(void);\rBoolean                IsValidSocket(int sockFD);\r\r/* Sockets API calls */\rint socket(int family, int type, int protocol);\rint socket_bind(int sockFD, const struct sockaddr *myAddr, int addrLength);\rint socket_fcntl(int sockFD, int command, int flags);\rint socket_close(int sockFD);\rint socket_shutdown(int sockFD, int howTo);\rint socket_connect(int sockFD, struct sockaddr *servAddr, int addrLength);\rint socket_select(int maxFDsExamined, fd_set *readFDs, fd_set *writeFDs, fd_set *exceptFDs,\r                  struct timeval *timeOut);\r#ifdef USE_STREAMS\rint socket_poll (struct pollfd *fds, unsigned int nfds, int timeout);\r#endif /* USE_STREAMS */\rint socket_getpeername(int sockFD, struct sockaddr *peerAddr, int *addrLength);\rint socket_getsockname(int sockFD, struct sockaddr *localAddr, int *addrLength);\rint socket_read(int sockFD, void *buffer, UInt32 numBytes);\rint socket_write(int sockFD, const void *buffer, UInt32 numBytes);\rint socket_readv(int sockFD, struct iovec *iov, UInt32 iovCount);\rint socket_writev(int sockFD, struct iovec *iov, UInt32 iovCount);\rint socket_recv(int sockFD, void *buffer, UInt32 numBytes, int flags);\rint socket_send(int sockFD, const void *buffer, UInt32 numBytes, int flags);\rint socket_recvfrom(int sockFD, void *buffer, UInt32 numBytes, int flags, struct sockaddr *fromAddr, \r                    socklen_t *addrLength);\rint socket_sendto(int sockFD, const void *buffer, UInt32 numBytes, int flags, struct sockaddr *toAddr, \r                  socklen_t addrLength);\r\r/* Utilites API calls */\rchar     *inet_ntoa(struct in_addr addr);\rint             inet_aton(const char *str, struct in_addr *addr);\rin_addr_t         inet_addr(const char *str);\rint             inet_pton(int family, const char *str, void *addr);\rconst char *inet_ntop(int family, const void *addr, char *str, size_t len);\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers reset\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#   pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* _SOCKETS_ */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Utilities.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Utilities.h
new file mode 100755 (executable)
index 0000000..3b5b6c5
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Utilities.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/*\r * Utilities.h - Public header file for the Utilities library\r */\r \r#ifndef __UTILITIES__\r#define __UTILITIES__\r\r#include <time.h>\r#include <KerberosSupport/pwd.h>\r\r#include <ConditionalMacros.h>\r#include <MacTypes.h>\r\r#if PRAGMA_ONCE\r#pragma once\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r#if PRAGMA_STRUCT_ALIGN\r     #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r/************************/\r/* Structures and Types */\r/************************/\r\r/* common types for POSIX structures */\rtypedef       unsigned char   u_char;\rtypedef unsigned short  u_short;\rtypedef        unsigned int    u_int;\rtypedef  unsigned long   u_long;\r\rtypedef unsigned char   uchar_t;\rtypedef unsigned short  ushort_t;\r/*typedef UInt32  uint_t;*/   /* We don't define uint_t because OpenTransport.h does. */\rtypedef unsigned long      ulong_t;\r\rtypedef char   *caddr_t;\rtypedef SInt32  daddr_t;\rtypedef SInt16  cnt_t;\r\rtypedef ulong_t paddr_t;\rtypedef uchar_t use_t;\rtypedef SInt16  sysid_t;\rtypedef SInt16  index_t;\r\r\r/**********/\r/* Macros */\r/**********/\r\r/* macros for BSD memory utilities */\r#define bzero(dest, nbytes)                       memset(dest, 0, nbytes)\r#define bcopy(src, dest, nbytes)        memcpy(dest, src, nbytes)\r#define bcmp(ptr1, ptr2, nbytes)      memcmp(ptr1, ptr2, nbytes)\r#define index(s, c)                                  strchr(s, c)\r#define rindex(s, c)                               strrchr(s, c)\r\r\r/***********************/\r/* Function Prototypes */\r/***********************/\r\r/* String Utilities */\rint strcasecmp(const char *s1, const char *s2);\rint strncasecmp(const char *s1, const char *s2, register int n);\rchar *strtoken (const char *s, const char *delim, int index);\rchar *strdup (const char *s);\rvoid swab(register char *from, register char *to, register int n);\r\r/* Time Utilities */\rint gettimeofday (struct timeval *tp, struct timezone *);\rint settimeofday (struct timeval *tp, struct timezone *);\rvoid get_gmt_offset(void);\rvoid mac_time_to_unix_time (time_t *time);\rvoid unix_time_to_mac_time (time_t *time);\rvoid msl_time_to_unix_time (time_t *time);\rvoid unix_time_to_msl_time (time_t *time);\r\r/* Mac OS X Runtime utilities */\rBoolean        RunningUnderClassic (void);\rBoolean     RunningUnderMacOSX (void);\r\r\r#if PRAGMA_STRUCT_ALIGN\r   #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* __UTILTIES__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/hesiod.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/hesiod.h
new file mode 100755 (executable)
index 0000000..b88aeda
--- /dev/null
@@ -0,0 +1 @@
+/* $Id: hesiod.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/*\r * Copyright (c) 1996 by Internet Software Consortium.\r *\r * Permission to use, copy, modify, and distribute this software for any\r * purpose with or without fee is hereby granted, provided that the above\r * copyright notice and this permission notice appear in all copies.\r *\r * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS\r * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\r * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE\r * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL\r * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR\r * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS\r * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS\r * SOFTWARE.\r */\r\r#ifndef HESIOD__INCLUDED\r#define HESIOD__INCLUDED\r\r#include <KerberosSupport/KerberosConditionalMacros.h>\r\r#if TARGET_RT_MAC_CFM\r#include <MacTypes.h>\r#include <KerberosSupport/netdb.h>\r#include <KerberosSupport/pwd.h>\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#       pragma import on\r#endif\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r/* Application-visible define to signal that we have the new interfaces. */\r#define HESIOD_INTERFACES\r\rstruct hesiod_postoffice {\r  char *hesiod_po_type;\r  char *hesiod_po_host;\r  char *hesiod_po_name;\r};\r\r\r/* Library control functions */\r#define HesiodLibIsPresent_ ((Ptr) hesiod_init != (Ptr) kUnresolvedCFragSymbolAddress)\r\rOSStatus hesiod_abort_operations(void);\r\r\r/* Hesiod API functions */\rint hesiod_init(void **context);\rvoid hesiod_end(void *context);\rchar *hesiod_to_bind(void *context, const char *name, const char *type);\rchar **hesiod_resolve(void *context, const char *name, const char *type);\rvoid hesiod_free_list(void *context, char **list);\rstruct passwd *hesiod_getpwnam(void *context, const char *name);\rstruct passwd *hesiod_getpwuid(void *context, uid_t uid);\rvoid hesiod_free_passwd(void *context, struct passwd *pw);\rstruct servent *hesiod_getservbyname(void *context, const char *name,\r                                     const char *proto);\rvoid hesiod_free_servent(void *context, struct servent *serv);\rstruct hesiod_postoffice *hesiod_getmailhost(void *context, const char *user);\rvoid hesiod_free_postoffice(void *context, struct hesiod_postoffice *po);\r\r/* Compatibility stuff. */\r\r#define HES_ER_UNINIT     -1      /* uninitialized */\r#define HES_ER_OK   0       /* no error */\r#define HES_ER_NOTFOUND  1       /* Hesiod name not found by server */\r#define HES_ER_CONFIG     2       /* local problem (no config file?) */\r#define HES_ER_NET        3       /* network problem */\r\rstruct hes_postoffice {\r  char *po_type;\r  char *po_host;\r  char *po_name;\r};\r\rint hes_init(void);\rchar *hes_to_bind(const char *name, const char *type);\rchar **hes_resolve(const char *name, const char *type);\rint hes_error(void);\rstruct passwd *hes_getpwnam(const char *name);\rstruct passwd *hes_getpwuid(uid_t uid);\rstruct servent *hes_getservbyname(const char *name, const char *proto);\rstruct hes_postoffice *hes_getmailhost(const char *name);\r\r#ifdef __cplusplus\r}\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#       pragma import reset\r#endif\r\r#endif /* HESIOD__INCLUDED */\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/netdb.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/netdb.h
new file mode 100755 (executable)
index 0000000..4ab0231
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/netdb.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/*  MIT Sockets Library\r *  netdb.h\r *  macdev@mit.edu\r */\r\r#ifndef _NETDB_H\r#define _NETDB_H\r\r#include <stdlib.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\rstruct hostent\r{\r  char  *h_name;        /* official (cannonical) name of host                                              */\r  char **h_aliases;          /* pointer to array of pointers of alias names                          */\r  int    h_addrtype; /* host address type: AF_INET or AF_INET6                                       */\r  int    h_length;           /* length of address: 4 or 16                                                           */\r  char **h_addr_list;        /* pointer to array of pointers with IPv4 or IPv6 addresses     */\r};\r\r#define h_addr  h_addr_list[0]   /* first address in list                                                        */\r\rstruct servent\r{\r  char  *s_name;           /* official service name                                                                        */\r  char **s_aliases;          /* alias list                                                                                           */\r  int    s_port;             /* port number, network-byte order                                                      */\r  char  *s_proto;            /* protocol to use                                                                                      */\r};\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#     pragma import on\r#endif\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers on\r#endif\r\rstruct hostent *gethostbyname(const char *hostname);\rstruct hostent *gethostbyaddr(const char *addr, size_t len, int family);\r\r/* Gets the local host's hostname.  If namelen isn't long enough, it puts in as much of\r   the name as possible, without a terminating null.  This is done so it is compatible\r   with the unix version.  This is, admittedly, the wrong way to write a code, but my\r   excuse is compatibility.  It should really dynamically allocate space.  Oh well.\r   It also assert()'s if you don't pass it a reasonably sized buffer. */\rint gethostname(char *name, size_t namelen);\r\r/* Opens the service database if needed and gets the next service entry.\r   Returns NULL if you have read them all.  On error, returns NULL and\r   calls SetMITLibError(). */\rstruct servent *getservent (void);\r\r/* Closes the service database. On error, calls SetMITLibError(). */\rvoid endservent (void);\r\rstruct servent *getservbyname (const char *servname, const char *protname);\rstruct servent *getservbyport (int port, const char *protname);\r\r#if !TARGET_RT_MAC_CFM\r#   pragma d0_pointers reset\r#endif\r\r#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)\r#  pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r#endif /* _NETDB_H */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/pwd.h b/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/pwd.h
new file mode 100755 (executable)
index 0000000..f720956
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Permission to use, copy, modify, and distribute this software and its\r * documentation for any purpose and without fee is hereby granted,\r * provided that the above copyright notice appear in all copies and that\r * both that copyright notice and this permission notice appear in\r * supporting documentation, and that the name of M.I.T. not be used in\r * advertising or publicity pertaining to distribution of the software\r * without specific, written prior permission.  Furthermore if you modify\r * this software you must label your software as modified software and not\r * distribute it in such a fashion that it might be confused with the\r * original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/pwd.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */\r\r/* pwd.h -- struct passwd                                                                 */\r\r\r#ifndef __PWD__\r#define __PWD__\r\r#include <stat.h>\r\r/* passwd structure for passwd fields */\rstruct passwd \r{\r  char   *pw_name;\r  char   *pw_passwd;\r  uid_t   pw_uid;\r  uid_t   pw_gid;\r  int     pw_quota;\r  char   *pw_comment;\r  char   *pw_gecos;\r  char   *pw_dir;\r  char   *pw_shell;\r};\r\r\r#endif /* __PWD__ */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeper.h b/mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeper.h
new file mode 100755 (executable)
index 0000000..ad7e686
--- /dev/null
@@ -0,0 +1 @@
+/* $Copyright:\r *\r * Copyright 1998-2000 by the Massachusetts Institute of Technology.\r * \r * All rights reserved.\r * \r * Export of this software from the United States of America may require a\r * specific license from the United States Government.  It is the\r * responsibility of any person or organization contemplating export to\r * obtain such a license before exporting.\r * \r * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and distribute\r * this software and its documentation for any purpose and without fee is\r * hereby granted, provided that the above copyright notice appear in all\r * copies and that both that copyright notice and this permission notice\r * appear in supporting documentation, and that the name of M.I.T. not be\r * used in advertising or publicity pertaining to distribution of the\r * software without specific, written prior permission.  Furthermore if you\r * modify this software you must label your software as modified software\r * and not distribute it in such a fashion that it might be confused with\r * the original MIT software. M.I.T. makes no representations about the\r * suitability of this software for any purpose.  It is provided "as is"\r * without express or implied warranty.\r * \r * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\r * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\r * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.\r * \r * Individual source code files are copyright MIT, Cygnus Support,\r * OpenVision, Oracle, Sun Soft, FundsXpress, and others.\r * \r * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,\r * and Zephyr are trademarks of the Massachusetts Institute of Technology\r * (MIT).  No commercial use of these trademarks may be made without prior\r * written permission of MIT.\r * \r * "Commercial use" means use of a name in a product or other for-profit\r * manner.  It does NOT prevent a commercial firm from referring to the MIT\r * trademarks in order to convey information (although in doing so,\r * recognition of their trademark status should be given).\r * $\r */\r\r/* $Header: /afs/andrew/system/cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeper.h,v 1.2 2001/12/04 02:05:58 rjs3 Exp $ */\r\r#pragma once\r\r#include <Types.h>\r#include <Files.h>\r#include <Processes.h>\r#include <ConditionalMacros.h>\r\r#ifdef __cplusplus\rextern "C" {\r#endif\r\r#if PRAGMA_IMPORT\r#pragma import on\r#endif\r\r/*\r * TKAE_SendQuitApplication\r *\r * Send quit event to ticket keeper. This will cause Ticket Keeper to remove its\r * notification if it's up\r */\r\rOSStatus\rTKAE_SendQuitApplication ();\r\r/*\r * TKAE_SendOpenApplication\r *\r * Send open event to ticket keeper. Thiw will launch ticket keeper, and it will\r * display its self-dismissing notification if there's a problem\r */\r \rOSStatus\rTKAE_SendOpenApplication ();\r\r/*\r * TKAE_SendOpenApplicationNoNotification\r *\r * Send open event to Ticket Keeper. This will launch Ticket Keeper, and it will not\r * display its notification if there's a problem. It will stay running.\r */\r \rOSStatus\rTKAE_SendOpenApplicationNoNotification ();\r\r/*\r * TKAE_SendOpenApplicationNoNotificationFSSpec\r *\r * Send open event to the copy of Ticket Keeper specified in inTKFileSpec.\r * This will launch Ticket Keeper, and it will not\r * display its notification if there's a problem. It will stay running.\r */\r \rOSStatus\rTKAE_SendOpenApplicationNoNotificationFSSpec (FSSpec *inTKFileSpec);\r\r/*\r * TKAE_SendGetStatus\r *\r * Get status from Ticket Keeper\r */\r\rOSStatus\rTKAE_SendGetStatus (\r     OSErr*  outStatus);\r    \r/*\r * IsTicketKeeperRunning\r *\r * Return true if TK is running, and fills out outPSN if the pointer is non-null.\r * Return false if TK is not running, and outPSN is unchanged.\r *\r */\r        \rBoolean\rIsTicketKeeperRunning (ProcessSerialNumber *outPSN);\r\r/*\r   FindTicketKeeperInExtensions()\r   \r   Searches the startup volume for copies of Ticket Keeper and checks to see if\r   any of them are in the Extensions Folder.  If it finds one, returns true and\r   fills out *tkSpec.  If it doesn't find one or an error occurs, returns false\r   and *tkSpec is unchanged.\r   \r   If the hard drive catalog changes during the search, continues anyway.\r   \r   Uses functions from MoreFiles.\r*/\r\rBoolean\rFindTicketKeeperInExtensions(FSSpec *tkSpec);\r\r/*\r   TKAE_FindTargetTicketKeeper()\r   \r   Searches the startup volume to find the Ticket Keeper that would receive\r   AppleEvents if any of the TicketKeeperLib functions that send AEs were called.\r   First checks to see if TK is running, and returns the FSSpec of that one if it is.\r   Next looks in the Extensions Folder.  Finally it searches the drive for\r   a copy.\r   \r   If a Ticket Keeper is found, returns true and fills out *tkSpec. \r   If it doesn't find one or an error occurs, returns false and *tkSpec is unchanged.\r   \r   If the hard drive catalog changes during the search, continues anyway.\r*/\r\rBoolean TKAE_FindTargetTicketKeeper(FSSpec *tkSpec);\r\r#if !TARGET_API_MAC_CARBON\r\r/*\r    Menu State functions\r   \r       Ticket Keeper provides information needed for menus presented by the\r   Kerberos Control Strip and Kerberos Menu. \r */\r\rstruct MenuStateHeader;\rtypedef struct MenuStateHeader MenuStateHeader;\rtypedef MenuStateHeader**       MenuState;\r\r/*\r TKMS_GetMenuState\r      \r       Returns the current menu state. Dispose with TKMS_DisposeMenuState\r*/\r\rOSErr TKMS_GetMenuState (MenuState* outMenuState);\r\r/*\r  TKMS_DisposeMenuState\r  \r       Disposes the menu state.\r*/\r\rvoid TKMS_DisposeMenuState (MenuState outMenuState);\r\r/*\r  TKMS_GetDefaultCacheExpiration\r \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the expiration time of the default cache, in Mac epoch\r*/\r      \rOSErr TKMS_GetDefaultCacheExpiration (MenuState inState, UInt32* outExpiration);\r\r/*\r  TKMS_GetDefaultCacheLastChangeTime\r     \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the last change time of the default cache, in Mac epoch\r*/\r     \rOSErr TKMS_GetDefaultCacheLastChangeTime (MenuState inState, UInt32* outChangeTime);\r\r/*\r      TKMS_GetDefaultCachePrincipal\r  \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the principal of the default cache, realm removed if necessary\r*/\r      \rOSErr TKMS_GetDefaultCachePrincipal (MenuState inState, Str255 outPrincipal);\r\r/*\r     TKMS_GetDefaultCacheDisplayPrincipal\r   \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the principal of the default cache, quoting removed\r*/\r \rOSErr TKMS_GetDefaultCacheDisplayPrincipal (MenuState inState, Str255 outPrincipal);\r\r/*\r      TKMS_GetDefaultCacheShortDisplayPrincipal\r      \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the principal of the default cache, quoting and default realm removed\r*/\r       \rOSErr TKMS_GetDefaultCacheShortDisplayPrincipal (MenuState inState, Str255 outPrincipal);\r\r/*\r TKMS_GetDefaultCacheHasValidTickets\r    \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns whether the default cache has valid tickets\r*/\r \rOSErr TKMS_GetDefaultCacheHasValidTickets (MenuState inState, Boolean* outValidTickets);\r\r/*\r  TKMS_GetNumberOfCaches\r \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the total number of caches in the list\r*/\r      \rOSErr TKMS_GetNumberOfCaches (MenuState inState, UInt32* outNumCaches);\r\r/*\r   TKMS_SortCachesAlphabetically\r  \r       Pass in the menu state returned by TKMS_GetMenuState\r   Sorts the caches in the list alphabetically by principal\r*/\r    \rOSErr TKMS_SortCachesAlphabetically (\r MenuState       inState);\r\r/*\r  TKMS_GetCacheListChangeTime\r    \r       Pass in the menu state returned by TKMS_GetMenuState\r   Returns the last change time of the cache list in Mac epoch\r*/\r \rOSErr TKMS_GetCacheListLastChangeTime (MenuState inState, UInt32* outChangeTime);\r\r/*\r TKMS_GetIndexedCachePrincipal\r  \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the cache principal of the cache at the index\r*/\r       \rOSErr TKMS_GetIndexedCachePrincipal (MenuState inState, UInt32 inIndex, Str255 outPrincipal);\r\r/*\r     TKMS_GetIndexedCacheDisplayPrincipal\r   \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the cache principal of the cache at the index, quoting removed\r*/\r      \rOSErr TKMS_GetIndexedCacheDisplayPrincipal (MenuState inState, UInt32 inIndex, Str255 outPrincipal);\r\r/*\r      TKMS_GetIndexedCacheShortDisplayPrincipal\r      \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the cache principal of the cache at the index, quoting and default realm removed\r*/\r    \rOSErr TKMS_GetIndexedCacheShortDisplayPrincipal (MenuState inState, UInt32 inIndex, Str255 outPrincipal);\r\r/*\r TKMS_GetIndexedCacheVersion\r    \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the cache version of the cache at the index (version constants same as ccahe and login lib\r*/\r  \rOSErr TKMS_GetIndexedCacheVersion (MenuState inState, UInt32 inIndex, UInt32* outVersion);\r\r/*\r        TKMS_GetIndexedCacheIsDefault\r  \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns whether the cache at the index is default\r*/\r   \rOSErr TKMS_GetIndexedCacheIsDefault (MenuState inState, UInt32 inIndex, Boolean* outIsDefault);\r\r/*\r   TKMS_GetIndexedCacheIsValid\r    \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns whether the cache at the index has valid tickets\r*/\r    \rOSErr TKMS_GetIndexedCacheIsValid (MenuState inState, UInt32 inIndex, Boolean* outIsValid);\r\r/*\r       TKMS_GetIndexedCacheStartTime\r  \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the start time of the cache at the index in Mac epoch\r*/\r       \rOSErr TKMS_GetIndexedCacheStartTime (MenuState inState, UInt32 inIndex, UInt32* outStartTime);\r\r/*\r    TKMS_GetIndexedCacheExpirationTime\r     \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Returns the expiration time of the cache at the index in Mac epoch\r*/\r  \rOSErr TKMS_GetIndexedCacheExpirationTime (MenuState inState, UInt32 inIndex, UInt32* outExpirationTime);\r\r/*\r  TKMS_SetIndexedDefaultCache\r    \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Sets the cache at the index to be default\r*/\r   \rOSErr TKMS_SetIndexedDefaultCache (MenuState inState, UInt32 inIndex);\r\r/*\r    TKMS_DestroyIndexedCache\r       \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Destroys the cache\r*/\r  \rOSErr TKMS_DestroyIndexedCache (MenuState inState, UInt32 inIndex);\r\r/*\r       TKMS_RenewIndexedCache\r \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Renews the cache\r*/\r    \rOSErr TKMS_RenewIndexedCache (MenuState inState, UInt32 inIndex);\r\r\r/*\r        TKMS_ChangeIndexedCachePassword\r        \r       Pass in the menu state returned by TKMS_GetMenuState\r   Pass in index (zero based, less than value returned from TKMS_GetCachePrincipalForIndex)\r       Changes the password of the principal associated with the cache\r*/\r     \rOSErr TKMS_ChangeIndexedCachePassword (MenuState inState, UInt32 inIndex);\r\r/*\r        TKMS_GetFloaterStructureRegion\r \r       Pass in the menu state returned by TKMS_GetMenuState\r   Copies the structure region of the floater window into ioRegion. Used by tear-off MDEF.\r*/\r     \rOSErr TKMS_GetFloaterStructureRegion (\r        MenuState       inState,\r       RgnHandle       ioRegion);\r\r/*\r TKMS_DestroyDefaultCache\r\r      Destroys the default cache      \r*/\r    \rOSErr TKMS_DestroyDefaultCache (void);\r\r/*\r    TKMS_NewLogin\r\r Create a new cache, log in a new principal.\r*/\r \rOSErr TKMS_NewLogin (void);\r\r/*\r       TKMS_RenewDefaultCache\r\r        Renew tickets for the default cache\r*/\r \rOSErr TKMS_RenewDefaultCache (void);\r\r/*\r      TKMS_ChangeDefaultCachePassword\r\r       Changes the password of the principal associated with the default cache\r*/\r     \rOSErr TKMS_ChangeDefaultCachePassword (void);\r\r/*\r     TKMS_MoveFloaterStructureRegion\r        \r       Pass in the new bounding box for the structure region of the floater\r   Moves the floater to the new location\r*/\r       \rOSErr TKMS_MoveFloaterStructureRegion (\r       const Rect*     inNewBounds);\r\r/*\r      TKMS_OpenKerberosControlPanel\r  \r       Open the Kerberos Control Panel (if you can't calle KMLib because you're not\r   able to send events)\r*/\r        \rOSErr TKMS_OpenKerberosControlPanel (void);\r\r/*\r       TKF_SetHasCloseBox\r     \r       Set whether the floater has a close box or not\r*/\r      \rOSErr TKF_SetHasCloseBox (\r    Boolean         inHasCloseBox);\r\r/*\r    TKF_GetHasCloseBox\r     \r       return whether the floater has a close box or not\r*/\r   \rOSErr TKF_GetHasCloseBox (\r    Boolean*        outHasCloseBox);\r\r/*\r   TKF_SetDrawPies\r        \r       Set whether the floater draws pies for time remaining or not\r*/\r        \rOSErr TKF_SetDrawPies (\r       Boolean         inDrawPies);\r\r/*\r       TKF_GetDrawPies\r        \r       return whether the floater draws pies for time remaining or not\r*/\r     \rOSErr TKF_GetDrawPies (\r       Boolean*        outDrawPies);\r\r/*\r      TKF_SetIsVisible\r       \r       Set whether the floater is visible or not\r*/\r   \rOSErr TKF_SetIsVisible (\r      Boolean         inIsVisible);\r\r/*\r      TKF_GetIsVisible\r       \r       Return whether the floater is visible or not\r*/\r        \rOSErr TKF_GetIsVisible (\r      Boolean*        outIsVisible);\r\r/*\r     TKF_SetIsZoomedOut\r     \r       Set whether the floater is zoomed out or not\r*/\r        \rOSErr TKF_SetIsZoomedOut (\r    Boolean         inIsZoomedOut);\r\r/*\r    TKF_GetIsZoomedOut\r     \r       Return whether the floater is zoomed out or not\r*/\r     \rOSErr TKF_GetIsZoomedOut (\r    Boolean*        outIsZoomedOut);\r\r#endif /* !TARGET_API_MAC_CARBON */\r\r#ifdef PRAGMA_IMPORT_OFF\r#pragma import off\r#elif PRAGMA_IMPORT\r#pragma import reset\r#endif\r\r#ifdef __cplusplus\r}\r#endif\r\r/*\r * Constants\r */\r\renum {\r   keyDontQuit                             = FOUR_CHAR_CODE ('stay'),\r     keyStatus                               = FOUR_CHAR_CODE ('Stat')\r};\r\renum {\r   kTicketKeeperClass              = FOUR_CHAR_CODE ('TixK')\r};\r\renum {\r   kAEGetStatus                    = FOUR_CHAR_CODE ('Stat')\r};\r\renum {\r   kTicketKeeperSignature  = FOUR_CHAR_CODE ('TixK')\r};\r
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeperMenuStateProtocol.h b/mac/CommonKClient/mac_kclient3/Headers/TicketKeeper/TicketKeeperMenuStateProtocol.h
new file mode 100755 (executable)
index 0000000..1064938
--- /dev/null
@@ -0,0 +1 @@
+/*\r * TicketKeeperMenuStateProcotol.h\r *\r * Declarations of types for constants used in the Process-to-Process Communication\r * protocol used between TicketKeeperLib and TicketKeeper. This should not be used\r * by others\r *\r */\r \r#ifndef TicketKeeperMenuStateProcotol_h\r#define TicketKeeperMenuStateProcotol_h\r\r#if PRAGMA_STRUCT_ALIGN\r        #pragma options align=mac68k\r#elif PRAGMA_STRUCT_PACKPUSH\r      #pragma pack(push, 2)\r#elif PRAGMA_STRUCT_PACK\r #pragma pack(2)\r#endif\r\r/* Use these to find the PPC port for TicketKeeper */\renum {\r   mkPort_Creator = FOUR_CHAR_CODE ('MnuK'),\r      mkPort_Type = FOUR_CHAR_CODE ('appe')\r};\r       \r/* Use these on PPC blocks sent to TK. The block type determines what command you are sending */\renum {\r       mkBlock_Creator = FOUR_CHAR_CODE ('MnuK'),\r     mkBlock_Type_MenuState = FOUR_CHAR_CODE ('Menu'),\r      mkBlock_Type_SetDefault = FOUR_CHAR_CODE ('SDef'),\r     mkBlock_Type_Logout     = FOUR_CHAR_CODE ('LotP'),\r     mkBlock_Type_LogoutDefault      = FOUR_CHAR_CODE ('Lout'),\r     mkBlock_Type_NewLogin   = FOUR_CHAR_CODE ('Logn'),\r     mkBlock_Type_Renew      = FOUR_CHAR_CODE ('RnwP'),\r     mkBlock_Type_RenewDefault       = FOUR_CHAR_CODE ('Renw'),\r     mkBlock_Type_ChangePassword = FOUR_CHAR_CODE ('ChpP'),\r mkBlock_Type_ChangePasswordDefault = FOUR_CHAR_CODE ('Chps'),\r  mkBlock_Type_MoveFloaterStructureRegion = FOUR_CHAR_CODE ('MFst'),\r     mkBlock_Type_SetDrawPies        = FOUR_CHAR_CODE ('pie?'),\r     mkBlock_Type_SetHasCloseBox     = FOUR_CHAR_CODE ('cls?'),\r     mkBlock_Type_SetIsVisible       = FOUR_CHAR_CODE ('vis?'),\r     mkBlock_Type_SetIsZoomedOut     = FOUR_CHAR_CODE ('zum?'),\r     mkBlock_Type_GetIsVisible = FOUR_CHAR_CODE ('?vis'),\r   mkBlock_Type_GetDrawPies = FOUR_CHAR_CODE ('?pie'),\r    mkBlock_Type_GetHasCloseBox = FOUR_CHAR_CODE ('?cls'),\r mkBlock_Type_GetIsZoomedOut = FOUR_CHAR_CODE ('?zum'),\r mkBlock_Type_OpenKerberosControlPanel = FOUR_CHAR_CODE ('OKCP')\r};\r\r/* Version number for menu state command */\renum {\r mkReply_MenuState_CurrentVersion = 2\r};\r\r/*\r * MenuState ('Menu') command returns a blob of data in the following format:\r * (but you should really use the functions in TickerKeeperLib.h to parse it)\r *\r *   [4 Bytes]       Size of the structure\r *        [4 Bytes]       Version of the structure (current = 2)\r *\r *    [4 Bytes]       Last change time for the default cache information\r *   [4 Bytes]       Last change time for the cache list information\r *      [4 Bytes]       1 if default cache has valid tickets, 0 otherwise\r *    [4 bytes]       Expiration time of the default cache in Mac epoch\r *    [PString]       Principal of the default cache\r *  [PString]    Display principal of the default cache (quoting removed)\r *  [PString]  Short display principal of the default cache (quoting and default realm removed)\r *\r *  [4 Bytes]       Number of caches\r *\r *  [4 Bytes]       1 if the first cache is default\r *      [4 Bytes]       Version of the first cache\r *   [4 Bytes]       1 if the first cache has valid tickets\r *       [4 Bytes]       start time of the first cache\r *        [4 Bytes]       expiration time of the first cache\r *   [PString]       Principal of the 1st cache\r *  [PString]        Display principal if the 1st cache (quoting removed)\r *  [PString]      Short display principal if the 1st cache (quoting and default realm removed)\r *\r *         ...\r *\r *    [4 Bytes]       1 if the last cache is default\r *       [4 Bytes]       Version of the last cache\r *    [4 Bytes]       1 if the last cache has valid tickets\r *        [4 Bytes]       start time of the last cache\r * [4 Bytes]       expiration time of the last cache\r *    [PString]       Principal of the last cache\r *  [PString]       Display principal if the nth cache (quoting removed)\r *  [PString]      Short display principal if the nth cache (quoting and default realm removed)\r */\r\rstruct MenuStateHeader {\r     UInt32  version;\r       UInt32  defaultCacheLastChangeTime;\r    UInt32  cacheListLastChangeTime;\r       UInt32  defaultCacheHasValidTickets;\r   UInt32  defaultCacheExpiration;\r        Str255  defaultCachePrincipal;\r};\r\rstruct CacheEntry {\r UInt32  isDefault;\r     UInt32  version;\r       UInt32  isValid;\r       UInt32  startTime;\r     UInt32  expirationTime;\r        Str255  principal;\r};\r\rstruct CacheList {\r      UInt32          numCaches;\r     CacheEntry      cacheList;\r};\r\r/*\r * SetDefaultPrincipal, Logout, and Renew commands take a blob of data which contains the \r * new principal to be made default (version + string format)\r */\r \rstruct PrincipalParam {\r       UInt32          version;\r       Str255          principal;\r};\r\rstruct MoveFloaterStructureRegionParam {\r        Rect            bounds;\r};\r\rtypedef PrincipalParam SetDefaultParam;\rtypedef PrincipalParam LogoutParam;\rtypedef PrincipalParam RenewParam;\rtypedef PrincipalParam ChangePasswordParam;\r\rtypedef Boolean                 SetDrawPiesParam;\rtypedef Boolean                       SetHasCloseBoxParam;\rtypedef Boolean                    SetIsVisibleParam;\rtypedef Boolean                      SetIsZoomedOutParam;\r\r#if PRAGMA_STRUCT_ALIGN\r  #pragma options align=reset\r#elif PRAGMA_STRUCT_PACKPUSH\r       #pragma pack(pop)\r#elif PRAGMA_STRUCT_PACK\r     #pragma pack()\r#endif\r\r#endif /* TicketKeeperMenuStateProcotol_h */
\ No newline at end of file
diff --git a/mac/CommonKClient/mac_kclient3/kcglue_des.c b/mac/CommonKClient/mac_kclient3/kcglue_des.c
new file mode 100755 (executable)
index 0000000..46cdf73
--- /dev/null
@@ -0,0 +1,22 @@
+#include "des.h"
+#include "kcglue_des.h"
+
+/* $Id: kcglue_des.c,v 1.2 2001/12/04 02:05:35 rjs3 Exp $
+ * kclient and des have different definitions for key schedules
+ * this file is to include in the kclient code without dragging in the des definitions
+ */
+int kcglue_des_key_sched(void *akey,void *asched)
+{
+       return des_key_sched(akey,asched);
+}
+
+void kcglue_des_ecb_encrypt(void *asrc,void *adest,void *asched,int direction)
+{
+       des_ecb_encrypt(asrc,adest,asched,direction);
+}
+
+void kcglue_des_pcbc_encrypt(void *asrc,void *adest,long length,void *asched,void *akey,int direction)
+{
+       des_pcbc_encrypt(asrc,adest,length,asched,akey,direction);
+}
+
diff --git a/mac/CommonKClient/mac_kclient3/kcglue_des.h b/mac/CommonKClient/mac_kclient3/kcglue_des.h
new file mode 100755 (executable)
index 0000000..0233b26
--- /dev/null
@@ -0,0 +1,8 @@
+
+/* $Id: kcglue_des.h,v 1.2 2001/12/04 02:05:35 rjs3 Exp $
+ * kclient and des have different definitions for key schedules
+ * this file is to include in the kclient code without dragging in the des definitions
+ */
+int kcglue_des_key_sched(void *akey,void *asched);
+void kcglue_des_ecb_encrypt(void *asrc,void *adest,void *asched,int direction);
+void kcglue_des_pcbc_encrypt(void *asrc,void *adest,long length,void *asched,void *akey,int direction);
diff --git a/mac/CommonKClient/mac_kclient3/kcglue_krb.c b/mac/CommonKClient/mac_kclient3/kcglue_krb.c
new file mode 100755 (executable)
index 0000000..373d1ec
--- /dev/null
@@ -0,0 +1,164 @@
+/* $Id: kcglue_krb.c,v 1.3 2003/02/13 19:55:57 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.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <kcglue_krb.h>
+//#include "macKClientPublic.h"
+#include "KClient.h"
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define SOME_KRB_ERR_NUMBER (70)
+#define                MAX_KRB_ERRORS  256
+
+const char *krb_err_txt[MAX_KRB_ERRORS]={
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err",
+ "krb err","krb err","krb err","krb err","krb err","krb err","krb err","krb err"
+};
+
+
+/*
+ * given a service instance and realm, combine them to foo.bar@REALM
+ * return true upon success
+ */
+static int implode_krb_user_info(char *dst,const char *service,const char *instance,const char *realm)
+{
+       if(strlen(service)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       if(strlen(instance)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       if(strlen(realm)>=KCGLUE_ITEM_SIZE)
+               return FALSE;
+       strcpy(dst,service);
+       dst+=strlen(dst);
+       if(instance[0]!=0) {
+               *dst++='.';
+               strcpy(dst,instance);
+               dst+=strlen(dst);
+       }
+       *dst++='@';
+       strcpy(dst,realm);
+       return TRUE;
+}
+
+int kcglue_krb_mk_req(void *dat,int *len, const char *service, char *instance, char *realm, 
+          long checksum,
+          void *des_key,
+          char *pname,
+          char *pinst)
+{
+       char tkt_buf[KCGLUE_MAX_KTXT_LEN+20];
+       char user_id[KCGLUE_MAX_K_STR_LEN+1];
+       char dummy1[KCGLUE_MAX_K_STR_LEN+1], dummy2[KCGLUE_MAX_K_STR_LEN+1];
+       KClientSession ses;
+       KClientPrincipal prin, srvp;
+       int have_session=FALSE;
+       int rc;
+
+       if(!implode_krb_user_info(user_id,service,instance,realm))
+               return SOME_KRB_ERR_NUMBER;
+
+       rc=KClientNewClientSession(&ses/*,0,0,0,0*/ );
+       if(rc!=0)
+       return SOME_KRB_ERR_NUMBER;
+       have_session=TRUE;
+       
+    *len=sizeof(tkt_buf)-10;
+       //rc=KClientGetTicketForServiceFull(&ses,user_id,tkt_buf,len,checksum);
+       rc=KClientV4StringToPrincipal(user_id, &srvp);
+       if (rc==0)
+               rc=KClientSetServerPrincipal(ses,srvp);
+       if (rc==0)
+               rc=KClientGetTicketForService(ses,checksum,tkt_buf,len);
+       if(rc==0) {
+               memcpy(dat,tkt_buf/*+4*/,*len); /*kclient puts out a 4 byte length that mit doesnt*/
+               rc=KClientGetSessionKey(ses,des_key);
+       }
+       if(rc==0) {
+//             rc=KClientGetUserName(pname);
+               rc=KClientGetClientPrincipal(ses, &prin);
+               if (rc==0) {
+                       rc=KClientPrincipalToV4Triplet(prin, pname, dummy1, dummy2);
+                       KClientDisposePrincipal(prin);
+               }
+       }
+       *pinst=0;
+       if(have_session)
+       KClientDisposeSession(ses);
+  
+       if(rc!=0)
+               return SOME_KRB_ERR_NUMBER;
+       return 0;
+}
diff --git a/mac/CommonKClient/mac_kclient3/kcglue_krb.h b/mac/CommonKClient/mac_kclient3/kcglue_krb.h
new file mode 100755 (executable)
index 0000000..f604c2d
--- /dev/null
@@ -0,0 +1,23 @@
+/* $Id: kcglue_krb.h,v 1.2 2001/12/04 02:05:35 rjs3 Exp $
+ * mit kerberos and kclient include files are not compatable
+ * the define things with the same name but different implementations
+ * this is an interface that can be included with either kclient.h
+ * or krb.h.  It bridges between the two of them
+ */
+#define KCGLUE_ITEM_SIZE (40) /* name instance or realm size*/
+#define KCGLUE_MAX_K_STR_LEN (KCGLUE_ITEM_SIZE*3+2) /* id.instance@realm */
+#define        KCGLUE_MAX_KTXT_LEN     1250
+
+int kcglue_krb_mk_req(
+               void *dat,
+               int *len,
+               const char *service,
+               char *instance,
+               char *realm, 
+               long checksum,
+               void *des_key,
+               char *pname,
+               char *pinst
+               );
+          
diff --git a/mac/CommonKClient/mac_kclient3/mac_krb_lib1.c b/mac/CommonKClient/mac_kclient3/mac_krb_lib1.c
new file mode 100755 (executable)
index 0000000..0475370
--- /dev/null
@@ -0,0 +1,94 @@
+/* $Id: mac_krb_lib1.c,v 1.3 2003/02/13 19:55:57 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.
+ */
+/*
+ * library to emulate unix kerberos on a macintosh
+ */
+#include <config.h>
+#include <krb.h>
+#include <extra_krb.h>
+#include <kcglue_krb.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#include <stdio.h>
+
+/*
+ * given a hostname return the kerberos realm
+ * NOT thread safe....
+ */
+char *krb_realmofhost(const char *s)
+{
+       s=strchr(s,'.');
+       if(s==0)
+               return "ANDREW.CMU.EDU";
+       return (char *)(s+1);
+}
+
+/*
+ * return the default instance to use for a given hostname
+ * NOT thread safe... but then neathoer is the real kerberos one
+ */
+char *krb_get_phost(const char *alias)
+{
+#define MAX_HOST_LEN (512)
+    static char instance[MAX_HOST_LEN];
+    char *dst=instance;
+    int remaining=MAX_HOST_LEN-10;
+    while(remaining-->0) {
+       char ch= *alias++;
+       if(ch==0) break;
+       if(isupper(ch))
+               ch=tolower(ch);
+       if(ch=='.')
+               break;
+       *dst++=ch;
+    }
+    *dst=0;
+    return instance;
+}
diff --git a/mac/CommonKClient/mac_kclient3/saslk4.h b/mac/CommonKClient/mac_kclient3/saslk4.h
new file mode 100755 (executable)
index 0000000..5e7f769
--- /dev/null
@@ -0,0 +1,2 @@
+#define TARGET_API_MAC_OS8 1
+#define TARGET_API_MAC_CARBON 1
diff --git a/mac/README.filetypes b/mac/README.filetypes
new file mode 100644 (file)
index 0000000..8ebc7c8
--- /dev/null
@@ -0,0 +1,3 @@
+CodeWarrior will not recognize files with type other than 'TEXT'
+as valid source code or headers, and there appears to be no workaround.
+Please read the file doc/macosx.html for more information.
diff --git a/mac/build_plugins/build_plugins b/mac/build_plugins/build_plugins
new file mode 100755 (executable)
index 0000000..6ec8f2e
Binary files /dev/null and b/mac/build_plugins/build_plugins differ
diff --git a/mac/build_plugins/build_plugins.Carbon b/mac/build_plugins/build_plugins.Carbon
new file mode 100755 (executable)
index 0000000..8f041d2
Binary files /dev/null and b/mac/build_plugins/build_plugins.Carbon differ
diff --git a/mac/include/config.h b/mac/include/config.h
new file mode 100755 (executable)
index 0000000..35a3c66
--- /dev/null
@@ -0,0 +1,273 @@
+/* $Id: config.h,v 1.4 2004/03/08 16:57:27 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 CONFIG_H
+#define CONFIG_H
+
+//#ifdef XSUS
+//#include <windows.h>
+//#endif
+
+#include <string.h>
+
+/*
+ * funky names for functions so we dont conflict with possible
+ * real ones in applications we load into
+ */
+
+#define htons
+#define htonl
+#define ntohl
+#define ntohs
+#define strdup xxx_sasl_strdup
+#define strcasecmp xxx_sasl_strcasecmp
+#define gethostname xxx_sasl_gethostname
+#define inet_aton xxx_sasl_inetaton
+
+/* Our package */
+#define PACKAGE "cyrus-sasl"
+
+/* Our version */
+#define VERSION "2.0.4"
+
+/* We only want minimal server functionality.  Cripple the server functionality when necessary to get
+ * things to compile.
+ *
+ * Currently only cripples PLAIN.
+ */
+#define SASL_MINIMAL_SERVER 1
+
+/* DB Type */
+#undef SASL_DB_TYPE
+
+int strcasecmp(const char *s1,const char *s2);
+int strncasecmp(const char *s1,const char *s2,int len);
+
+int strcpy_truncate(char *dest,char *src,int len);
+
+#define gethostname xxx_sasl_gethostname
+int gethostname(char *dest,int destlen);
+
+#define SASL_PATH_ENV_VAR "foo"
+#define PLUGINDIR "make_me_a_function_to_get_that_info"
+
+typedef unsigned char u_char;
+typedef unsigned long u_long;
+
+char *strdup(const char *str);
+ struct sockaddr_in {
+       u_char  sin_len;
+       u_char  sin_family;
+   unsigned short sin_port;
+   union {
+        unsigned long s_addr;
+   } sin_addr;
+   char sin_zero[8];
+ };
+
+struct in_addr {
+       unsigned long s_addr;
+};
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#include "gai.h"
+
+#ifndef NULL
+#define NULL (0L)
+#endif
+
+#ifdef RUBBISH
+int snprintf (char *str,size_t count,const char *fmt,...);
+int snprintf (char *str,int count,const char *fmt,...);
+#endif
+
+extern char *optarg;
+extern int optind;
+extern int getopt(
+       int nargc,
+       char * const *nargv,
+       const char *ostr);
+
+extern int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+extern char* getpass(const char *prompt);
+
+/* ------------------------------------------------------------ */
+
+/* Things that are fetched via autoconf under Unix
+ */
+#define HAVE_MEMCPY 1
+
+#define MAXHOSTNAMELEN 1024
+
+/* ------------------------------------------------------------ */
+
+#define WITHOUT_NANA
+#define L_DEFAULT_GUARD (0)
+#define I_DEFAULT_GUARD (0)
+#define I(foo)
+#ifdef RUBBISH
+//#define VL(foo)
+#endif
+#include <stdio.h>
+#define XXVL(foo)  printf foo;
+#define VL(foo)
+#define VLP(foo,bar)
+
+#define __attribute__(foo)
+
+#include <netinet/in.h>
+
+#define getservbyname(X,Y) NULL
+struct servent {
+       int s_port;
+};
+
+struct sockaddr {
+        u_char  sa_len;                 /* total length */
+        u_char  sa_family;              /* address family */
+        char    sa_data[14];            /* address value */
+}; 
+#define SOCK_MAXADDRLEN 255             /* longest possible addresses */
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#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 */
+
+#define get_krb_err_txt(X) (krb_err_txt[(X)])
+
+/*
+ * Address families.
+ */
+#define AF_UNSPEC       0               /* unspecified */
+#define AF_UNIX         1               /* local to host (pipes, portals) */
+#define AF_INET         2               /* internetwork: UDP, TCP, etc. */
+#define AF_IMPLINK      3               /* arpanet imp addresses */
+#define AF_PUP          4               /* pup protocols: e.g. BSP */
+#define AF_CHAOS        5               /* mit CHAOS protocols */
+#define AF_NS           6               /* XEROX NS protocols */
+#define AF_NBS          7               /* nbs protocols */
+#define AF_ECMA         8               /* european computer manufacturers */
+#define AF_DATAKIT      9               /* datakit protocols */
+#define AF_CCITT        10              /* CCITT protocols, X.25 etc */
+#define AF_SNA          11              /* IBM SNA */
+#define AF_DECnet       12              /* DECnet */
+#define AF_DLI          13              /* Direct data link interface */
+#define AF_LAT          14              /* LAT */
+#define AF_HYLINK       15              /* NSC Hyperchannel */
+#define AF_APPLETALK    16              /* Apple Talk */
+#define AF_NIT          17              /* Network Interface Tap */
+#define AF_802          18              /* IEEE 802.2, also ISO 8802 */
+#define AF_OSI          19              /* umbrella for all families used */
+#define AF_X25          20              /* CCITT X.25 in particular */
+#define AF_OSINET       21              /* AFI = 47, IDI = 4 */
+#define AF_GOSIP        22              /* U.S. Government OSI */
+#define AF_IPX          23              /* Novell Internet Protocol */
+#define AF_ROUTE        24              /* Internal Routing Protocol */
+#define AF_LINK         25              /* Link-layer interface */
+#define AF_INET6        26              /* Internet Protocol, Version 6 */
+#define AF_KEY          27              /* Security Association DB socket */
+
+#define AF_MAX          27
+
+/*
+ * Protocol families, same as address families for now.
+ */
+#define PF_UNSPEC       AF_UNSPEC
+#define PF_UNIX         AF_UNIX
+#define PF_INET         AF_INET
+#define PF_IMPLINK      AF_IMPLINK
+#define PF_PUP          AF_PUP
+#define PF_CHAOS        AF_CHAOS
+#define PF_NS           AF_NS
+#define PF_NBS          AF_NBS
+#define PF_ECMA         AF_ECMA
+#define PF_DATAKIT      AF_DATAKIT
+#define PF_CCITT        AF_CCITT
+#define PF_SNA          AF_SNA
+#define PF_DECnet       AF_DECnet
+#define PF_DLI          AF_DLI
+#define PF_LAT          AF_LAT
+#define PF_HYLINK       AF_HYLINK
+#define PF_APPLETALK    AF_APPLETALK
+#define PF_NIT          AF_NIT
+#define PF_802          AF_802
+#define PF_OSI          AF_OSI
+#define PF_X25          AF_X25
+#define PF_OSINET       AF_OSINET
+#define PF_GOSIP        AF_GOSIP
+#define PF_IPX          AF_IPX
+#define PF_ROUTE        AF_ROUTE
+#define PF_LINK         AF_LINK
+#define PF_INET6        AF_INET6
+#define PF_KEY          AF_KEY
+
+#define PF_MAX          AF_MAX
+
+#define SOCK_STREAM            1
+#define SOCK_DGRAM             2
+
+struct iovec {
+    char *iov_base; 
+    long iov_len;
+};      
+
+#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
+
+#endif /* CONFIG_H */
diff --git a/mac/include/extra_krb.h b/mac/include/extra_krb.h
new file mode 100755 (executable)
index 0000000..b42894d
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * declarations missing from unix krb.h
+ */
+
+
+int xxx_krb_mk_priv(void *inp,
+       void *outp,
+       unsigned inplen,
+       des_key_schedule init_keysched,
+       des_cblock *session,
+       struct sockaddr_in *iplocal,
+       struct sockaddr_in *ipremote);
+
+
+int xxx_krb_rd_priv(char *buf,
+       int inplen,
+       des_key_schedule init_keysched,
+       des_cblock *session,
+       struct sockaddr_in *iplocal,
+       struct sockaddr_in *ipremote,
+       MSG_DAT *data);
+
+#ifdef RUBBISH
+#include <kcglue_des.h>
+
+#define des_key_sched kcglue_des_key_sched
+#define des_ecb_encrypt kcglue_des_ecb_encrypt
+#define des_pcbc_encrypt kcglue_des_pcbc_encrypt
+
+#ifndef DES_ENCRYPT
+#define DES_ENCRYPT 0
+#endif
+#ifndef DES_DECRYPT
+#define DES_DECRYPT 1
+#endif
+#endif
\ No newline at end of file
diff --git a/mac/include/md5global.h b/mac/include/md5global.h
new file mode 100755 (executable)
index 0000000..b146b27
--- /dev/null
@@ -0,0 +1,38 @@
+/* GLOBAL.H - RSAREF types and constants
+ */
+#ifndef MD5GLOBAL_H
+#define MD5GLOBAL_H
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+  function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+  been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+typedef signed char 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/mac/include/netinet/in.h b/mac/include/netinet/in.h
new file mode 100755 (executable)
index 0000000..591d3c8
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _SASL_NETINET_IN_H
+#define _SASL_NETINET_IN_H
+
+struct  hostent {
+        char    *h_name;        /* official name of host */ 
+        char    **h_aliases;    /* alias list */
+        int     h_addrtype;     /* host address type */
+        int     h_length;       /* length of address */
+        char    **h_addr_list;  /* list of addresses from name server */
+#define h_addr  h_addr_list[0]  /* address, for backward compatiblity */
+};
+
+struct hostent *gethostbyname(const char *hnam);
+
+#define IPPROTO_UDP 17
+#define IPPROTO_TCP 6
+#endif
diff --git a/mac/include/parse_cmd_line.h b/mac/include/parse_cmd_line.h
new file mode 100755 (executable)
index 0000000..ebf9fc1
--- /dev/null
@@ -0,0 +1,6 @@
+/*
+ * mac doesnt have a command line to read
+ * prompt for one
+ */
+
+int parse_cmd_line(int max_argc,char **argv,int line_size,char *line);
diff --git a/mac/include/sasl_anonymous_plugin_decl.h b/mac/include/sasl_anonymous_plugin_decl.h
new file mode 100755 (executable)
index 0000000..ed3b1e4
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef SASL_MONOLITHIC
+#define sasl_server_plug_init anonymous_sasl_server_plug_init
+#define sasl_client_plug_init anonymous_sasl_client_plug_init
+#endif
+#include <sasl_plugin_decl.h>
diff --git a/mac/include/sasl_crammd5_plugin_decl.h b/mac/include/sasl_crammd5_plugin_decl.h
new file mode 100755 (executable)
index 0000000..285bad2
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef SASL_MONOLITHIC
+#define sasl_server_plug_init cram_sasl_server_plug_init
+#define sasl_client_plug_init cram_sasl_client_plug_init
+#endif
+#include <sasl_plugin_decl.h>
diff --git a/mac/include/sasl_digestmd5_plugin_decl.h b/mac/include/sasl_digestmd5_plugin_decl.h
new file mode 100755 (executable)
index 0000000..b7a0bbb
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef SASL_MONOLITHIC
+#define sasl_server_plug_init md5_sasl_server_plug_init
+#define sasl_client_plug_init md5_sasl_client_plug_init
+#endif
+#include <sasl_plugin_decl.h>
diff --git a/mac/include/sasl_kerberos4_plugin_decl.h b/mac/include/sasl_kerberos4_plugin_decl.h
new file mode 100755 (executable)
index 0000000..9348d76
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef SASL_MONOLITHIC
+#define sasl_server_plug_init kerberos4_sasl_server_plug_init
+#define sasl_client_plug_init kerberos4_sasl_client_plug_init
+#endif
+#include <sasl_plugin_decl.h>
diff --git a/mac/include/sasl_mac_krb_locl.h b/mac/include/sasl_mac_krb_locl.h
new file mode 100755 (executable)
index 0000000..0536300
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * mac replacement for mit krb_locl.h
+ */
+
+#define RCSID(xxx) static char *xxrcs=xxx
+#define xxu_int32_t unsigned long
+#define xxint32_t long
+#define xxint16_t short
+
+#include <config.h>
+#include <krb.h>
+#include <prot.h>
+
+struct timeval {
+       time_t tv_sec;
+       long tv_usec;
+};
+#define gettimeofday yyy_gettimeofday
+int gettimeofday(struct timeval *tp, void *);
+
+#define swab yyy_swab
+void swab(char *a, char *b,int len);
+
+/*
+ * printf a warning
+ */
+void krb_warning(const char *fmt,...);
+
+#define inet_ntoa yyy_inet_netoa
+char *inet_ntoa(unsigned long);
+
+void encrypt_ktext(KTEXT cip,des_cblock *key,int encrypt);
+
+#define DES_QUAD_GUESS 0
+#define DES_QUAD_NEW 1
+#define DES_QUAD_OLD 2
+#define DES_QUAD_DEFAULT DES_QUAD_GUESS
+
+void
+fixup_quad_cksum(void *start, size_t len, des_cblock *key, 
+                void *new_checksum, void *old_checksum, int little);
+                
+#define abs yyy_abs
+int abs(int x);
+
+#ifdef RUBBISH
+#include <krb-protos.h>
+#endif
+
+#include <time.h>
diff --git a/mac/include/sasl_plain_plugin_decl.h b/mac/include/sasl_plain_plugin_decl.h
new file mode 100755 (executable)
index 0000000..1020e12
--- /dev/null
@@ -0,0 +1,5 @@
+#ifdef SASL_MONOLITHIC
+#define sasl_server_plug_init plain_sasl_server_plug_init
+#define sasl_client_plug_init plain_sasl_client_plug_init
+#endif
+#include <sasl_plugin_decl.h>
diff --git a/mac/include/sasl_plugin_decl.h b/mac/include/sasl_plugin_decl.h
new file mode 100755 (executable)
index 0000000..51c4058
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * i guess the unix computer isnt picky about undeclared functions
+ * should build with gcc with warn all
+ */
+#if defined(macintosh) && (!defined(SASL_MONOLITHIC))
+#pragma export on
+#define SASL_TURN_OFF_PLUGIN_EXPORT
+#endif
+sasl_server_plug_init_t sasl_server_plug_init;
+sasl_client_plug_init_t sasl_client_plug_init;
+#ifdef SASL_TURN_OFF_PLUGIN_EXPORT
+#pragma export reset
+#undef SASL_TURN_OFF_PLUGIN_EXPORT
+#endif
+
+#ifdef rubbish
+int sasl_server_plug_init(sasl_utils_t *utils __attribute__((unused)),
+                         int maxversion,
+                         int *out_version,
+                         const sasl_server_plug_t **pluglist,
+                         int *plugcount);
+
+int sasl_client_plug_init(sasl_utils_t *utils __attribute__((unused)),
+                         int maxversion,
+                         int *out_version,
+                         const sasl_client_plug_t **pluglist,
+                         int *plugcount);
+#endif
\ No newline at end of file
diff --git a/mac/kerberos_includes/conf-svsparc.h b/mac/kerberos_includes/conf-svsparc.h
new file mode 100755 (executable)
index 0000000..15261f6
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 1991, by Sun Microsystems, Inc.
+ */
+
+#ifndef        _KERBEROS_CONF_SVSPARC_H
+#define        _KERBEROS_CONF_SVSPARC_H
+
+#pragma ident  "@(#)conf-svsparc.h     1.5     92/07/14 SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Machine-type definitions: SPARC with SYSV Unix, e.g. SUN-4
+ */
+
+#define        BITS32
+#define        BIG
+#define        MSBFIRST
+/* #define BSDUNIX */
+#define        MUSTALIGN
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_CONF_SVSPARC_H */
diff --git a/mac/kerberos_includes/conf.h b/mac/kerberos_includes/conf.h
new file mode 100755 (executable)
index 0000000..53fa1dc
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/conf.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/conf.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Configuration info for operating system, hardware description,
+ * language implementation, C library, etc.
+ *
+ * This file should be included in (almost) every file in the Kerberos
+ * sources, and probably should *not* be needed outside of those
+ * sources.  (How do we deal with /usr/include/des.h and
+ * /usr/include/krb.h?)
+ */
+
+#ifndef        _KERBEROS_CONF_H
+#define        _KERBEROS_CONF_H
+
+#pragma ident  "@(#)conf.h     1.5     93/02/04 SMI"
+
+#include <kerberos/mit-copyright.h>
+
+#include <kerberos/osconf.h>
+
+#ifdef SHORTNAMES
+#include <kerberos/names.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Language implementation-specific definitions
+ */
+
+/* special cases */
+#ifdef __HIGHC__
+/* broken implementation of ANSI C */
+#undef __STDC__
+#endif
+
+#ifndef __STDC__
+#define        const
+#define        volatile
+#define        signed
+typedef char *pointer;         /* pointer to generic data */
+#define        PROTOTYPE(p) ()
+#else
+typedef void *pointer;
+#define        PROTOTYPE(p) p
+#endif
+
+/* Does your compiler understand "void"? */
+#ifdef notdef
+#define        void int
+#endif
+
+/*
+ * A few checks to see that necessary definitions are included.
+ */
+
+/* byte order */
+
+#ifndef MSBFIRST
+#ifndef LSBFIRST
+/* #error byte order not defined */
+Error: byte order not defined.
+#endif
+#endif
+
+/* machine size */
+#ifndef BITS16
+#ifndef BITS32
+Error: how big is this machine anyways?
+#endif
+#endif
+
+/* end of checks */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_CONF_H */
diff --git a/mac/kerberos_includes/error_table.h b/mac/kerberos_includes/error_table.h
new file mode 100755 (executable)
index 0000000..0e32543
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 1991, by Sun Microsystems, Inc.
+ */
+
+#ifndef        _KERBEROS_ERROR_TABLE_H
+#define        _KERBEROS_ERROR_TABLE_H
+
+#pragma ident  "@(#)error_table.h      1.4     93/08/30 SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       char    **msgs;
+       int     base;
+       int     n_msgs;
+} error_table;
+extern error_table **_et_list;
+
+#define        ERROR_CODE      "int"   /* type used for error codes */
+
+#define        ERRCODE_RANGE   8       /* # of bits to shift table number */
+#define        BITS_PER_CHAR   6       /* # bits to shift per character in name */
+
+extern char *error_table_name();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_ERROR_TABLE_H */
diff --git a/mac/kerberos_includes/kerberos/des.h b/mac/kerberos_includes/kerberos/des.h
new file mode 100755 (executable)
index 0000000..8259874
--- /dev/null
@@ -0,0 +1,317 @@
+/* crypto/des/des.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@mincom.oz.au).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@mincom.oz.au).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@mincom.oz.au)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#if (defined(__MWERKS__)&&defined(__MC68K__)&&(!defined(DESLIB_CFM68K_NO_IMPORTS)))
+#pragma import on
+#define UNDO_CFM68K_IMPORT
+#endif
+
+#ifndef DES_LIB_FUNCTION
+#if defined(__BORLANDC__)
+#define DES_LIB_FUNCTION /* not-ready-definition-yet */
+#elif defined(_MSC_VER)
+#define DES_LIB_FUNCTION /* not-ready-definition-yet2 */
+#else
+#define DES_LIB_FUNCTION
+#endif
+#endif
+
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#if defined(__alpha)
+#define DES_LONG unsigned int
+#else /* Not a 64 bit machine */
+#define DES_LONG unsigned long
+#endif
+#endif
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct
+       {
+       union   {
+               des_cblock _;
+               /* make sure things are correct size on machines with
+                * 8 byte longs */
+               DES_LONG pad[2];
+               } ks;
+#undef _
+#define _      ks._
+       } des_key_schedule[16];
+
+#define DES_KEY_SZ     (sizeof(des_cblock))
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
+
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#define DES_CBC_MODE   0
+#define DES_PCBC_MODE  1
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+       des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+       des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+       des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+       des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#ifdef KERBEROS
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#endif
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set_key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define ncbc_encrypt des_ncbc_encrypt
+#define xcbc_encrypt des_xcbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef des_key_schedule bit_64;
+#define des_fixup_key_parity des_set_odd_parity
+#define des_check_key_parity check_parity
+
+extern int des_check_key;      /* defaults to false */
+extern int des_rw_mode;                /* defaults to DES_PCBC_MODE */
+
+#ifdef cplusplus
+extern "C" {
+#endif
+
+/* The next line is used to disable full ANSI prototypes, if your
+ * compiler has problems with the prototypes, make sure this line always
+ * evaluates to true :-) */
+#if defined(MSDOS) || defined(__STDC__)
+#undef NOPROTO
+#endif
+#ifndef NOPROTO
+char *DES_LIB_FUNCTION des_options(void);
+void DES_LIB_FUNCTION des_ecb3_encrypt(des_cblock *input,des_cblock *output,
+       des_key_schedule ks1,des_key_schedule ks2,
+       des_key_schedule ks3, int enc);
+DES_LONG DES_LIB_FUNCTION des_cbc_cksum(des_cblock *input,des_cblock *output,
+       long length,des_key_schedule schedule,des_cblock *ivec);
+void DES_LIB_FUNCTION des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,
+       des_cblock *inw,des_cblock *outw,int enc);
+void DES_LIB_FUNCTION des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule sk1,des_key_schedule sk2,
+       des_cblock *ivec1,des_cblock *ivec2,int enc);
+void DES_LIB_FUNCTION des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+       long length,des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_ecb_encrypt(des_cblock *input,des_cblock *output,
+       des_key_schedule ks,int enc);
+void DES_LIB_FUNCTION des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
+void DES_LIB_FUNCTION des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
+void DES_LIB_FUNCTION des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+       des_key_schedule ks2, des_key_schedule ks3);
+void DES_LIB_FUNCTION des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+       des_key_schedule ks2, des_key_schedule ks3);
+void DES_LIB_FUNCTION des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, 
+       long length, des_key_schedule ks1, des_key_schedule ks2, 
+       des_key_schedule ks3, des_cblock *ivec, int enc);
+void DES_LIB_FUNCTION des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+       long length, des_key_schedule ks1, des_key_schedule ks2,
+       des_key_schedule ks3, des_cblock *ivec, int *num, int encrypt);
+void DES_LIB_FUNCTION des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+       long length, des_key_schedule ks1, des_key_schedule ks2,
+       des_key_schedule ks3, des_cblock *ivec, int *num);
+
+int DES_LIB_FUNCTION des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
+       des_cblock *iv);
+int DES_LIB_FUNCTION des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
+       des_cblock *iv);
+char *DES_LIB_FUNCTION des_fcrypt(const char *buf,const char *salt, char *ret);
+#ifdef PERL5
+char *des_crypt(const char *buf,const char *salt);
+#else
+/* some stupid compilers complain because I have declared char instead
+ * of const char */
+#ifdef HEADER_DES_LOCL_H
+char *DES_LIB_FUNCTION crypt(const char *buf,const char *salt);
+#else
+char *crypt();
+#endif
+#endif
+void DES_LIB_FUNCTION des_ofb_encrypt(unsigned char *in,unsigned char *out,
+       int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
+void DES_LIB_FUNCTION des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+DES_LONG DES_LIB_FUNCTION des_quad_cksum(des_cblock *input,des_cblock *output,
+       long length,int out_count,des_cblock *seed);
+void DES_LIB_FUNCTION des_random_seed(des_cblock key);
+void DES_LIB_FUNCTION des_random_key(des_cblock ret);
+int DES_LIB_FUNCTION des_read_password(des_cblock *key,char *prompt,int verify);
+int DES_LIB_FUNCTION des_read_2passwords(des_cblock *key1,des_cblock *key2,
+       char *prompt,int verify);
+int DES_LIB_FUNCTION des_read_pw_string(char *buf,int length,char *prompt,int verify);
+void DES_LIB_FUNCTION des_set_odd_parity(des_cblock *key);
+int DES_LIB_FUNCTION des_is_weak_key(des_cblock *key);
+int DES_LIB_FUNCTION des_set_key(des_cblock *key,des_key_schedule schedule);
+int DES_LIB_FUNCTION des_key_sched(des_cblock *key,des_key_schedule schedule);
+void DES_LIB_FUNCTION des_string_to_key(char *str,des_cblock *key);
+void DES_LIB_FUNCTION des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
+void DES_LIB_FUNCTION des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+       des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
+void DES_LIB_FUNCTION des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+       des_key_schedule schedule, des_cblock *ivec, int *num);
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+void DES_LIB_FUNCTION des_cblock_print_file(des_cblock *cb, FILE *fp);
+/* The following functions are not in the normal unix build or the
+ * SSLeay build.  When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+int DES_LIB_FUNCTION des_new_random_key(des_cblock *key);
+void DES_LIB_FUNCTION des_init_random_number_generator(des_cblock *key);
+void DES_LIB_FUNCTION des_set_random_generator_seed(des_cblock *key);
+void DES_LIB_FUNCTION des_set_sequence_number(des_cblock new_sequence_number);
+void DES_LIB_FUNCTION des_generate_random_block(des_cblock *block);
+void DES_LIB_FUNCTION des_rand_data(unsigned char *data, int size);
+
+#else
+
+char *des_options();
+void des_ecb3_encrypt();
+DES_LONG des_cbc_cksum();
+void des_cbc_encrypt();
+void des_ncbc_encrypt();
+void des_xcbc_encrypt();
+void des_3cbc_encrypt();
+void des_cfb_encrypt();
+void des_ede3_cfb64_encrypt();
+void des_ede3_ofb64_encrypt();
+void des_ecb_encrypt();
+void des_encrypt();
+void des_encrypt2();
+void des_encrypt3();
+void des_decrypt3();
+void des_ede3_cbc_encrypt();
+int des_enc_read();
+int des_enc_write();
+char *des_fcrypt();
+#ifdef PERL5
+char *des_crypt();
+#else
+char *crypt();
+#endif
+void des_ofb_encrypt();
+void des_pcbc_encrypt();
+DES_LONG des_quad_cksum();
+void des_random_seed();
+void des_random_key();
+int des_read_password();
+int des_read_2passwords();
+int des_read_pw_string();
+void des_set_odd_parity();
+int des_is_weak_key();
+int des_set_key();
+int des_key_sched();
+void des_string_to_key();
+void des_string_to_2keys();
+void des_cfb64_encrypt();
+void des_ofb64_encrypt();
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+void des_cblock_print_file();
+/* The following functions are not in the normal unix build or the
+ * SSLeay build.  When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+int des_new_random_key();
+void des_init_random_number_generator();
+void des_set_random_generator_seed();
+void des_set_sequence_number();
+void des_generate_random_block();
+void des_rand_data();
+
+#endif
+
+#ifdef UNDO_CFM68K_IMPORT
+#pragma import reset
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mac/kerberos_includes/kerberos/des.h.unix b/mac/kerberos_includes/kerberos/des.h.unix
new file mode 100755 (executable)
index 0000000..9468e0c
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/kerberos/des.h.unix,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/kerberos/des.h.unix,v 1.2 2001/12/04 02:06:07 rjs3 Exp $
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file for the Data Encryption Standard library.
+ */
+
+#ifndef        _KERBEROS_DES_H
+#define        _KERBEROS_DES_H
+
+/* #pragma ident       "@(#)des.h      1.5     93/05/27 SMI" */
+
+#include <kerberos/mit-copyright.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char des_cblock[8];   /* crypto-block size */
+/* Key schedule */
+typedef struct des_ks_struct { des_cblock _; } des_key_schedule[16];
+
+#define        DES_KEY_SZ      (sizeof (des_cblock))
+#define        KRBDES_ENCRYPT  1
+#define        KRBDES_DECRYPT  0
+
+#ifndef NCOMPAT
+#define        C_Block des_cblock
+#define        Key_schedule des_key_schedule
+#define        ENCRYPT KRBDES_ENCRYPT
+#define        DECRYPT KRBDES_DECRYPT
+#define        KEY_SZ DES_KEY_SZ
+#define        string_to_key des_string_to_key
+#define        read_pw_string des_read_pw_string
+#define        random_key des_random_key
+#define        pcbc_encrypt des_pcbc_encrypt
+#define        key_sched des_key_sched
+#define        cbc_encrypt des_cbc_encrypt
+#define        cbc_cksum des_cbc_cksum
+#define        C_Block_print des_cblock_print
+#define        quad_cksum des_quad_cksum
+typedef struct des_ks_struct bit_64;
+#endif
+
+#define        des_cblock_print(x) des_cblock_print_file(x, stdout)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_DES_H */
diff --git a/mac/kerberos_includes/kerberos/mit-copyright.h b/mac/kerberos_includes/kerberos/mit-copyright.h
new file mode 100755 (executable)
index 0000000..5044c89
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *     Copyright (C) 1989 by the Massachusetts Institute of Technology
+ *
+ *     Export of this software from the United States of America is assumed
+ *     to require a specific license from the United States Government.
+ *     It is the responsibility of any person or organization contemplating
+ *     export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ */
+
+#ifndef        _KERBEROS_MIT_COPYRIGHT_H
+#define        _KERBEROS_MIT_COPYRIGHT_H
+
+/* #pragma ident       "@(#)mit-copyright.h    1.4     93/02/04 SMI" */
+
+#endif /* _KERBEROS_MIT_COPYRIGHT_H */
diff --git a/mac/kerberos_includes/klog.h b/mac/kerberos_includes/klog.h
new file mode 100755 (executable)
index 0000000..1460ee2
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/klog.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/klog.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This file defines the types of log messages logged by klog.  Each
+ * type of message may be selectively turned on or off.
+ */
+
+#ifndef        _KERBEROS_KLOG_H
+#define        _KERBEROS_KLOG_H
+
+#pragma ident  "@(#)klog.h     1.3     92/07/14 SMI"
+
+#include <kerberos/mit-copyright.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define        KRBLOG          "/kerberos/kerberos.log"  /* master server  */
+#define        KRBSLAVELOG     "/kerberos/kerberos_slave.log"  /* master server  */
+#define        NLOGTYPE        100     /* Maximum number of log msg types  */
+
+#define        L_NET_ERR         1     /* Error in network code            */
+#define        L_NET_INFO        2     /* Info on network activity         */
+#define        L_KRB_PERR        3     /* Kerberos protocol errors         */
+#define        L_KRB_PINFO       4     /* Kerberos protocol info           */
+#define        L_INI_REQ         5     /* Request for initial ticket       */
+#define        L_NTGT_INTK       6     /* Initial request not for TGT      */
+#define        L_DEATH_REQ       7     /* Request for server death         */
+#define        L_TKT_REQ         8     /* All ticket requests using a tgt  */
+#define        L_ERR_SEXP        9     /* Service expired                  */
+#define        L_ERR_MKV        10     /* Master key version incorrect     */
+#define        L_ERR_NKY        11     /* User's key is null               */
+#define        L_ERR_NUN        12     /* Principal not unique             */
+#define        L_ERR_UNK        13     /* Principal Unknown                */
+#define        L_ALL_REQ        14     /* All requests                     */
+#define        L_APPL_REQ       15     /* Application requests (using tgt) */
+#define        L_KRB_PWARN      16     /* Protocol warning messages        */
+
+char   *klog();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_KLOG_H */
diff --git a/mac/kerberos_includes/kparse.h b/mac/kerberos_includes/kparse.h
new file mode 100755 (executable)
index 0000000..c07c7e4
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/kparse.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/kparse.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file for kparse routines.
+ */
+
+#ifndef        _KERBEROS_KPARSE_H
+#define        _KERBEROS_KPARSE_H
+
+#pragma ident  "@(#)kparse.h   1.4     93/11/01 SMI"
+
+#include <kerberos/mit-copyright.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * values returned by fGetParameterSet()
+ */
+
+#define        PS_BAD_KEYWORD    -2    /* unknown or duplicate keyword */
+#define        PS_SYNTAX         -1    /* syntax error */
+#define        PS_OKAY            0    /* got a complete parameter set */
+#define        PS_EOF             1    /* nothing more in the file */
+
+/*
+ * values returned by fGetKeywordValue()
+ */
+
+#define        KV_SYNTAX        -2     /* syntax error */
+#define        KV_EOF           -1     /* nothing more in the file */
+#define        KV_OKAY           0     /* got a keyword/value pair */
+#define        KV_EOL            1     /* nothing more on this line */
+
+/*
+ * values returned by fGetToken()
+ */
+
+#define        GTOK_BAD_QSTRING -1     /* newline found in quoted string */
+#define        GTOK_EOF          0     /* end of file encountered */
+#define        GTOK_QSTRING      1     /* quoted string */
+#define        GTOK_STRING       2     /* unquoted string */
+#define        GTOK_NUMBER       3     /* one or more digits */
+#define        GTOK_PUNK         4     /* punks are punctuation, newline, etc. */
+#define        GTOK_WHITE        5     /* one or more whitespace chars */
+
+/*
+ * extended character classification macros
+ */
+
+#define        ISOCTAL(CH)     ((CH >= '0') && (CH <= '7'))
+#define        ISQUOTE(CH)     ((CH == '\"') || (CH == '\'') || (CH == '`'))
+#define        ISWHITESPACE(C) ((C == ' ') || (C == '\t'))
+#define        ISLINEFEED(C)   ((C == '\n') || (C == '\r') || (C == '\f'))
+
+/*
+ * tokens consist of any printable charcacter except comma, equal, or
+ * whitespace
+ */
+
+#define        ISTOKENCHAR(C) ((C > 040) && (C < 0177) && (C != ',') && (C != '='))
+
+/*
+ * the parameter table defines the keywords that will be recognized by
+ * fGetParameterSet, and their default values if not specified.
+ */
+
+typedef struct {
+       char *keyword;
+       char *defvalue;
+       char *value;
+} parmtable;
+
+#define        PARMCOUNT(P) (sizeof (P)/sizeof (P[0]))
+
+extern int LineNbr;            /* current line # in parameter file */
+
+extern char ErrorMsg[];                /* meaningful only when KV_SYNTAX, */
+                               /* PS_SYNTAX,  or PS_BAD_KEYWORD is */
+                               /* returned by fGetKeywordValue or */
+                               /* fGetParameterSet */
+
+extern char *strsave();                /* defined in this module */
+extern char *strutol();                /* defined in this module */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_KPARSE_H */
diff --git a/mac/kerberos_includes/krb-protos.h b/mac/kerberos_includes/krb-protos.h
new file mode 100755 (executable)
index 0000000..bc63eb2
--- /dev/null
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * 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. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id: krb-protos.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $ */
+
+#ifndef __krb_protos_h__
+#define __krb_protos_h__
+
+#if defined (__STDC__) || defined (_MSC_VER)
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+#ifdef __STDC__
+struct in_addr;
+struct sockaddr_in;
+struct timeval;
+#endif
+
+#ifndef KRB_LIB_FUNCTION
+#if defined(__BORLANDC__)
+#define KRB_LIB_FUNCTION /* not-ready-definition-yet */
+#elif defined(_MSC_VER)
+#define KRB_LIB_FUNCTION /* not-ready-definition-yet2 */
+#else
+#define KRB_LIB_FUNCTION
+#endif
+#endif
+
+void KRB_LIB_FUNCTION
+afs_string_to_key __P((
+       const char *str,
+       const char *cell,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+create_ciph __P((
+       KTEXT c,
+       unsigned char *session,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t life,
+       int kvno,
+       KTEXT tkt,
+       u_int32_t kdc_time,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+cr_err_reply __P((
+       KTEXT pkt,
+       char *pname,
+       char *pinst,
+       char *prealm,
+       u_int32_t time_ws,
+       u_int32_t e,
+       char *e_string));
+
+int KRB_LIB_FUNCTION
+decomp_ticket __P((
+       KTEXT tkt,
+       unsigned char *flags,
+       char *pname,
+       char *pinstance,
+       char *prealm,
+       u_int32_t *paddress,
+       unsigned char *session,
+       int *life,
+       u_int32_t *time_sec,
+       char *sname,
+       char *sinstance,
+       des_cblock *key,
+       des_key_schedule schedule));
+
+int KRB_LIB_FUNCTION
+dest_tkt __P((void));
+
+int KRB_LIB_FUNCTION
+get_ad_tkt __P((
+       char *service,
+       char *sinstance,
+       char *realm,
+       int lifetime));
+
+int KRB_LIB_FUNCTION
+getst __P((
+       int fd,
+       char *s,
+       int n));
+
+int KRB_LIB_FUNCTION
+in_tkt __P((
+       char *pname,
+       char *pinst));
+
+int KRB_LIB_FUNCTION
+k_get_all_addrs __P((struct in_addr **l));
+
+int KRB_LIB_FUNCTION
+k_gethostname __P((
+       char *name,
+       int namelen));
+
+int KRB_LIB_FUNCTION
+k_getportbyname __P((
+       const char *service,
+       const char *proto,
+       int default_port));
+
+int KRB_LIB_FUNCTION
+k_getsockinst __P((
+       int fd,
+       char *inst,
+       size_t inst_size));
+
+int KRB_LIB_FUNCTION
+k_isinst __P((char *s));
+
+int KRB_LIB_FUNCTION
+k_isname __P((char *s));
+
+int KRB_LIB_FUNCTION
+k_isrealm __P((char *s));
+
+struct tm * KRB_LIB_FUNCTION
+k_localtime __P((u_int32_t *tp));
+
+int KRB_LIB_FUNCTION
+kname_parse __P((
+       char *np,
+       char *ip,
+       char *rp,
+       char *fullname));
+
+int KRB_LIB_FUNCTION
+krb_atime_to_life __P((char *atime));
+
+int KRB_LIB_FUNCTION
+krb_check_auth __P((
+       KTEXT packet,
+       u_int32_t checksum,
+       MSG_DAT *msg_data,
+       des_cblock *session,
+       struct des_ks_struct *schedule,
+       struct sockaddr_in *laddr,
+       struct sockaddr_in *faddr));
+
+int KRB_LIB_FUNCTION
+krb_check_tm __P((struct tm tm));
+
+KTEXT KRB_LIB_FUNCTION
+krb_create_death_packet __P((char *a_name));
+
+int KRB_LIB_FUNCTION
+krb_create_ticket __P((
+       KTEXT tkt,
+       unsigned char flags,
+       char *pname,
+       char *pinstance,
+       char *prealm,
+       int32_t paddress,
+       void *session,
+       int16_t life,
+       int32_t time_sec,
+       char *sname,
+       char *sinstance,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+krb_decode_as_rep __P((
+       const char *user,
+       char *instance,         /* INOUT parameter */
+       const char *realm,
+       const char *service,
+       const char *sinstance,
+       key_proc_t key_proc,
+       decrypt_proc_t decrypt_proc,
+       const void *arg,
+       KTEXT as_rep,
+       CREDENTIALS *cred));
+
+int KRB_LIB_FUNCTION
+krb_disable_debug __P((void));
+
+int KRB_LIB_FUNCTION
+krb_enable_debug __P((void));
+
+int KRB_LIB_FUNCTION
+krb_equiv __P((
+       u_int32_t a,
+       u_int32_t b));
+
+int KRB_LIB_FUNCTION
+krb_get_address __P((
+       void *from,
+       u_int32_t *to));
+
+int KRB_LIB_FUNCTION
+krb_get_admhst __P((
+       char *host,
+       char *realm,
+       int nth));
+
+int KRB_LIB_FUNCTION
+krb_get_config_bool __P((const char *variable));
+
+const char * KRB_LIB_FUNCTION
+krb_get_config_string __P((const char *variable));
+
+int KRB_LIB_FUNCTION
+krb_get_cred __P((
+        char *service,
+        char *instance,
+        char *realm,
+        CREDENTIALS *c));
+
+int KRB_LIB_FUNCTION
+krb_get_default_principal __P((
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_get_default_realm __P((void));
+
+const char * KRB_LIB_FUNCTION
+krb_get_default_tkt_root __P((void));
+
+const char * KRB_LIB_FUNCTION
+krb_get_default_keyfile __P((void));
+
+const char * KRB_LIB_FUNCTION
+krb_get_err_text __P((int code));
+
+struct krb_host* KRB_LIB_FUNCTION
+krb_get_host __P((
+       int nth,
+       const char *realm,
+       int admin));
+
+int KRB_LIB_FUNCTION
+krb_get_in_tkt __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       key_proc_t key_proc,
+       decrypt_proc_t decrypt_proc,
+       void *arg));
+
+int KRB_LIB_FUNCTION
+krb_get_int __P((
+       void *f,
+       u_int32_t *to,
+       int size,
+       int lsb));
+
+int KRB_LIB_FUNCTION
+krb_get_kdc_time_diff __P((void));
+
+int KRB_LIB_FUNCTION
+krb_get_krbconf __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_krbextra __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_krbhst __P((
+       char *host,
+       char *realm,
+       int nth));
+
+int KRB_LIB_FUNCTION
+krb_get_krbrealms __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_lrealm __P((
+       char *r,
+       int n));
+
+int KRB_LIB_FUNCTION
+krb_get_nir __P((
+       void *from,
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_get_phost __P((const char *alias));
+
+int KRB_LIB_FUNCTION
+krb_get_pw_in_tkt __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const char *service,
+       const char *sinstance,
+       int life,
+       const char *password));
+
+int KRB_LIB_FUNCTION
+krb_get_pw_in_tkt2 __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const char *service,
+       const char *sinstance,
+       int life,
+       const char *password,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+krb_get_string __P((
+       void *from,
+       char *to,
+       size_t to_size));
+
+int KRB_LIB_FUNCTION
+krb_get_svc_in_tkt __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       char *srvtab));
+
+int KRB_LIB_FUNCTION
+krb_get_tf_fullname __P((
+       char *ticket_file,
+       char *name,
+       char *instance,
+       char *realm));
+
+int KRB_LIB_FUNCTION
+krb_get_tf_realm __P((
+       char *ticket_file,
+       char *realm));
+
+void KRB_LIB_FUNCTION
+krb_kdctimeofday __P((struct timeval *tv));
+
+int KRB_LIB_FUNCTION
+krb_kntoln __P((
+       AUTH_DAT *ad,
+       char *lname));
+
+int KRB_LIB_FUNCTION
+krb_kuserok __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *luser));
+
+char * KRB_LIB_FUNCTION
+krb_life_to_atime __P((int life));
+
+u_int32_t KRB_LIB_FUNCTION
+krb_life_to_time __P((
+       u_int32_t start,
+       int life_));
+
+int KRB_LIB_FUNCTION
+krb_lsb_antinet_ulong_cmp __P((
+       u_int32_t x,
+       u_int32_t y));
+
+int KRB_LIB_FUNCTION
+krb_lsb_antinet_ushort_cmp __P((
+       u_int16_t x,
+       u_int16_t y));
+
+int KRB_LIB_FUNCTION
+krb_mk_as_req __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const char *service,
+       const char *sinstance,
+       int life,
+       KTEXT cip));
+
+int KRB_LIB_FUNCTION
+krb_mk_auth __P((
+       int32_t options,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t checksum,
+       char *version,
+       KTEXT buf));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_err __P((
+       u_char *p,
+       int32_t e,
+       char *e_string));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_priv __P((
+       void *in,
+       void *out,
+       u_int32_t length,
+       struct des_ks_struct *schedule,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver));
+
+int KRB_LIB_FUNCTION
+krb_mk_req __P((
+       KTEXT authent,
+       char *service,
+       char *instance,
+       char *realm,
+       int32_t checksum));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_safe __P((
+       void *in,
+       void *out,
+       u_int32_t length,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver));
+
+int KRB_LIB_FUNCTION
+krb_net_read __P((
+       int fd,
+       void *v,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_net_write __P((
+       int fd,
+       const void *v,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_parse_name __P((
+       const char *fullname,
+       krb_principal *principal));
+
+int KRB_LIB_FUNCTION
+krb_put_address __P((
+       u_int32_t addr,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_put_int __P((
+       u_int32_t from,
+       void *to,
+       size_t rem,
+       int size));
+
+int KRB_LIB_FUNCTION
+krb_put_nir __P((
+       const char *name,
+       const char *instance,
+       const char *realm,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_put_string __P((
+       const char *from,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_rd_err __P((
+       u_char *in,
+       u_int32_t in_length,
+       int32_t *code,
+       MSG_DAT *m_data));
+
+int32_t KRB_LIB_FUNCTION
+krb_rd_priv __P((
+       void *in,
+       u_int32_t in_length,
+       struct des_ks_struct *schedule,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver,
+       MSG_DAT *m_data));
+
+int KRB_LIB_FUNCTION
+krb_rd_req __P((
+       KTEXT authent,
+       char *service,
+       char *instance,
+       int32_t from_addr,
+       AUTH_DAT *ad,
+       char *fn));
+
+int32_t KRB_LIB_FUNCTION
+krb_rd_safe __P((
+       void *in,
+       u_int32_t in_length,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver,
+       MSG_DAT *m_data));
+
+int KRB_LIB_FUNCTION
+krb_realm_parse __P((
+       char *realm,
+       int length));
+
+char * KRB_LIB_FUNCTION
+krb_realmofhost __P((const char *host));
+
+int KRB_LIB_FUNCTION
+krb_recvauth __P((
+       int32_t options,
+       int fd,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       struct sockaddr_in *faddr,
+       struct sockaddr_in *laddr,
+       AUTH_DAT *kdata,
+       char *filename,
+       struct des_ks_struct *schedule,
+       char *version));
+
+int KRB_LIB_FUNCTION
+krb_sendauth __P((
+       int32_t options,
+       int fd,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t checksum,
+       MSG_DAT *msg_data,
+       CREDENTIALS *cred,
+       struct des_ks_struct *schedule,
+       struct sockaddr_in *laddr,
+       struct sockaddr_in *faddr,
+       char *version));
+
+void KRB_LIB_FUNCTION
+krb_set_kdc_time_diff __P((int diff));
+
+int KRB_LIB_FUNCTION
+krb_set_key __P((
+       void *key,
+       int cvt));
+
+int KRB_LIB_FUNCTION
+krb_set_lifetime __P((int newval));
+
+void KRB_LIB_FUNCTION
+krb_set_tkt_string __P((const char *val));
+
+const char * KRB_LIB_FUNCTION
+krb_stime __P((time_t *t));
+
+int KRB_LIB_FUNCTION
+krb_time_to_life __P((
+       u_int32_t start,
+       u_int32_t end));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name __P((krb_principal *pr));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_long __P((
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_long_r __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *fullname));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_r __P((
+       krb_principal *pr,
+       char *fullname));
+
+int KRB_LIB_FUNCTION
+krb_use_admin_server __P((int flag));
+
+int KRB_LIB_FUNCTION
+krb_verify_user __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *password,
+       int secure,
+       char *linstance));
+
+int KRB_LIB_FUNCTION
+krb_verify_user_srvtab __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *password,
+       int secure,
+       char *linstance,
+       char *srvtab));
+
+int KRB_LIB_FUNCTION
+kuserok __P((
+       AUTH_DAT *auth,
+       char *luser));
+
+u_int32_t KRB_LIB_FUNCTION
+lsb_time __P((
+       time_t t,
+       struct sockaddr_in *src,
+       struct sockaddr_in *dst));
+
+const char * KRB_LIB_FUNCTION
+month_sname __P((int n));
+
+int KRB_LIB_FUNCTION
+passwd_to_5key __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+passwd_to_afskey __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+passwd_to_key __P((
+       const char *user,
+       const char *instance,
+       const char *realm,
+       const void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+read_service_key __P((
+       const char *service,
+       char *instance,
+       const char *realm,
+       int kvno,
+       const char *file,
+       void *key));
+
+int KRB_LIB_FUNCTION
+save_credentials __P((
+       char *service,
+       char *instance,
+       char *realm,
+       unsigned char *session,
+       int lifetime,
+       int kvno,
+       KTEXT ticket,
+       int32_t issue_date));
+
+int KRB_LIB_FUNCTION
+send_to_kdc __P((
+       KTEXT pkt,
+       KTEXT rpkt,
+       const char *realm));
+
+int KRB_LIB_FUNCTION
+srvtab_to_key __P((
+       const char *user,
+       char *instance,         /* INOUT parameter */
+       const char *realm,
+       const void *srvtab,
+       des_cblock *key));
+
+void KRB_LIB_FUNCTION
+tf_close __P((void));
+
+int KRB_LIB_FUNCTION
+tf_create __P((char *tf_name));
+
+int KRB_LIB_FUNCTION
+tf_get_cred __P((CREDENTIALS *c));
+
+int KRB_LIB_FUNCTION
+tf_get_cred_addr __P((char *realm, size_t realm_sz, struct in_addr *addr));
+
+int KRB_LIB_FUNCTION
+tf_get_pinst __P((char *inst));
+
+int KRB_LIB_FUNCTION
+tf_get_pname __P((char *p));
+
+int KRB_LIB_FUNCTION
+tf_init __P((
+       char *tf_name,
+       int rw));
+
+int KRB_LIB_FUNCTION
+tf_put_pinst __P((const char *inst));
+
+int KRB_LIB_FUNCTION
+tf_put_pname __P((const char *p));
+
+int KRB_LIB_FUNCTION
+tf_save_cred __P((
+       char *service,
+       char *instance,
+       char *realm,
+       unsigned char *session,
+       int lifetime,
+       int kvno,
+       KTEXT ticket,
+       u_int32_t issue_date));
+
+int KRB_LIB_FUNCTION
+tf_setup __P((
+       CREDENTIALS *cred,
+       const char *pname,
+       const char *pinst));
+
+int KRB_LIB_FUNCTION
+tf_get_addr __P((
+       const char *realm,
+       struct in_addr *addr));
+
+int KRB_LIB_FUNCTION
+tf_store_addr __P((const char *realm, struct in_addr *addr));
+
+char * KRB_LIB_FUNCTION
+tkt_string __P((void));
+
+int KRB_LIB_FUNCTION
+krb_add_our_ip_for_realm __P((const char *user, const char *instance,
+                             const char *realm, const char *password));
+
+#endif /* __krb_protos_h__ */
diff --git a/mac/kerberos_includes/krb.h b/mac/kerberos_includes/krb.h
new file mode 100755 (executable)
index 0000000..929e89b
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * $Id: krb.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos library. 
+ */
+
+#if !defined (__STDC__) && !defined(_MSC_VER)
+#define const
+#define signed
+#endif
+
+#include <ktypes.h>
+#include <time.h>
+
+#ifndef __KRB_H__
+#define __KRB_H__
+
+/* XXX */
+#ifndef __BEGIN_DECLS
+#if defined(__cplusplus)
+#define        __BEGIN_DECLS   extern "C" {
+#define        __END_DECLS     };
+#else
+#define        __BEGIN_DECLS
+#define        __END_DECLS
+#endif
+#endif
+
+#if defined (__STDC__) || defined (_MSC_VER)
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+__BEGIN_DECLS
+
+/* Need some defs from des.h    */
+#if !defined(NOPROTO) && !defined(__STDC__)
+#define NOPROTO
+#endif
+#include <des.h>
+
+/* CNS compatibility ahead! */
+#ifndef KRB_INT32
+#define KRB_INT32 int32_t
+#endif
+#ifndef KRB_UINT32
+#define KRB_UINT32 u_int32_t
+#endif
+
+/* Global library variables. */
+extern int krb_ignore_ip_address; /* To turn off IP address comparison */
+extern int krb_no_long_lifetimes; /* To disable AFS compatible lifetimes */
+extern int krbONE;
+#define         HOST_BYTE_ORDER (* (char *) &krbONE)
+/* Debug variables */
+extern int krb_debug;
+extern int krb_ap_req_debug;
+extern int krb_dns_debug;
+
+
+/* Text describing error codes */
+#define                MAX_KRB_ERRORS  256
+extern const char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* General definitions */
+#define                KSUCCESS        0
+#define                KFAILURE        255
+
+/*
+ * Kerberos specific definitions 
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database.  The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server.  Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm. 
+ */
+
+/* /etc/kerberosIV is only for backwards compatibility, don't use it! */
+#ifndef KRB_CONF
+#define KRB_CONF       "/etc/krb.conf"
+#endif
+#ifndef KRB_RLM_TRANS
+#define KRB_RLM_TRANS   "/etc/krb.realms"
+#endif
+#ifndef KRB_CNF_FILES
+#define KRB_CNF_FILES  { KRB_CONF,   "/etc/kerberosIV/krb.conf", 0}
+#endif
+#ifndef KRB_RLM_FILES
+#define KRB_RLM_FILES  { KRB_RLM_TRANS, "/etc/kerberosIV/krb.realms", 0}
+#endif
+#ifndef KRB_EQUIV
+#define KRB_EQUIV      "/etc/krb.equiv"
+#endif
+#define KRB_MASTER     "kerberos"
+#ifndef KRB_REALM
+#define KRB_REALM      (krb_get_default_realm())
+#endif
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define        ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+/* Leave space for quoting */
+#define                MAX_K_NAME_SZ   (2*ANAME_SZ + 2*INST_SZ + 2*REALM_SZ - 3)
+#define                KKEY_SZ         100
+#define                VERSION_SZ      1
+#define                MSG_TYPE_SZ     1
+#define                DATE_SZ         26      /* RTI date output */
+
+#define MAX_HSTNM 100 /* for compatibility */
+
+typedef struct krb_principal{
+    char name[ANAME_SZ];
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+}krb_principal;
+
+#ifndef DEFAULT_TKT_LIFE       /* allow compile-time override */
+/* default lifetime for krb_mk_req & co., 10 hrs */
+#define        DEFAULT_TKT_LIFE 141
+#endif
+
+#define                KRB_TICKET_GRANTING_TICKET      "krbtgt"
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+    unsigned int length;               /* Length of the text */
+    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */
+    u_int32_t mbz;             /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define        CLIENT_KRB_TIMEOUT      4       /* default time between retries */
+#define CLIENT_KRB_RETRY       5       /* retry this many times */
+#define        CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define        R_TKT_FIL       0
+#define        W_TKT_FIL       1
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define        CLOCK_SKEW      5*60
+/* Filename for readservkey */
+#ifndef                KEYFILE
+#define                KEYFILE         (krb_get_default_keyfile())
+#endif
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+    unsigned char k_flags;     /* Flags from ticket */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* His Instance */
+    char    prealm[REALM_SZ];  /* His Realm */
+    u_int32_t checksum;                /* Data checksum (opt) */
+    des_cblock session;                /* Session Key */
+    int     life;              /* Life of ticket */
+    u_int32_t time_sec;                /* Time ticket issued */
+    u_int32_t address;         /* Address in ticket */
+    KTEXT_ST reply;            /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+    char    service[ANAME_SZ]; /* Service name */
+    char    instance[INST_SZ]; /* Instance */
+    char    realm[REALM_SZ];   /* Auth domain */
+    des_cblock session;                /* Session key */
+    int     lifetime;          /* Lifetime */
+    int     kvno;              /* Key version number */
+    KTEXT_ST ticket_st;                /* The ticket itself */
+    int32_t    issue_date;     /* The issue time */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+    unsigned char *app_data;   /* pointer to appl data */
+    u_int32_t app_length;      /* length of appl data */
+    u_int32_t hash;            /* hash to lookup replay */
+    int     swap;              /* swap bytes? */
+    int32_t    time_sec;               /* msg timestamp seconds */
+    unsigned char time_5ms;    /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+struct krb_host {
+    char *realm;
+    char *host;
+    enum krb_host_proto { PROTO_UDP, PROTO_TCP, PROTO_HTTP } proto;
+    int port;
+    int admin;
+};
+
+/* Location of ticket file for save_cred and get_cred */
+#define TKT_FILE        tkt_string()
+#ifndef TKT_ROOT
+#define TKT_ROOT        (krb_get_default_tkt_root())
+#endif
+
+/* Error codes returned from the KDC */
+#define                KDC_OK          0       /* Request OK */
+#define                KDC_NAME_EXP    1       /* Principal expired */
+#define                KDC_SERVICE_EXP 2       /* Service expired */
+#define                KDC_AUTH_EXP    3       /* Auth expired */
+#define                KDC_PKT_VER     4       /* Protocol version unknown */
+#define                KDC_P_MKEY_VER  5       /* Wrong master key version */
+#define                KDC_S_MKEY_VER  6       /* Wrong master key version */
+#define                KDC_BYTE_ORDER  7       /* Byte order unknown */
+#define                KDC_PR_UNKNOWN  8       /* Principal unknown */
+#define                KDC_PR_N_UNIQUE 9       /* Principal not unique */
+#define                KDC_NULL_KEY   10       /* Principal has null key */
+#define                KDC_GEN_ERR    20       /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define                GC_OK           0       /* Retrieve OK */
+#define                RET_OK          0       /* Retrieve OK */
+#define                GC_TKFIL       21       /* Can't read ticket file */
+#define                RET_TKFIL      21       /* Can't read ticket file */
+#define                GC_NOTKT       22       /* Can't find ticket or TGT */
+#define                RET_NOTKT      22       /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req         */
+#define                MK_AP_OK        0       /* Success */
+#define                MK_AP_TGTEXP   26       /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define                RD_AP_OK        0       /* Request authentic */
+#define                RD_AP_UNDEC    31       /* Can't decode authenticator */
+#define                RD_AP_EXP      32       /* Ticket expired */
+#define                RD_AP_NYV      33       /* Ticket not yet valid */
+#define                RD_AP_REPEAT   34       /* Repeated request */
+#define                RD_AP_NOT_US   35       /* The ticket isn't for us */
+#define                RD_AP_INCON    36       /* Request is inconsistent */
+#define                RD_AP_TIME     37       /* delta_t too big */
+#define                RD_AP_BADD     38       /* Incorrect net address */
+#define                RD_AP_VERSION  39       /* protocol version mismatch */
+#define                RD_AP_MSG_TYPE 40       /* invalid msg type */
+#define                RD_AP_MODIFIED 41       /* message stream modified */
+#define                RD_AP_ORDER    42       /* message out of order */
+#define                RD_AP_UNAUTHOR 43       /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define                GT_PW_OK        0       /* Got password changing tkt */
+#define                GT_PW_NULL     51       /* Current PW is null */
+#define                GT_PW_BADPW    52       /* Incorrect current password */
+#define                GT_PW_PROT     53       /* Protocol Error */
+#define                GT_PW_KDCERR   54       /* Error returned by KDC */
+#define                GT_PW_NULLTKT  55       /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define                SKDC_OK         0       /* Response received */
+#define                SKDC_RETRY     56       /* Retry count exceeded */
+#define                SKDC_CANT      57       /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define                INTK_OK         0       /* Ticket obtained */
+#define                INTK_W_NOTALL  61       /* Not ALL tickets returned */
+#define                INTK_BADPW     62       /* Incorrect password */
+#define                INTK_PROT      63       /* Protocol Error */
+#define                INTK_ERR       70       /* Other error */
+
+/* Values returned by get_adtkt */
+#define         AD_OK           0      /* Ticket Obtained */
+#define         AD_NOTGT       71      /* Don't have tgt */
+#define         AD_INTR_RLM_NOTGT 72   /* Can't get inter-realm tgt */
+
+/* Error codes returned by ticket file utilities */
+#define                NO_TKT_FIL      76      /* No ticket file found */
+#define                TKT_FIL_ACC     77      /* Couldn't access tkt file */
+#define                TKT_FIL_LCK     78      /* Couldn't lock ticket file */
+#define                TKT_FIL_FMT     79      /* Bad ticket file format */
+#define                TKT_FIL_INI     80      /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define                KNAME_FMT       81      /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define                SAFE_PRIV_ERROR -1      /* syscall error */
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define        KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define        KOPT_DO_MUTUAL   0x00000002 /* do mutual auth */
+
+#define        KOPT_DONT_CANON  0x00000004 /*
+                                    * don't canonicalize inst as
+                                    * a hostname
+                                    */
+
+#define KOPT_IGNORE_PROTOCOL 0x0008
+
+#define        KRB_SENDAUTH_VLEN 8         /* length for version strings */
+
+
+/* flags for krb_verify_user() */
+#define KRB_VERIFY_NOT_SECURE  0
+#define KRB_VERIFY_SECURE      1
+#define KRB_VERIFY_SECURE_FAIL 2
+
+extern char *krb4_version;
+
+typedef int (*key_proc_t) __P((const char *name,
+                              char *instance, /* INOUT parameter */
+                              const char *realm,
+                              const void *password,
+                              des_cblock *key));
+
+typedef int (*decrypt_proc_t) __P((const char *name,
+                                  const char *instance,
+                                  const char *realm,
+                                  const void *arg, 
+                                  key_proc_t,
+                                  KTEXT *));
+
+#include "krb-protos.h"
+
+__END_DECLS
+
+#endif /* __KRB_H__ */
diff --git a/mac/kerberos_includes/krb_conf.h b/mac/kerberos_includes/krb_conf.h
new file mode 100755 (executable)
index 0000000..48687ff
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/krb_conf.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/krb_conf.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * This file contains configuration information for the Kerberos library
+ * which is machine specific; currently, this file contains
+ * configuration information for the vax, the "ibm032" (RT), and the
+ * "PC8086" (IBM PC).
+ *
+ * Note:  cross-compiled targets must appear BEFORE their corresponding
+ * cross-compiler host.  Otherwise, both will be defined when running
+ * the native compiler on the programs that construct cross-compiled
+ * sources.
+ */
+
+#ifndef _KERBEROS_KRB_CONF_H
+#define        _KERBEROS_KRB_CONF_H
+
+#pragma ident  "@(#)krb_conf.h 1.3     92/07/14 SMI"
+
+#include <kerberos/mit-copyright.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Byte ordering */
+extern int krbONE;
+#define                HOST_BYTE_ORDER (* (char *) &krbONE)
+#define                MSB_FIRST               0       /* 68000, IBM RT/PC */
+#define                LSB_FIRST               1       /* Vax, PC8086 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_KRB_CONF_H */
diff --git a/mac/kerberos_includes/ktypes.h b/mac/kerberos_includes/ktypes.h
new file mode 100755 (executable)
index 0000000..fbb40e7
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef __KTYPES_H__
+#define __KTYPES_H__
+
+typedef unsigned char u_char;
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef short int16_t;
+typedef unsigned short u_int16_t;
+#if TARGET_API_MAC_CARBON
+typedef long int32_t;
+typedef unsigned long u_int32_t;
+#else
+typedef int int32_t;
+typedef unsigned int u_int32_t;
+#endif
+#endif /*  __KTYPES_H__ */
diff --git a/mac/kerberos_includes/lsb_addr_comp.h b/mac/kerberos_includes/lsb_addr_comp.h
new file mode 100755 (executable)
index 0000000..97f9280
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/lsb_addr_comp.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/lsb_addr_comp.h,v 1.2 2001/12/04 02:06:05 rjs3 Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Comparison macros to emulate LSBFIRST comparison results of network
+ * byte-order quantities
+ */
+
+#ifndef        _KERBEROS_LSB_ADDR_COMP_H
+#define        _KERBEROS_LSB_ADDR_COMP_H
+
+#pragma ident  "@(#)lsb_addr_comp.h    1.4     93/02/04 SMI"
+
+#include <kerberos/mit-copyright.h>
+#include <kerberos/osconf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LSBFIRST
+#define        lsb_net_ulong_less(x, y)        ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#define        lsb_net_ushort_less(x, y)       ((x < y) ? -1 : ((x > y) ? 1 : 0))
+#else
+/* MSBFIRST */
+#define        u_char_comp(x, y) \
+       (((x) > (y)) ? (1) : (((x) == (y)) ? (0) : (-1)))
+/* This is gross, but... */
+#define        lsb_net_ulong_less(x, y) long_less_than((u_char *)&x, (u_char *)&y)
+#define        lsb_net_ushort_less(x, y) short_less_than((u_char *)&x, (u_char *)&y)
+
+#define        long_less_than(x, y) \
+       (u_char_comp((x)[3], (y)[3]) ? u_char_comp((x)[3], (y)[3]) : \
+           (u_char_comp((x)[2], (y)[2]) ? u_char_comp((x)[2], (y)[2]) : \
+           (u_char_comp((x)[1], (y)[1]) ? u_char_comp((x)[1], (y)[1]) : \
+           (u_char_comp((x)[0], (y)[0])))))
+#define        short_less_than(x, y) \
+       (u_char_comp((x)[1], (y)[1]) ? u_char_comp((x)[1], (y)[1]) : \
+           (u_char_comp((x)[0], (y)[0])))
+
+#endif /* LSBFIRST */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_LSB_ADDR_COMP_H */
diff --git a/mac/kerberos_includes/mit-sipb-copyright.h b/mac/kerberos_includes/mit-sipb-copyright.h
new file mode 100755 (executable)
index 0000000..b6fe0c0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 1987 by the Student Information Processing Board
+ *     of the Massachusetts Institute of Technology
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purpose and without fee is
+ * hereby granted, provided that the above copyright notice
+ * appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation,
+ * and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
+ * used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * M.I.T. and the M.I.T. S.I.P.B. make no representations about
+ * the suitability of this software for any purpose.  It is
+ * provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef        _KERBEROS_MIT_COPYRIGHT_H
+#define        _KERBEROS_MIT_COPYRIGHT_H
+
+#pragma ident  "@(#)mit-sipb-copyright.h       1.5     93/02/04 SMI"
+
+#endif /* _KERBEROS_MIT_COPYRIGHT_H */
diff --git a/mac/kerberos_includes/old_krb.h b/mac/kerberos_includes/old_krb.h
new file mode 100755 (executable)
index 0000000..423ab5e
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/old_krb.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/old_krb.h,v 1.2 2001/12/04 02:06:06 rjs3 Exp $
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file for the Kerberos library.
+ */
+
+#ifndef        _KERBEROS_KRB_H
+#define        _KERBEROS_KRB_H
+
+/* #pragma ident       "@(#)krb.h      1.12    97/04/14 SMI" */
+
+#include <kerberos/mit-copyright.h>
+#include <kerberos/des.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Text describing error codes */
+#define                KRB_ERRORS_TABLE_SIZE   256
+#define                MAX_KRB_ERRORS  (KRB_ERRORS_TABLE_SIZE-1)
+extern char *krb_err_txt[KRB_ERRORS_TABLE_SIZE];
+
+/* These are not defined for at least SunOS 3.3 and Ultrix 2.2 */
+#if defined(ULTRIX022) || (defined(SunOS) && SunOS < 40)
+#define        FD_ZERO(p)      ((p)->fds_bits[0] = 0)
+#define        FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << (n)))
+#define        FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << (n)))
+#endif /* ULTRIX022 || SunOS */
+
+/* General definitions */
+#define                KSUCCESS        0
+#define                KFAILURE        255
+
+#ifdef NO_UIDGID_T
+typedef unsigned short uid_t;
+typedef unsigned short gid_t;
+#endif /* NO_UIDGID_T */
+
+/*
+ * Kerberos specific definitions
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database.  The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine when looking for a kerberos slave server.  Other
+ * possibilities are in the KRB_CONF file. KRB_REALM is the name of
+ * the realm.
+ */
+
+#ifdef notdef
+this is server - only, does not belong here;
+#define                KRBLOG          "/kerberos/kerberos.log"
+are these used anyplace '?';
+#define                VX_KRB_HSTFILE  "/etc/krbhst"
+#define                PC_KRB_HSTFILE  "\\kerberos\\krbhst"
+#endif
+
+#define                KRB_CONF        "/etc/krb.conf"
+#define                KRB_RLM_TRANS   "/etc/krb.realms"
+#define                KRB_MASTER      "kerberos"
+#define                KRB_HOST        KRB_MASTER
+/* #define     KRB_REALM       "ATHENA.MIT.EDU" */
+#define                KRB_REALM       krb_get_default_realm()
+char           *krb_get_default_realm();
+
+#ifdef NIS
+/* defines for use with NIS service */
+#define                KRB_CONF_MAP    "krb.conf"          /* conf NIS map name */
+#define                KRB_REALM_DEFKEY "DEFAULT_REALM"    /* key for default realm */
+#endif /* NIS */
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define                ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+/* include space for '.' and '@' */
+#define                MAX_K_NAME_SZ   (ANAME_SZ + INST_SZ + REALM_SZ + 2)
+#define                KKEY_SZ         100
+#define                VERSION_SZ      1
+#define                MSG_TYPE_SZ     1
+#define                DATE_SZ         26      /* RTI date output */
+
+#define                MAX_HSTNM       100
+
+#ifndef DEFAULT_TKT_LIFE               /* allow compile-time override */
+#define        DEFAULT_TKT_LIFE        96      /* default lifetime for krb_mk_req */
+                                       /* & co., 8 hrs */
+#endif
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+       int     length;                         /* Length of the text */
+       unsigned char dat[MAX_KTXT_LEN];        /* The data itself */
+       unsigned long mbz;                      /* zero to catch runaway */
+                                               /* strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define        CLIENT_KRB_TIMEOUT      4       /* time between retries */
+#define        CLIENT_KRB_RETRY        5       /* retry this many times */
+#define        CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define        R_TKT_FIL       0
+#define        W_TKT_FIL       1
+
+/* Definitions for cl_get_tgt */
+#ifdef PC
+#define        CL_GTGT_INIT_FILE               "\\kerberos\\k_in_tkts"
+#else
+#define        CL_GTGT_INIT_FILE               "/etc/k_in_tkts"
+#endif /* PC */
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define                CLOCK_SKEW      5*60
+/* Filename for readservkey */
+#define                KEYFILE         "/etc/srvtab"
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+       unsigned char k_flags;          /* Flags from ticket */
+       char    pname[ANAME_SZ];        /* Principal's name */
+       char    pinst[INST_SZ];         /* His Instance */
+       char    prealm[REALM_SZ];       /* His Realm */
+       unsigned long checksum;         /* Data checksum (opt) */
+       C_Block session;                /* Session Key */
+       int     life;                   /* Life of ticket */
+       unsigned long time_sec;         /* Time ticket issued */
+       unsigned long address;          /* Address in ticket */
+       KTEXT_ST        reply;          /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+       char    service[ANAME_SZ];      /* Service name */
+       char    instance[INST_SZ];      /* Instance */
+       char    realm[REALM_SZ];        /* Auth domain */
+       C_Block session;                /* Session key */
+       int     lifetime;               /* Lifetime */
+       int     kvno;                   /* Key version number */
+       KTEXT_ST ticket_st;             /* The ticket itself */
+       long    issue_date;             /* The issue time */
+       char    pname[ANAME_SZ];        /* Principal's name */
+       char    pinst[INST_SZ];         /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+       unsigned char *app_data;        /* pointer to appl data */
+       unsigned long app_length;       /* length of appl data */
+       unsigned long hash;             /* hash to lookup replay */
+       int     swap;                   /* swap bytes? */
+       long    time_sec;               /* msg timestamp seconds */
+       unsigned char time_5ms;         /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+
+/* Location of ticket file for save_cred and get_cred */
+#ifdef PC
+#define        TKT_FILE        "\\kerberos\\ticket.ses"
+#else
+#define        TKT_FILE        tkt_string()
+#define        TKT_ROOT        "/tmp/tkt"
+#endif /* PC */
+
+/* Error codes returned from the KDC */
+#define                KDC_OK          0       /* Request OK */
+#define                KDC_NAME_EXP    1       /* Principal expired */
+#define                KDC_SERVICE_EXP 2       /* Service expired */
+#define                KDC_AUTH_EXP    3       /* Auth expired */
+#define                KDC_PKT_VER     4       /* Protocol version unknown */
+#define                KDC_P_MKEY_VER  5       /* Wrong master key version */
+#define                KDC_S_MKEY_VER  6       /* Wrong master key version */
+#define                KDC_BYTE_ORDER  7       /* Byte order unknown */
+#define                KDC_PR_UNKNOWN  8       /* Principal unknown */
+#define                KDC_PR_N_UNIQUE 9       /* Principal not unique */
+#define                KDC_NULL_KEY    10      /* Principal has null key */
+#define                KDC_GEN_ERR     20      /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define                GC_OK           0       /* Retrieve OK */
+#define                RET_OK          0       /* Retrieve OK */
+#define                GC_TKFIL        21      /* Can't read ticket file */
+#define                RET_TKFIL       21      /* Can't read ticket file */
+#define                GC_NOTKT        22      /* Can't find ticket or TGT */
+#define                RET_NOTKT       22      /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req         */
+#define                MK_AP_OK        0       /* Success */
+#define                MK_AP_TGTEXP    26      /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define                RD_AP_OK        0       /* Request authentic */
+#define                RD_AP_UNDEC     31      /* Can't decode authenticator */
+#define                RD_AP_EXP       32      /* Ticket expired */
+#define                RD_AP_NYV       33      /* Ticket not yet valid */
+#define                RD_AP_REPEAT    34      /* Repeated request */
+#define                RD_AP_NOT_US    35      /* The ticket isn't for us */
+#define                RD_AP_INCON     36      /* Request is inconsistent */
+#define                RD_AP_TIME      37      /* delta_t too big */
+#define                RD_AP_BADD      38      /* Incorrect net address */
+#define                RD_AP_VERSION   39      /* protocol version mismatch */
+#define                RD_AP_MSG_TYPE  40      /* invalid msg type */
+#define                RD_AP_MODIFIED  41      /* message stream modified */
+#define                RD_AP_ORDER     42      /* message out of order */
+#define                RD_AP_UNAUTHOR  43      /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define                GT_PW_OK        0       /* Got password changing tkt */
+#define                GT_PW_NULL      51      /* Current PW is null */
+#define                GT_PW_BADPW     52      /* Incorrect current password */
+#define                GT_PW_PROT      53      /* Protocol Error */
+#define                GT_PW_KDCERR    54      /* Error returned by KDC */
+#define                GT_PW_NULLTKT   55      /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define                SKDC_OK         0       /* Response received */
+#define                SKDC_RETRY      56      /* Retry count exceeded */
+#define                SKDC_CANT       57      /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define                INTK_OK         0       /* Ticket obtained */
+#define                INTK_W_NOTALL   61      /* Not ALL tickets returned */
+#define                INTK_BADPW      62      /* Incorrect password */
+#define                INTK_PROT       63      /* Protocol Error */
+#define                INTK_ERR        70      /* Other error */
+
+/* Values returned by get_adtkt */
+#define                AD_OK           0       /* Ticket Obtained */
+#define                AD_NOTGT        71      /* Don't have tgt */
+
+/* Error codes returned by ticket file utilities */
+#define                NO_TKT_FIL      76      /* No ticket file found */
+#define                TKT_FIL_ACC     77      /* Couldn't access tkt file */
+#define                TKT_FIL_LCK     78      /* Couldn't lock ticket file */
+#define                TKT_FIL_FMT     79      /* Bad ticket file format */
+#define                TKT_FIL_INI     80      /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define                KNAME_FMT       81      /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define                SAFE_PRIV_ERROR -1      /* syscall error */
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad  0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_long  0-->3, 1-->2, 2-->1, 3-->0
+ * u_short 0-->1, 1-->0
+ */
+
+#define            swap_u_16(x) {\
+       unsigned long   _krb_swap_tmp[4]; \
+       swab(((char *)x) +0,  ((char *)_krb_swap_tmp) +14, 2); \
+       swab(((char *)x) +2,  ((char *)_krb_swap_tmp) +12, 2); \
+       swab(((char *)x) +4,  ((char *)_krb_swap_tmp) +10, 2); \
+       swab(((char *)x) +6,  ((char *)_krb_swap_tmp) +8, 2); \
+       swab(((char *)x) +8,  ((char *)_krb_swap_tmp) +6, 2); \
+       swab(((char *)x) +10, ((char *)_krb_swap_tmp) +4, 2); \
+       swab(((char *)x) +12, ((char *)_krb_swap_tmp) +2, 2); \
+       swab(((char *)x) +14, ((char *)_krb_swap_tmp) +0, 2); \
+       memcpy((char *)x, (char *)_krb_swap_tmp, 16); \
+       }
+
+#define            swap_u_12(x) {\
+       unsigned long   _krb_swap_tmp[4]; \
+       swab(((char *)x) +0,   ((char *)_krb_swap_tmp) +10, 2); \
+       swab(((char *)x) +2,  ((char *)_krb_swap_tmp) +8, 2); \
+       swab(((char *)x) +4,  ((char *)_krb_swap_tmp) +6, 2); \
+       swab(((char *)x) +6,  ((char *)_krb_swap_tmp) +4, 2); \
+       swab(((char *)x) +8,  ((char *)_krb_swap_tmp) +2, 2); \
+       swab(((char *)x) +10, ((char *)_krb_swap_tmp) +0, 2); \
+       memcpy((char *)x, (char *)_krb_swap_tmp, 12); \
+       }
+
+#define            swap_C_Block(x) {\
+       unsigned long   _krb_swap_tmp[4]; \
+       swab(((char *)x) +0,  ((char *)_krb_swap_tmp) +6, 2); \
+       swab(((char *)x) +2,  ((char *)_krb_swap_tmp) +4, 2); \
+       swab(((char *)x) +4,  ((char *)_krb_swap_tmp) +2, 2); \
+       swab(((char *)x) +6,  ((char *)_krb_swap_tmp) +0, 2); \
+       memcpy((char *)x, (char *)_krb_swap_tmp, 8); \
+       }
+
+#define            swap_u_quad(x) {\
+       unsigned long   _krb_swap_tmp[4]; \
+       swab(((char *)&x) +0,  ((char *)_krb_swap_tmp) +6, 2); \
+       swab(((char *)&x) +2,  ((char *)_krb_swap_tmp) +4, 2); \
+       swab(((char *)&x) +4,  ((char *)_krb_swap_tmp) +2, 2); \
+       swab(((char *)&x) +6,  ((char *)_krb_swap_tmp) +0, 2); \
+       memcpy((char *)&x, (char *)_krb_swap_tmp, 8); \
+       }
+
+#define            swap_u_long(x) { \
+       unsigned long   _krb_swap_tmp[4]; \
+       swab(((char *)&x) +0,  ((char *)_krb_swap_tmp) +2, 2); \
+       swab(((char *)&x) +2,  ((char *)_krb_swap_tmp) +0, 2); \
+       x = _krb_swap_tmp[0]; \
+       }
+
+#define            swap_u_short(x) {\
+       unsigned short  _krb_swap_sh_tmp; \
+       swab(((char *)&x),   (&_krb_swap_sh_tmp), 2); \
+       x = (unsigned short) _krb_swap_sh_tmp; \
+       }
+
+/* Kerberos ticket flag field bit definitions */
+#define        K_FLAG_ORDER    0       /* bit 0 --> lsb */
+#define        K_FLAG_1                /* reserved */
+#define        K_FLAG_2                /* reserved */
+#define        K_FLAG_3                /* reserved */
+#define        K_FLAG_4                /* reserved */
+#define        K_FLAG_5                /* reserved */
+#define        K_FLAG_6                /* reserved */
+#define        K_FLAG_7                /* reserved, bit 7 --> msb */
+
+#ifndef PC
+char *tkt_string();
+#endif /* PC */
+
+/*
+ * forward declartion otherwise need to include netinet/in.h
+ */
+
+struct sockaddr_in;
+
+#ifdef OLDNAMES
+#define        krb_mk_req              mk_ap_req
+#define        krb_rd_req              rd_ap_req
+#define        krb_kntoln              an_to_ln
+#define        krb_set_key             set_serv_key
+#define        krb_get_cred            get_credentials
+#define        krb_mk_priv             mk_private_msg
+#define        krb_rd_priv             rd_private_msg
+#define        krb_mk_safe             mk_safe_msg
+#define        krb_rd_safe             rd_safe_msg
+#define        krb_mk_err              mk_appl_err_msg
+#define        krb_rd_err              rd_appl_err_msg
+#define        krb_ck_repl             check_replay
+#define        krb_get_pw_in_tkt       get_in_tkt
+#define        krb_get_svc_in_tkt      get_svc_in_tkt
+#define        krb_get_pw_tkt          get_pw_tkt
+#define        krb_realmofhost         krb_getrealm
+#define        krb_get_phost           get_phost
+#define        krb_get_krbhst          get_krbhst
+#define        krb_get_lrealm          get_krbrlm
+#else
+#ifdef __STDC__
+extern int krb_mk_req(KTEXT, char *, char *, char *, long);
+extern int krb_rd_req(KTEXT, char *, char *, long, AUTH_DAT *, char *);
+extern int krb_kntoln(AUTH_DAT *, char *);
+extern int krb_set_key(char *, int);
+extern int krb_get_cred(char *, char *, char *, CREDENTIALS *);
+extern long krb_mk_safe(unsigned char *, unsigned char *, unsigned long,
+       C_Block *, struct sockaddr_in *, struct sockaddr_in *);
+extern long krb_rd_safe(unsigned char *, unsigned long, C_Block *,
+       struct sockaddr_in *, struct sockaddr_in *, MSG_DAT *);
+extern long krb_mk_err(unsigned char *, long, char *);
+extern int krb_rd_err(unsigned char *, unsigned long, long *, MSG_DAT *);
+extern char *krb_realmofhost(char *);
+extern char *krb_get_phost(char *);
+extern int krb_get_krbhst(char *, char *, int);
+extern int krb_get_admhst(char *, char *, int);
+extern int krb_get_lrealm(char *realm, int n);
+extern int krb_sendauth(long, int, KTEXT, char *, char *, char *, unsigned long,
+       MSG_DAT *, CREDENTIALS *, Key_schedule, struct sockaddr_in *,
+       struct sockaddr_in *, char *);
+extern int krb_recvauth(long, int, KTEXT, char *, char *,
+       struct sockaddr_in *, struct sockaddr_in *,
+       AUTH_DAT *, char *, Key_schedule, char *);
+extern int krb_net_write(int, char *, int);
+extern int krb_net_read(int, char *, int);
+extern void krb_set_tkt_string(char *);
+#else
+extern int krb_mk_req();
+extern int krb_rd_req();
+extern int krb_kntoln();
+extern int krb_set_key();
+extern int krb_get_cred();
+extern long krb_mk_safe();
+extern long krb_rd_safe();
+extern long krb_mk_err();
+extern int krb_rd_err();
+extern char *krb_realmofhost();
+extern char *krb_get_phost();
+extern int krb_get_krbhst();
+extern int krb_get_admhst();
+extern int krb_get_lrealm();
+extern int krb_sendauth();
+extern int krb_recvauth();
+extern int krb_net_write();
+extern int krb_net_read();
+extern void krb_set_tkt_string();
+#endif /* __STDC__ */
+#endif /* OLDNAMES */
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define        KOPT_DONT_MK_REQ        0x00000001      /* don't call krb_mk_req */
+#define        KOPT_DO_MUTUAL          0x00000002      /* do mutual auth */
+#define        KOPT_DONT_CANON         0x00000004      /* don't canonicalize inst */
+                                               /* as a hostname */
+
+#define        KRB_SENDAUTH_VLEN       8               /* length for version strings */
+
+#ifdef ATHENA_COMPAT
+#define        KOPT_DO_OLDSTYLE        0x00000008      /* use the old-style protocol */
+#endif /* ATHENA_COMPAT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_KRB_H */
diff --git a/mac/kerberos_includes/osconf.h b/mac/kerberos_includes/osconf.h
new file mode 100755 (executable)
index 0000000..6744de4
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $Source: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/osconf.h
+ * $Author: rjs3 $
+ * $Header: /afs/athena.mit.edu/astaff/project/kerberos/src/include/RCS/osconf.h
+ *             4.4 89/12/19 13:26:27 jtkohl Exp $
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Athena configuration.
+ */
+
+#ifndef        _KERBEROS_OSCONF_H
+#define        _KERBEROS_OSCONF_H
+
+#pragma ident  "@(#)osconf.h   1.7     94/07/29 SMI"
+
+#include <kerberos/mit-copyright.h>
+
+#ifdef tahoe
+#include <kerberos/conf-bsdtahoe.h>
+#else /* !tahoe */
+#ifdef vax
+#include <kerberos/conf-bsdvax.h>
+#else /* !vax */
+#if defined(mips) && defined(ultrix)
+#include <kerberos/conf-ultmips2.h>
+#else /* !Ultrix MIPS-2 */
+#ifdef ibm032
+#include <kerberos/conf-bsdibm032.h>
+#else /* !ibm032 */
+#ifdef apollo
+#include <kerberos/conf-bsdapollo.h>
+#else /* !apollo */
+#ifdef sun
+#ifdef sparc
+#if defined(SunOS) && SunOS >= 50
+#include <kerberos/conf-svsparc.h>
+#else
+#include <kerberos/conf-bsdsparc.h>
+#endif
+#else /* sun but not sparc */
+#ifdef i386
+#include <kerberos/conf-bsd386i.h>
+#else /* sun but not sparc or i386 */
+#ifdef __ppc
+#include <kerberos/conf-svppc.h>
+#else /* sun but not (sparc, i386, or ppc) */
+#include <kerberos/conf-bsdm68k.h>
+#endif /* ppc */
+#endif /* i386 */
+#endif /* sparc */
+#else /* !sun */
+#ifdef pyr
+#include <kerberos/conf-pyr.h>
+#endif /* pyr */
+#endif /* sun */
+#endif /* apollo */
+#endif /* ibm032 */
+#endif /* mips */
+#endif /* vax */
+#endif /* tahoe */
+
+#endif /* _KERBEROS_OSCONF_H */
diff --git a/mac/kerberos_includes/prot.h b/mac/kerberos_includes/prot.h
new file mode 100755 (executable)
index 0000000..987867c
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * $Source: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/prot.h,v $
+ * $Author: rjs3 $
+ * $Header: /afs/andrew/system/cvs/src/sasl/mac/kerberos_includes/prot.h,v 1.2 2001/12/04 02:06:06 rjs3 Exp $
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ *
+ * Include file with authentication protocol information.
+ */
+#ifndef        _KERBEROS_PROT_H
+#define        _KERBEROS_PROT_H
+
+#ifdef RUBBISH
+#pragma ident  "@(#)prot.h     1.3     92/07/14 SMI"
+#endif
+
+//#include <kerberos/mit-copyright.h>
+#ifdef RUBBISH
+#include <kerberos/krb_conf.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define                KRB_PORT                750     /* PC's don't have */
+                                               /* /etc/services */
+#define                KRB_PROT_VERSION        4
+#define                MAX_PKT_LEN             1000
+#define                MAX_TXT_LEN             1000
+#define                TICKET_GRANTING_TICKET  "krbtgt"
+
+/* Macro's to obtain various fields from a packet */
+
+#define        pkt_version(packet)  (unsigned int) *(packet->dat)
+#define        pkt_msg_type(packet) (unsigned int) *(packet->dat+1)
+#define        pkt_a_name(packet)   (packet->dat+2)
+#define        pkt_a_inst(packet)   \
+       (packet->dat+3+strlen((char *)pkt_a_name(packet)))
+#define        pkt_a_realm(packet)  \
+       (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet)))
+
+/* Macro to obtain realm from application request */
+#define        apreq_realm(auth)       (auth->dat + 3)
+
+#define        pkt_time_ws(packet) (char *) \
+       (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \
+           strlen((char *)pkt_a_inst(packet)) + \
+           strlen((char *)pkt_a_realm(packet)))
+
+#define        pkt_no_req(packet) (unsigned short) \
+       *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+           strlen((char *)pkt_a_inst(packet)) + \
+           strlen((char *)pkt_a_realm(packet)))
+#define        pkt_x_date(packet) (char *) \
+       (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \
+           strlen((char *)pkt_a_inst(packet)) + \
+           strlen((char *)pkt_a_realm(packet)))
+#define        pkt_err_code(packet) ((char *) \
+       (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+           strlen((char *)pkt_a_inst(packet)) + \
+           strlen((char *)pkt_a_realm(packet))))
+#define        pkt_err_text(packet) \
+       (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \
+           strlen((char *)pkt_a_inst(packet)) + \
+           strlen((char *)pkt_a_realm(packet)))
+
+/* Routines to create and read packets may be found in prot.c */
+
+#ifdef RUBBISH
+KTEXT create_auth_reply();
+KTEXT create_death_packet();
+KTEXT pkt_cipher();
+#endif
+
+/* Message types , always leave lsb for byte order */
+
+#define                AUTH_MSG_KDC_REQUEST                     1<<1
+#define                AUTH_MSG_KDC_REPLY                       2<<1
+#define                AUTH_MSG_APPL_REQUEST                    3<<1
+#define                AUTH_MSG_APPL_REQUEST_MUTUAL             4<<1
+#define                AUTH_MSG_ERR_REPLY                       5<<1
+#define                AUTH_MSG_PRIVATE                         6<<1
+#define                AUTH_MSG_SAFE                            7<<1
+#define                AUTH_MSG_APPL_ERR                        8<<1
+#define                AUTH_MSG_DIE                            63<<1
+
+/* values for kerb error codes */
+
+#define                KERB_ERR_OK                              0
+#define                KERB_ERR_NAME_EXP                        1
+#define                KERB_ERR_SERVICE_EXP                     2
+#define                KERB_ERR_AUTH_EXP                        3
+#define                KERB_ERR_PKT_VER                         4
+#define                KERB_ERR_NAME_MAST_KEY_VER               5
+#define                KERB_ERR_SERV_MAST_KEY_VER               6
+#define                KERB_ERR_BYTE_ORDER                      7
+#define                KERB_ERR_PRINCIPAL_UNKNOWN               8
+#define                KERB_ERR_PRINCIPAL_NOT_UNIQUE            9
+#define                KERB_ERR_NULL_KEY                       10
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _KERBEROS_PROT_H */
diff --git a/mac/krb4_sources/krb-archaeology.h b/mac/krb4_sources/krb-archaeology.h
new file mode 100755 (executable)
index 0000000..ddf3bca
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * $Id: krb-archaeology.h,v 1.2 2001/12/04 02:06:08 rjs3 Exp $
+ *
+ * Most of the cruft in this file is probably:
+ *
+ * Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
+ * of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+#ifndef __KRB_ARCHAEOLOGY_H__
+#define __KRB_ARCHAEOLOGY_H__
+
+/* Compare x and y in VAX byte order, result is -1, 0 or 1. */
+
+#define krb_lsb_antinet_ulong_less(x, y) (((x) == (y)) ? 0 :  krb_lsb_antinet_ulong_cmp(x, y))
+
+#define krb_lsb_antinet_ushort_less(x, y) (((x) == (y)) ? 0 : krb_lsb_antinet_ushort_cmp(x, y))
+
+int krb_lsb_antinet_ulong_cmp(u_int32_t x, u_int32_t y);
+int krb_lsb_antinet_ushort_cmp(u_int16_t x, u_int16_t y);
+u_int32_t lsb_time(time_t t, struct sockaddr_in *src, struct sockaddr_in *dst);
+
+/* Macro's to obtain various fields from a packet */
+
+#define pkt_version(packet)  (unsigned int) *(packet->dat)
+#define pkt_msg_type(packet) (unsigned int) *(packet->dat+1)
+#define pkt_a_name(packet)   (packet->dat+2)
+#define pkt_a_inst(packet)   \
+       (packet->dat+3+strlen((char *)pkt_a_name(packet)))
+#define pkt_a_realm(packet)  \
+       (pkt_a_inst(packet)+1+strlen((char *)pkt_a_inst(packet)))
+
+/* Macro to obtain realm from application request */
+#define apreq_realm(auth)     (auth->dat + 3)
+
+#define pkt_time_ws(packet) (char *) \
+        (packet->dat+5+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+#define pkt_no_req(packet) (unsigned short) \
+        *(packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+         strlen((char *)pkt_a_inst(packet)) + \
+         strlen((char *)pkt_a_realm(packet)))
+#define pkt_x_date(packet) (char *) \
+        (packet->dat+10+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+#define xxx_pkt_err_code(packet) ( (char *) \
+        (packet->dat+9+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet))))
+#define pkt_err_text(packet) \
+        (packet->dat+13+strlen((char *)pkt_a_name(packet)) + \
+        strlen((char *)pkt_a_inst(packet)) + \
+        strlen((char *)pkt_a_realm(packet)))
+
+/*
+ * macros for byte swapping; also scratch space
+ * u_quad  0-->7, 1-->6, 2-->5, 3-->4, 4-->3, 5-->2, 6-->1, 7-->0
+ * u_int32_t  0-->3, 1-->2, 2-->1, 3-->0
+ * u_int16_t 0-->1, 1-->0
+ */
+
+#define     swap_u_16(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(((char *) x) +0, ((char *)  _krb_swap_tmp) +14 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +12 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +8  ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +12,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +14,((char *)  _krb_swap_tmp) +0 ,2); \
+ memcpy(x, _krb_swap_tmp, 16);\
+                            }
+
+#define     swap_u_12(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) x,     ((char *)  _krb_swap_tmp) +10 ,2); \
+ swab(((char *) x) +2, ((char *)  _krb_swap_tmp) +8 ,2); \
+ swab(((char *) x) +4, ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +6, ((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +8, ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +10,((char *)  _krb_swap_tmp) +0 ,2); \
+ memcpy(x, _krb_swap_tmp, 12);\
+                            }
+
+#define     swap_C_Block(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ memcpy(x, _krb_swap_tmp, 8);\
+                            }
+#define     swap_u_quad(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab(( char *) &x,    ((char *)  _krb_swap_tmp) +6 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp) +4 ,2); \
+ swab(((char *) &x) +4,((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +6,((char *)  _krb_swap_tmp)    ,2); \
+ memcpy(x, _krb_swap_tmp, 8);\
+                            }
+
+#define     swap_u_long(x) {\
+ u_int32_t   _krb_swap_tmp[4];\
+ swab((char *)  &x,    ((char *)  _krb_swap_tmp) +2 ,2); \
+ swab(((char *) &x) +2,((char *)  _krb_swap_tmp),2); \
+ x = _krb_swap_tmp[0];   \
+                           }
+
+#define     swap_u_short(x) {\
+ u_int16_t     _krb_swap_sh_tmp; \
+ swab((char *)  &x,    ( &_krb_swap_sh_tmp) ,2); \
+ x = (u_int16_t) _krb_swap_sh_tmp; \
+                            }
+/* Kerberos ticket flag field bit definitions */
+#define K_FLAG_ORDER    0       /* bit 0 --> lsb */
+#define K_FLAG_1                /* reserved */
+#define K_FLAG_2                /* reserved */
+#define K_FLAG_3                /* reserved */
+#define K_FLAG_4                /* reserved */
+#define K_FLAG_5                /* reserved */
+#define K_FLAG_6                /* reserved */
+#define K_FLAG_7                /* reserved, bit 7 --> msb */
+
+#endif /* __KRB_ARCHAEOLOGY_H__ */
diff --git a/mac/krb4_sources/krb-protos.h b/mac/krb4_sources/krb-protos.h
new file mode 100755 (executable)
index 0000000..cb9209b
--- /dev/null
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. All advertising materials mentioning features or use of this software 
+ *    must display the following acknowledgement: 
+ *      This product includes software developed by Kungliga Tekniska 
+ *      H\9agskolan and its contributors. 
+ *
+ * 4. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id: krb-protos.h,v 1.2 2001/12/04 02:06:08 rjs3 Exp $ */
+
+#ifndef __krb_protos_h__
+#define __krb_protos_h__
+
+#if defined (__STDC__) || defined (_MSC_VER)
+#include <stdarg.h>
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+#ifdef __STDC__
+struct in_addr;
+struct sockaddr_in;
+struct timeval;
+#endif
+
+#ifndef KRB_LIB_FUNCTION
+#if defined(__BORLANDC__)
+#define KRB_LIB_FUNCTION /* not-ready-definition-yet */
+#elif defined(_MSC_VER)
+#define KRB_LIB_FUNCTION /* not-ready-definition-yet2 */
+#else
+#define KRB_LIB_FUNCTION
+#endif
+#endif
+
+void KRB_LIB_FUNCTION
+afs_string_to_key __P((
+       char *str,
+       char *cell,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+create_ciph __P((
+       KTEXT c,
+       unsigned char *session,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t life,
+       int kvno,
+       KTEXT tkt,
+       u_int32_t kdc_time,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+cr_err_reply __P((
+       KTEXT pkt,
+       char *pname,
+       char *pinst,
+       char *prealm,
+       u_int32_t time_ws,
+       u_int32_t e,
+       char *e_string));
+
+int KRB_LIB_FUNCTION
+decomp_ticket __P((
+       KTEXT tkt,
+       unsigned char *flags,
+       char *pname,
+       char *pinstance,
+       char *prealm,
+       u_int32_t *paddress,
+       unsigned char *session,
+       int *life,
+       u_int32_t *time_sec,
+       char *sname,
+       char *sinstance,
+       des_cblock *key,
+       des_key_schedule schedule));
+
+int KRB_LIB_FUNCTION
+dest_tkt __P((void));
+
+int KRB_LIB_FUNCTION
+get_ad_tkt __P((
+       char *service,
+       char *sinstance,
+       char *realm,
+       int lifetime));
+
+int KRB_LIB_FUNCTION
+getst __P((
+       int fd,
+       char *s,
+       int n));
+
+int KRB_LIB_FUNCTION
+in_tkt __P((
+       char *pname,
+       char *pinst));
+
+int KRB_LIB_FUNCTION
+k_get_all_addrs __P((struct in_addr **l));
+
+int KRB_LIB_FUNCTION
+k_gethostname __P((
+       char *name,
+       int namelen));
+
+int KRB_LIB_FUNCTION
+k_getportbyname __P((
+       const char *service,
+       const char *proto,
+       int default_port));
+
+int KRB_LIB_FUNCTION
+k_getsockinst __P((
+       int fd,
+       char *inst,
+       size_t inst_size));
+
+int KRB_LIB_FUNCTION
+k_isinst __P((char *s));
+
+int KRB_LIB_FUNCTION
+k_isname __P((char *s));
+
+int KRB_LIB_FUNCTION
+k_isrealm __P((char *s));
+
+struct tm * KRB_LIB_FUNCTION
+k_localtime __P((u_int32_t *tp));
+
+int KRB_LIB_FUNCTION
+kname_parse __P((
+       char *np,
+       char *ip,
+       char *rp,
+       char *fullname));
+
+int KRB_LIB_FUNCTION
+krb_atime_to_life __P((char *atime));
+
+int KRB_LIB_FUNCTION
+krb_check_auth __P((
+       KTEXT packet,
+       u_int32_t checksum,
+       MSG_DAT *msg_data,
+       des_cblock *session,
+       struct des_ks_struct *schedule,
+       struct sockaddr_in *laddr,
+       struct sockaddr_in *faddr));
+
+int KRB_LIB_FUNCTION
+krb_check_tm __P((struct tm tm));
+
+KTEXT KRB_LIB_FUNCTION
+krb_create_death_packet __P((char *a_name));
+
+int KRB_LIB_FUNCTION
+krb_create_ticket __P((
+       KTEXT tkt,
+       unsigned char flags,
+       char *pname,
+       char *pinstance,
+       char *prealm,
+       int32_t paddress,
+       void *session,
+       int16_t life,
+       int32_t time_sec,
+       char *sname,
+       char *sinstance,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+krb_decode_as_rep __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       key_proc_t key_proc,
+       decrypt_proc_t decrypt_proc,
+       void *arg,
+       KTEXT as_rep,
+       CREDENTIALS *cred));
+
+int KRB_LIB_FUNCTION
+krb_enable_debug __P((void));
+
+int KRB_LIB_FUNCTION
+krb_equiv __P((
+       u_int32_t a,
+       u_int32_t b));
+
+int KRB_LIB_FUNCTION
+krb_get_address __P((
+       void *from,
+       u_int32_t *to));
+
+int KRB_LIB_FUNCTION
+krb_get_admhst __P((
+       char *host,
+       char *realm,
+       int nth));
+
+int KRB_LIB_FUNCTION
+krb_get_config_bool __P((const char *variable));
+
+const char * KRB_LIB_FUNCTION
+krb_get_config_string __P((const char *variable));
+
+int KRB_LIB_FUNCTION
+krb_get_cred __P((
+        char *service,
+        char *instance,
+        char *realm,
+        CREDENTIALS *c));
+
+int KRB_LIB_FUNCTION
+krb_get_default_principal __P((
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_get_default_realm __P((void));
+
+const char * KRB_LIB_FUNCTION
+krb_get_err_text __P((int code));
+
+struct krb_host* KRB_LIB_FUNCTION
+krb_get_host __P((
+       int nth,
+       char *realm,
+       int admin));
+
+int KRB_LIB_FUNCTION
+krb_get_in_tkt __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       key_proc_t key_proc,
+       decrypt_proc_t decrypt_proc,
+       void *arg));
+
+int KRB_LIB_FUNCTION
+krb_get_int __P((
+       void *f,
+       u_int32_t *to,
+       int size,
+       int lsb));
+
+int KRB_LIB_FUNCTION
+krb_get_kdc_time_diff __P((void));
+
+int KRB_LIB_FUNCTION
+krb_get_krbconf __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_krbextra __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_krbhst __P((
+       char *host,
+       char *realm,
+       int nth));
+
+int KRB_LIB_FUNCTION
+krb_get_krbrealms __P((
+       int num,
+       char *buf,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_get_lrealm __P((
+       char *r,
+       int n));
+
+int KRB_LIB_FUNCTION
+krb_get_nir __P((
+       void *from,
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_get_phost __P((const char *alias));
+
+int KRB_LIB_FUNCTION
+krb_get_pw_in_tkt __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       char *password));
+
+int KRB_LIB_FUNCTION
+krb_get_pw_in_tkt2 __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       char *password,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+krb_get_string __P((
+       void *from,
+       char *to,
+       size_t to_size));
+
+int KRB_LIB_FUNCTION
+krb_get_svc_in_tkt __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       char *srvtab));
+
+int KRB_LIB_FUNCTION
+krb_get_tf_fullname __P((
+       char *ticket_file,
+       char *name,
+       char *instance,
+       char *realm));
+
+int KRB_LIB_FUNCTION
+krb_get_tf_realm __P((
+       char *ticket_file,
+       char *realm));
+
+void KRB_LIB_FUNCTION
+krb_kdctimeofday __P((struct timeval *tv));
+
+int KRB_LIB_FUNCTION
+krb_kntoln __P((
+       AUTH_DAT *ad,
+       char *lname));
+
+int KRB_LIB_FUNCTION
+krb_kuserok __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *luser));
+
+char * KRB_LIB_FUNCTION
+krb_life_to_atime __P((int life));
+
+u_int32_t KRB_LIB_FUNCTION
+krb_life_to_time __P((
+       u_int32_t start,
+       int life_));
+
+int KRB_LIB_FUNCTION
+krb_lsb_antinet_ulong_cmp __P((
+       u_int32_t x,
+       u_int32_t y));
+
+int KRB_LIB_FUNCTION
+krb_lsb_antinet_ushort_cmp __P((
+       u_int16_t x,
+       u_int16_t y));
+
+int KRB_LIB_FUNCTION
+krb_mk_as_req __P((
+       char *user,
+       char *instance,
+       char *realm,
+       char *service,
+       char *sinstance,
+       int life,
+       KTEXT cip));
+
+int KRB_LIB_FUNCTION
+krb_mk_auth __P((
+       int32_t options,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t checksum,
+       char *version,
+       KTEXT buf));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_err __P((
+       u_char *p,
+       int32_t e,
+       char *e_string));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_priv __P((
+       void *in,
+       void *out,
+       u_int32_t length,
+       struct des_ks_struct *schedule,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver));
+
+int KRB_LIB_FUNCTION
+krb_mk_req __P((
+       KTEXT authent,
+       char *service,
+       char *instance,
+       char *realm,
+       int32_t checksum));
+
+int32_t KRB_LIB_FUNCTION
+krb_mk_safe __P((
+       void *in,
+       void *out,
+       u_int32_t length,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver));
+
+int KRB_LIB_FUNCTION
+krb_net_read __P((
+       int fd,
+       void *v,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_net_write __P((
+       int fd,
+       const void *v,
+       size_t len));
+
+int KRB_LIB_FUNCTION
+krb_parse_name __P((
+       const char *fullname,
+       krb_principal *principal));
+
+int KRB_LIB_FUNCTION
+krb_put_address __P((
+       u_int32_t addr,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_put_int __P((
+       u_int32_t from,
+       void *to,
+       size_t rem,
+       int size));
+
+int KRB_LIB_FUNCTION
+krb_put_nir __P((
+       char *name,
+       char *instance,
+       char *realm,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_put_string __P((
+       char *from,
+       void *to,
+       size_t rem));
+
+int KRB_LIB_FUNCTION
+krb_rd_err __P((
+       u_char *in,
+       u_int32_t in_length,
+       int32_t *code,
+       MSG_DAT *m_data));
+
+int32_t KRB_LIB_FUNCTION
+krb_rd_priv __P((
+       void *in,
+       u_int32_t in_length,
+       struct des_ks_struct *schedule,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver,
+       MSG_DAT *m_data));
+
+int KRB_LIB_FUNCTION
+krb_rd_req __P((
+       KTEXT authent,
+       char *service,
+       char *instance,
+       int32_t from_addr,
+       AUTH_DAT *ad,
+       char *fn));
+
+int32_t KRB_LIB_FUNCTION
+krb_rd_safe __P((
+       void *in,
+       u_int32_t in_length,
+       des_cblock *key,
+       struct sockaddr_in *sender,
+       struct sockaddr_in *receiver,
+       MSG_DAT *m_data));
+
+int KRB_LIB_FUNCTION
+krb_realm_parse __P((
+       char *realm,
+       int length));
+
+char * KRB_LIB_FUNCTION
+krb_realmofhost __P((const char *host));
+
+int KRB_LIB_FUNCTION
+krb_recvauth __P((
+       int32_t options,
+       int fd,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       struct sockaddr_in *faddr,
+       struct sockaddr_in *laddr,
+       AUTH_DAT *kdata,
+       char *filename,
+       struct des_ks_struct *schedule,
+       char *version));
+
+int KRB_LIB_FUNCTION
+krb_sendauth __P((
+       int32_t options,
+       int fd,
+       KTEXT ticket,
+       char *service,
+       char *instance,
+       char *realm,
+       u_int32_t checksum,
+       MSG_DAT *msg_data,
+       CREDENTIALS *cred,
+       struct des_ks_struct *schedule,
+       struct sockaddr_in *laddr,
+       struct sockaddr_in *faddr,
+       char *version));
+
+void KRB_LIB_FUNCTION
+krb_set_kdc_time_diff __P((int diff));
+
+int KRB_LIB_FUNCTION
+krb_set_key __P((
+       void *key,
+       int cvt));
+
+int KRB_LIB_FUNCTION
+krb_set_lifetime __P((int newval));
+
+void KRB_LIB_FUNCTION
+krb_set_tkt_string __P((const char *val));
+
+const char * KRB_LIB_FUNCTION
+krb_stime __P((time_t *t));
+
+int KRB_LIB_FUNCTION
+krb_time_to_life __P((
+       u_int32_t start,
+       u_int32_t end));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name __P((krb_principal *pr));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_long __P((
+       char *name,
+       char *instance,
+       char *realm));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_long_r __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *fullname));
+
+char * KRB_LIB_FUNCTION
+krb_unparse_name_r __P((
+       krb_principal *pr,
+       char *fullname));
+
+int KRB_LIB_FUNCTION
+krb_use_admin_server __P((int flag));
+
+int KRB_LIB_FUNCTION
+krb_verify_user __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *password,
+       int secure,
+       char *linstance));
+
+int KRB_LIB_FUNCTION
+krb_verify_user_srvtab __P((
+       char *name,
+       char *instance,
+       char *realm,
+       char *password,
+       int secure,
+       char *linstance,
+       char *srvtab));
+
+int KRB_LIB_FUNCTION
+kuserok __P((
+       AUTH_DAT *auth,
+       char *luser));
+
+u_int32_t KRB_LIB_FUNCTION
+lsb_time __P((
+       time_t t,
+       struct sockaddr_in *src,
+       struct sockaddr_in *dst));
+
+const char * KRB_LIB_FUNCTION
+month_sname __P((int n));
+
+int KRB_LIB_FUNCTION
+passwd_to_5key __P((
+       char *user,
+       char *instance,
+       char *realm,
+       void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+passwd_to_afskey __P((
+       char *user,
+       char *instance,
+       char *realm,
+       void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+passwd_to_key __P((
+       char *user,
+       char *instance,
+       char *realm,
+       void *passwd,
+       des_cblock *key));
+
+int KRB_LIB_FUNCTION
+read_service_key __P((
+       char *service,
+       char *instance,
+       char *realm,
+       int kvno,
+       char *file,
+       char *key));
+
+int KRB_LIB_FUNCTION
+save_credentials __P((
+       char *service,
+       char *instance,
+       char *realm,
+       unsigned char *session,
+       int lifetime,
+       int kvno,
+       KTEXT ticket,
+       int32_t issue_date));
+
+int KRB_LIB_FUNCTION
+send_to_kdc __P((
+       KTEXT pkt,
+       KTEXT rpkt,
+       char *realm));
+
+int KRB_LIB_FUNCTION
+srvtab_to_key __P((
+       char *user,
+       char *instance,
+       char *realm,
+       void *srvtab,
+       des_cblock *key));
+
+void KRB_LIB_FUNCTION
+tf_close __P((void));
+
+int KRB_LIB_FUNCTION
+tf_create __P((char *tf_name));
+
+int KRB_LIB_FUNCTION
+tf_get_cred __P((CREDENTIALS *c));
+
+int KRB_LIB_FUNCTION
+tf_get_pinst __P((char *inst));
+
+int KRB_LIB_FUNCTION
+tf_get_pname __P((char *p));
+
+int KRB_LIB_FUNCTION
+tf_init __P((
+       char *tf_name,
+       int rw));
+
+int KRB_LIB_FUNCTION
+tf_put_pinst __P((char *inst));
+
+int KRB_LIB_FUNCTION
+tf_put_pname __P((char *p));
+
+int KRB_LIB_FUNCTION
+tf_save_cred __P((
+       char *service,
+       char *instance,
+       char *realm,
+       unsigned char *session,
+       int lifetime,
+       int kvno,
+       KTEXT ticket,
+       u_int32_t issue_date));
+
+int KRB_LIB_FUNCTION
+tf_setup __P((
+       CREDENTIALS *cred,
+       char *pname,
+       char *pinst));
+
+char * KRB_LIB_FUNCTION
+tkt_string __P((void));
+
+#endif /* __krb_protos_h__ */
diff --git a/mac/krb4_sources/krb.h b/mac/krb4_sources/krb.h
new file mode 100755 (executable)
index 0000000..c491b4c
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * $Id: krb.h,v 1.2 2001/12/04 02:06:08 rjs3 Exp $
+ *
+ * Copyright 1987, 1988 by the Massachusetts Institute of Technology. 
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>. 
+ *
+ * Include file for the Kerberos library. 
+ */
+
+#if !defined (__STDC__) && !defined(_MSC_VER)
+#define const
+#define signed
+#endif
+
+#include <ktypes.h>
+#include <time.h>
+
+#ifndef __KRB_H__
+#define __KRB_H__
+
+/* XXX */
+#ifndef __BEGIN_DECLS
+#if defined(__cplusplus)
+#define        __BEGIN_DECLS   extern "C" {
+#define        __END_DECLS     };
+#else
+#define        __BEGIN_DECLS
+#define        __END_DECLS
+#endif
+#endif
+
+#if defined (__STDC__) || defined (_MSC_VER)
+#ifndef __P
+#define __P(x) x
+#endif
+#else
+#ifndef __P
+#define __P(x) ()
+#endif
+#endif
+
+__BEGIN_DECLS
+
+/* Need some defs from des.h    */
+#if !defined(NOPROTO) && !defined(__STDC__)
+#define NOPROTO
+#endif
+#include <des.h>
+
+/* CNS compatibility ahead! */
+#ifndef KRB_INT32
+#define KRB_INT32 int32_t
+#endif
+#ifndef KRB_UINT32
+#define KRB_UINT32 u_int32_t
+#endif
+
+/* Global library variables. */
+extern int krb_ignore_ip_address; /* To turn off IP address comparison */
+extern int krb_no_long_lifetimes; /* To disable AFS compatible lifetimes */
+extern int krbONE;
+#define         HOST_BYTE_ORDER (* (char *) &krbONE)
+/* Debug variables */
+extern int krb_debug;
+extern int krb_ap_req_debug;
+extern int krb_dns_debug;
+
+
+/* Text describing error codes */
+#define                MAX_KRB_ERRORS  256
+extern const char *krb_err_txt[MAX_KRB_ERRORS];
+
+/* General definitions */
+#define                KSUCCESS        0
+#define                KFAILURE        255
+
+/*
+ * Kerberos specific definitions 
+ *
+ * KRBLOG is the log file for the kerberos master server. KRB_CONF is
+ * the configuration file where different host machines running master
+ * and slave servers can be found. KRB_MASTER is the name of the
+ * machine with the master database.  The admin_server runs on this
+ * machine, and all changes to the db (as opposed to read-only
+ * requests, which can go to slaves) must go to it. KRB_HOST is the
+ * default machine * when looking for a kerberos slave server.  Other
+ * possibilities are * in the KRB_CONF file. KRB_REALM is the name of
+ * the realm. 
+ */
+
+/* /etc/kerberosIV is only for backwards compatibility, don't use it! */
+#ifndef KRB_CONF
+#define KRB_CONF       "/etc/krb.conf"
+#endif
+#ifndef KRB_RLM_TRANS
+#define KRB_RLM_TRANS   "/etc/krb.realms"
+#endif
+#ifndef KRB_CNF_FILES
+#define KRB_CNF_FILES  { KRB_CONF,   "/etc/kerberosIV/krb.conf", 0}
+#endif
+#ifndef KRB_RLM_FILES
+#define KRB_RLM_FILES  { KRB_RLM_TRANS, "/etc/kerberosIV/krb.realms", 0}
+#endif
+#ifndef KRB_EQUIV
+#define KRB_EQUIV      "/etc/krb.equiv"
+#endif
+#define KRB_MASTER     "kerberos"
+#ifndef KRB_REALM
+#define KRB_REALM      (krb_get_default_realm())
+#endif
+
+/* The maximum sizes for aname, realm, sname, and instance +1 */
+#define        ANAME_SZ        40
+#define                REALM_SZ        40
+#define                SNAME_SZ        40
+#define                INST_SZ         40
+/* Leave space for quoting */
+#define                MAX_K_NAME_SZ   (2*ANAME_SZ + 2*INST_SZ + 2*REALM_SZ - 3)
+#define                KKEY_SZ         100
+#define                VERSION_SZ      1
+#define                MSG_TYPE_SZ     1
+#define                DATE_SZ         26      /* RTI date output */
+
+#define MAX_HSTNM 100 /* for compatibility */
+
+typedef struct krb_principal{
+    char name[ANAME_SZ];
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+}krb_principal;
+
+#ifndef DEFAULT_TKT_LIFE       /* allow compile-time override */
+/* default lifetime for krb_mk_req & co., 10 hrs */
+#define        DEFAULT_TKT_LIFE 141
+#endif
+
+#define                KRB_TICKET_GRANTING_TICKET      "krbtgt"
+
+/* Definition of text structure used to pass text around */
+#define                MAX_KTXT_LEN    1250
+
+struct ktext {
+    unsigned int length;               /* Length of the text */
+    unsigned char dat[MAX_KTXT_LEN];   /* The data itself */
+    u_int32_t mbz;             /* zero to catch runaway strings */
+};
+
+typedef struct ktext *KTEXT;
+typedef struct ktext KTEXT_ST;
+
+
+/* Definitions for send_to_kdc */
+#define        CLIENT_KRB_TIMEOUT      4       /* time between retries */
+#define CLIENT_KRB_RETRY       5       /* retry this many times */
+#define        CLIENT_KRB_BUFLEN       512     /* max unfragmented packet */
+
+/* Definitions for ticket file utilities */
+#define        R_TKT_FIL       0
+#define        W_TKT_FIL       1
+
+/* Parameters for rd_ap_req */
+/* Maximum alloable clock skew in seconds */
+#define        CLOCK_SKEW      5*60
+/* Filename for readservkey */
+#ifndef                KEYFILE
+#define                KEYFILE         "/etc/srvtab"
+#endif
+
+/* Structure definition for rd_ap_req */
+
+struct auth_dat {
+    unsigned char k_flags;     /* Flags from ticket */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* His Instance */
+    char    prealm[REALM_SZ];  /* His Realm */
+    u_int32_t checksum;                /* Data checksum (opt) */
+    des_cblock session;                /* Session Key */
+    int     life;              /* Life of ticket */
+    u_int32_t time_sec;                /* Time ticket issued */
+    u_int32_t address;         /* Address in ticket */
+    KTEXT_ST reply;            /* Auth reply (opt) */
+};
+
+typedef struct auth_dat AUTH_DAT;
+
+/* Structure definition for credentials returned by get_cred */
+
+struct credentials {
+    char    service[ANAME_SZ]; /* Service name */
+    char    instance[INST_SZ]; /* Instance */
+    char    realm[REALM_SZ];   /* Auth domain */
+    des_cblock session;                /* Session key */
+    int     lifetime;          /* Lifetime */
+    int     kvno;              /* Key version number */
+    KTEXT_ST ticket_st;                /* The ticket itself */
+    int32_t    issue_date;     /* The issue time */
+    char    pname[ANAME_SZ];   /* Principal's name */
+    char    pinst[INST_SZ];    /* Principal's instance */
+};
+
+typedef struct credentials CREDENTIALS;
+
+/* Structure definition for rd_private_msg and rd_safe_msg */
+
+struct msg_dat {
+    unsigned char *app_data;   /* pointer to appl data */
+    u_int32_t app_length;      /* length of appl data */
+    u_int32_t hash;            /* hash to lookup replay */
+    int     swap;              /* swap bytes? */
+    int32_t    time_sec;               /* msg timestamp seconds */
+    unsigned char time_5ms;    /* msg timestamp 5ms units */
+};
+
+typedef struct msg_dat MSG_DAT;
+
+struct krb_host {
+    char *realm;
+    char *host;
+    enum krb_host_proto { PROTO_UDP, PROTO_TCP, PROTO_HTTP } proto;
+    int port;
+    int admin;
+};
+
+/* Location of ticket file for save_cred and get_cred */
+#define TKT_FILE        tkt_string()
+#define TKT_ROOT        "/tmp/tkt"
+
+/* Error codes returned from the KDC */
+#define                KDC_OK          0       /* Request OK */
+#define                KDC_NAME_EXP    1       /* Principal expired */
+#define                KDC_SERVICE_EXP 2       /* Service expired */
+#define                KDC_AUTH_EXP    3       /* Auth expired */
+#define                KDC_PKT_VER     4       /* Protocol version unknown */
+#define                KDC_P_MKEY_VER  5       /* Wrong master key version */
+#define                KDC_S_MKEY_VER  6       /* Wrong master key version */
+#define                KDC_BYTE_ORDER  7       /* Byte order unknown */
+#define                KDC_PR_UNKNOWN  8       /* Principal unknown */
+#define                KDC_PR_N_UNIQUE 9       /* Principal not unique */
+#define                KDC_NULL_KEY   10       /* Principal has null key */
+#define                KDC_GEN_ERR    20       /* Generic error from KDC */
+
+
+/* Values returned by get_credentials */
+#define                GC_OK           0       /* Retrieve OK */
+#define                RET_OK          0       /* Retrieve OK */
+#define                GC_TKFIL       21       /* Can't read ticket file */
+#define                RET_TKFIL      21       /* Can't read ticket file */
+#define                GC_NOTKT       22       /* Can't find ticket or TGT */
+#define                RET_NOTKT      22       /* Can't find ticket or TGT */
+
+
+/* Values returned by mk_ap_req         */
+#define                MK_AP_OK        0       /* Success */
+#define                MK_AP_TGTEXP   26       /* TGT Expired */
+
+/* Values returned by rd_ap_req */
+#define                RD_AP_OK        0       /* Request authentic */
+#define                RD_AP_UNDEC    31       /* Can't decode authenticator */
+#define                RD_AP_EXP      32       /* Ticket expired */
+#define                RD_AP_NYV      33       /* Ticket not yet valid */
+#define                RD_AP_REPEAT   34       /* Repeated request */
+#define                RD_AP_NOT_US   35       /* The ticket isn't for us */
+#define                RD_AP_INCON    36       /* Request is inconsistent */
+#define                RD_AP_TIME     37       /* delta_t too big */
+#define                RD_AP_BADD     38       /* Incorrect net address */
+#define                RD_AP_VERSION  39       /* protocol version mismatch */
+#define                RD_AP_MSG_TYPE 40       /* invalid msg type */
+#define                RD_AP_MODIFIED 41       /* message stream modified */
+#define                RD_AP_ORDER    42       /* message out of order */
+#define                RD_AP_UNAUTHOR 43       /* unauthorized request */
+
+/* Values returned by get_pw_tkt */
+#define                GT_PW_OK        0       /* Got password changing tkt */
+#define                GT_PW_NULL     51       /* Current PW is null */
+#define                GT_PW_BADPW    52       /* Incorrect current password */
+#define                GT_PW_PROT     53       /* Protocol Error */
+#define                GT_PW_KDCERR   54       /* Error returned by KDC */
+#define                GT_PW_NULLTKT  55       /* Null tkt returned by KDC */
+
+
+/* Values returned by send_to_kdc */
+#define                SKDC_OK         0       /* Response received */
+#define                SKDC_RETRY     56       /* Retry count exceeded */
+#define                SKDC_CANT      57       /* Can't send request */
+
+/*
+ * Values returned by get_intkt
+ * (can also return SKDC_* and KDC errors)
+ */
+
+#define                INTK_OK         0       /* Ticket obtained */
+#define                INTK_W_NOTALL  61       /* Not ALL tickets returned */
+#define                INTK_BADPW     62       /* Incorrect password */
+#define                INTK_PROT      63       /* Protocol Error */
+#define                INTK_ERR       70       /* Other error */
+
+/* Values returned by get_adtkt */
+#define         AD_OK           0      /* Ticket Obtained */
+#define         AD_NOTGT       71      /* Don't have tgt */
+#define         AD_INTR_RLM_NOTGT 72   /* Can't get inter-realm tgt */
+
+/* Error codes returned by ticket file utilities */
+#define                NO_TKT_FIL      76      /* No ticket file found */
+#define                TKT_FIL_ACC     77      /* Couldn't access tkt file */
+#define                TKT_FIL_LCK     78      /* Couldn't lock ticket file */
+#define                TKT_FIL_FMT     79      /* Bad ticket file format */
+#define                TKT_FIL_INI     80      /* tf_init not called first */
+
+/* Error code returned by kparse_name */
+#define                KNAME_FMT       81      /* Bad Kerberos name format */
+
+/* Error code returned by krb_mk_safe */
+#define                SAFE_PRIV_ERROR -1      /* syscall error */
+
+/* Defines for krb_sendauth and krb_recvauth */
+
+#define        KOPT_DONT_MK_REQ 0x00000001 /* don't call krb_mk_req */
+#define        KOPT_DO_MUTUAL   0x00000002 /* do mutual auth */
+
+#define        KOPT_DONT_CANON  0x00000004 /*
+                                    * don't canonicalize inst as
+                                    * a hostname
+                                    */
+
+#define KOPT_IGNORE_PROTOCOL 0x0008
+
+#define        KRB_SENDAUTH_VLEN 8         /* length for version strings */
+
+
+extern char *krb4_version;
+
+typedef int (*key_proc_t) __P((char*, char*, char*, void*, des_cblock*));
+
+typedef int (*decrypt_proc_t) __P((char*, char*, char*, void*, 
+                             key_proc_t, KTEXT*));
+
+#include "krb-protos.h"
+
+__END_DECLS
+
+#endif /* __KRB_H__ */
diff --git a/mac/krb4_sources/lsb_addr_comp.c b/mac/krb4_sources/lsb_addr_comp.c
new file mode 100755 (executable)
index 0000000..785ab87
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: lsb_addr_comp.c,v 1.2 2001/12/04 02:06:08 rjs3 Exp $");
+
+#include "krb-archaeology.h"
+
+int
+krb_lsb_antinet_ulong_cmp(u_int32_t x, u_int32_t y)
+{
+    int i;
+    u_int32_t a = 0, b = 0;
+    u_int8_t *p = (u_int8_t*) &x;
+    u_int8_t *q = (u_int8_t*) &y;
+
+    for(i = sizeof(u_int32_t) - 1; i >= 0; i--){
+       a = (a << 8) | p[i];
+       b = (b << 8) | q[i];
+    }
+    if(a > b)
+       return 1;
+    if(a < b)
+       return -1;
+    return 0;
+}
+
+int
+krb_lsb_antinet_ushort_cmp(u_int16_t x, u_int16_t y)
+{
+    int i;
+    u_int16_t a = 0, b = 0;
+    u_int8_t *p = (u_int8_t*) &x;
+    u_int8_t *q = (u_int8_t*) &y;
+
+    for(i = sizeof(u_int16_t) - 1; i >= 0; i--){
+       a = (a << 8) | p[i];
+       b = (b << 8) | q[i];
+    }
+    if(a > b)
+       return 1;
+    if(a < b)
+       return -1;
+    return 0;
+}
+
+u_int32_t
+lsb_time(time_t t, struct sockaddr_in *src, struct sockaddr_in *dst)
+{
+    int dir = 1;
+    const char *fw;
+
+    /*
+     * direction bit is the sign bit of the timestamp.  Ok until
+     * 2038??
+     */
+    if(krb_debug) {
+       krb_warning("lsb_time: src = %s:%u\n", 
+                   inet_ntoa(src->sin_addr.s_addr), ntohs(src->sin_port));
+       krb_warning("lsb_time: dst = %s:%u\n", 
+                   inet_ntoa(dst->sin_addr.s_addr), ntohs(dst->sin_port));
+    }
+
+    /* For compatibility with broken old code, compares are done in VAX 
+       byte order (LSBFIRST) */ 
+    if (krb_lsb_antinet_ulong_less(src->sin_addr.s_addr, /* src < recv */ 
+                                  dst->sin_addr.s_addr) < 0) 
+        dir = -1;
+    else if (krb_lsb_antinet_ulong_less(src->sin_addr.s_addr, 
+                                       dst->sin_addr.s_addr)==0) 
+        if (krb_lsb_antinet_ushort_less(src->sin_port, dst->sin_port) < 0)
+            dir = -1;
+    /*
+     * all that for one tiny bit!  Heaven help those that talk to
+     * themselves.
+     */
+    if(krb_get_config_bool("reverse_lsb_test")) {
+       if(krb_debug) 
+           krb_warning("lsb_time: reversing direction: %d -> %d\n", dir, -dir);
+       dir = -dir;
+    }   
+ #ifdef RUBBISH   
+    else if((fw = krb_get_config_string("firewall_address"))) {
+       struct in_addr fw_addr;
+       fw_addr.sin_addr.s_addr = inet_addr(fw);
+       if(fw_addr.s_addr != INADDR_NONE) {
+           int s_lt_d, d_lt_f;
+           krb_warning("lsb_time: fw = %s\n", inet_ntoa(fw_addr));
+           /* negate if src < dst < fw || fw < dst < src */
+           s_lt_d = (krb_lsb_antinet_ulong_less(src->sin_addr.s_addr,
+                                                dst->sin_addr.s_addr) == -1);
+           d_lt_f = (krb_lsb_antinet_ulong_less(fw_addr.s_addr,
+                                                dst->sin_addr.s_addr) == 1);
+           if((s_lt_d ^ d_lt_f) == 0) {
+               if(krb_debug) 
+                   krb_warning("lsb_time: reversing direction: %d -> %d\n", 
+                               dir, -dir);
+               dir = -dir;
+           }
+       }
+    }
+#endif
+    t = t * dir;
+    t = t & 0xffffffff;
+    return t;
+}
diff --git a/mac/krb4_sources/mk_auth.c b/mac/krb4_sources/mk_auth.c
new file mode 100755 (executable)
index 0000000..43d3b31
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "krb_locl.h"
+
+RCSID("$Id: mk_auth.c,v 1.2 2001/12/04 02:06:08 rjs3 Exp $");
+
+/*
+ * Generate an authenticator for service.instance@realm.
+ * instance is canonicalized by `krb_get_phost'
+ * realm is set to the local realm if realm == NULL
+ * The ticket acquired by `krb_mk_req' is returned in `ticket' and the
+ * authenticator in `buf'.  
+ * Options control the behaviour (see krb_sendauth).
+ */
+
+int
+krb_mk_auth(int32_t options,
+           KTEXT ticket,
+           char *service,
+           char *instance,
+           char *realm,
+           u_int32_t checksum,
+           char *version,
+           KTEXT buf)
+{
+  char realinst[INST_SZ];
+  char realrealm[REALM_SZ];
+  int ret;
+  char *tmp;
+
+  if (options & KOPT_DONT_CANON)
+    tmp = instance;
+  else
+    tmp = krb_get_phost (instance);
+
+  strlcpy(realinst, tmp, sizeof(realinst));
+
+  if (realm == NULL) {
+    ret = krb_get_lrealm (realrealm, 1);
+    if (ret != KSUCCESS)
+      return ret;
+    realm = realrealm;
+  }
+  
+  if(!(options & KOPT_DONT_MK_REQ)) {
+    ret = krb_mk_req (ticket, service, realinst, realm, checksum);
+    if (ret != KSUCCESS)
+      return ret;
+  }
+    
+  {
+      int tmp;
+      size_t rem = sizeof(buf->dat);
+      unsigned char *p = buf->dat;
+
+      p = buf->dat;
+
+      if (rem < 2 * KRB_SENDAUTH_VLEN)
+         return KFAILURE;
+      memcpy (p, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN);
+      p += KRB_SENDAUTH_VLEN;
+      rem -= KRB_SENDAUTH_VLEN;
+
+      memcpy (p, version, KRB_SENDAUTH_VLEN);
+      p += KRB_SENDAUTH_VLEN;
+      rem -= KRB_SENDAUTH_VLEN;
+
+      tmp = krb_put_int(ticket->length, p, rem, 4);
+      if (tmp < 0)
+         return KFAILURE;
+      p += tmp;
+      rem -= tmp;
+
+      if (rem < ticket->length)
+         return KFAILURE;
+      memcpy(p, ticket->dat, ticket->length);
+      p += ticket->length;
+      rem -= ticket->length;
+      buf->length = p - buf->dat;
+  }
+  return KSUCCESS;
+}
diff --git a/mac/krb4_sources/mk_priv.c b/mac/krb4_sources/mk_priv.c
new file mode 100755 (executable)
index 0000000..2c49a4c
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * 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. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: mk_priv.c,v 1.2 2001/12/04 02:06:08 rjs3 Exp $");
+
+/* application include files */
+#include "krb-archaeology.h"
+
+/*
+ * krb_mk_priv() constructs an AUTH_MSG_PRIVATE message.  It takes
+ * some user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address.
+ * The packet is encrypted by pcbc_encrypt(), using the given
+ * "key" and "schedule".
+ * The length of the resulting packet "out" is
+ * returned.
+ *
+ * It is similar to krb_mk_safe() except for the additional key
+ * schedule argument "schedule" and the fact that the data is encrypted
+ * rather than appended with a checksum.  The protocol version is
+ * KRB_PROT_VERSION, defined in "krb.h".
+ *
+ * The "out" packet consists of:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 1 byte              KRB_PROT_VERSION        protocol version number
+ * 1 byte              AUTH_MSG_PRIVATE |      message type plus local
+ *                     HOST_BYTE_ORDER         byte order in low bit
+ *
+ * 4 bytes             c_length                length of data
+ * we encrypt from here with pcbc_encrypt
+ * 
+ * 4 bytes             length                  length of user data
+ * length              in                      user data
+ * 1 byte              msg_time_5ms            timestamp milliseconds
+ * 4 bytes             sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes             msg_time_sec or         timestamp seconds with
+ *                     -msg_time_sec           direction in sign bit
+ *
+ * 0<=n<=7  bytes      pad to 8 byte multiple  zeroes
+ */
+
+int32_t
+krb_mk_priv(void *in, void *out, u_int32_t length, 
+           struct des_ks_struct *schedule, des_cblock *key, 
+           struct sockaddr_in *sender, struct sockaddr_in *receiver)
+{
+    unsigned char *p = (unsigned char*)out;
+    unsigned char *cipher;
+
+    struct timeval tv;
+    u_int32_t src_addr;
+    u_int32_t len;
+
+    p += krb_put_int(KRB_PROT_VERSION, p, 1, 1);
+    p += krb_put_int(AUTH_MSG_PRIVATE, p, 1, 1);
+
+    len = 4 + length + 1 + 4 + 4;
+    len = (len + 7) & ~7;
+    p += krb_put_int(len, p, 4, 4);
+    
+    cipher = p;
+
+    p += krb_put_int(length, p, 4, 4);
+    
+    memcpy(p, in, length);
+    p += length;
+    
+    krb_kdctimeofday(&tv);
+
+    *p++ =tv.tv_usec / 5000;
+    
+    src_addr = sender->sin_addr.s_addr;
+    p += krb_put_address(src_addr, p, 4);
+
+    p += krb_put_int(lsb_time(tv.tv_sec, sender, receiver), p, 4, 4);
+    
+    memset(p, 0, 7);
+
+    des_pcbc_encrypt((des_cblock *)cipher, (des_cblock *)cipher,
+                    len, schedule, key, DES_ENCRYPT);
+
+    return  (cipher - (unsigned char*)out) + len;
+}
diff --git a/mac/krb4_sources/mk_req.c b/mac/krb4_sources/mk_req.c
new file mode 100755 (executable)
index 0000000..18f104c
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: mk_req.c,v 1.2 2001/12/04 02:06:08 rjs3 Exp $");
+
+static int lifetime = 255;     /* But no longer than TGT says. */
+
+
+static int
+build_request(KTEXT req, char *name, char *inst, char *realm, 
+             u_int32_t checksum)
+{
+    struct timeval tv;
+    unsigned char *p = req->dat;
+    int tmp;
+    size_t rem = sizeof(req->dat);
+
+    tmp = krb_put_nir(name, inst, realm, p, rem);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    tmp = krb_put_int(checksum, p, rem, 4);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    /* Fill in the times on the request id */
+    krb_kdctimeofday(&tv);
+
+    if (rem < 1)
+       return KFAILURE;
+
+    *p++ = tv.tv_usec / 5000; /* 5ms */
+    --rem;
+    
+    tmp = krb_put_int(tv.tv_sec, p, rem, 4);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    /* Fill to a multiple of 8 bytes for DES */
+    req->length = ((p - req->dat + 7)/8) * 8;
+    return 0;
+}
+
+
+/*
+ * krb_mk_req takes a text structure in which an authenticator is to
+ * be built, the name of a service, an instance, a realm,
+ * and a checksum.  It then retrieves a ticket for
+ * the desired service and creates an authenticator in the text
+ * structure passed as the first argument.  krb_mk_req returns
+ * KSUCCESS on success and a Kerberos error code on failure.
+ *
+ * The peer procedure on the other end is krb_rd_req.  When making
+ * any changes to this routine it is important to make corresponding
+ * changes to krb_rd_req.
+ *
+ * The authenticator consists of the following:
+ *
+ * authent->dat
+ *
+ * unsigned char       KRB_PROT_VERSION        protocol version no.
+ * unsigned char       AUTH_MSG_APPL_REQUEST   message type
+ * (least significant
+ * bit of above)       HOST_BYTE_ORDER         local byte ordering
+ * unsigned char       kvno from ticket        server's key version
+ * string              realm                   server's realm
+ * unsigned char       tl                      ticket length
+ * unsigned char       idl                     request id length
+ * text                        ticket->dat             ticket for server
+ * text                        req_id->dat             request id
+ *
+ * The ticket information is retrieved from the ticket cache or
+ * fetched from Kerberos.  The request id (called the "authenticator"
+ * in the papers on Kerberos) contains the following:
+ *
+ * req_id->dat
+ *
+ * string              cr.pname                {name, instance, and
+ * string              cr.pinst                realm of principal
+ * string              myrealm                 making this request}
+ * 4 bytes             checksum                checksum argument given
+ * unsigned char       tv_local.tf_usec        time (milliseconds)
+ * 4 bytes             tv_local.tv_sec         time (seconds)
+ *
+ * req_id->length = 3 strings + 3 terminating nulls + 5 bytes for time,
+ *                  all rounded up to multiple of 8.
+ */
+
+int
+krb_mk_req(KTEXT authent, char *service, char *instance, char *realm, 
+          int32_t checksum)
+{
+    KTEXT_ST req_st;
+    KTEXT req_id = &req_st;
+
+    CREDENTIALS cr;             /* Credentials used by retr */
+    KTEXT ticket = &(cr.ticket_st); /* Pointer to tkt_st */
+    int retval;                 /* Returned by krb_get_cred */
+
+    char myrealm[REALM_SZ];
+
+    unsigned char *p = authent->dat;
+    int rem = sizeof(authent->dat);
+    int tmp;
+
+    tmp = krb_put_int(KRB_PROT_VERSION, p, rem, 1);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    tmp = krb_put_int(AUTH_MSG_APPL_REQUEST, p, rem, 1);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    /* Get the ticket and move it into the authenticator */
+    if (krb_ap_req_debug)
+        krb_warning("Realm: %s\n", realm);
+
+    retval = krb_get_cred(service,instance,realm,&cr);
+
+    if (retval == RET_NOTKT) {
+       retval = get_ad_tkt(service, instance, realm, lifetime);
+       if (retval == KSUCCESS)
+           retval = krb_get_cred(service, instance, realm, &cr);
+    }
+
+    if (retval != KSUCCESS)
+       return retval;
+
+
+    /*
+     * With multi realm ticket files either find a matching TGT or
+     * else use the first TGT for inter-realm authentication.
+     *
+     * In myrealm hold the realm of the principal "owning" the
+     * corresponding ticket-granting-ticket.
+     */
+
+    retval = krb_get_cred(KRB_TICKET_GRANTING_TICKET, realm, realm, 0);
+    if (retval == KSUCCESS) {
+      strcpy_truncate(myrealm, realm, REALM_SZ);
+    } else
+      retval = krb_get_tf_realm(TKT_FILE, myrealm);
+    
+    if (retval != KSUCCESS)
+       return retval;
+    
+    if (krb_ap_req_debug)
+        krb_warning("serv=%s.%s@%s princ=%s.%s@%s\n", service, instance, realm,
+                   cr.pname, cr.pinst, myrealm);
+
+    tmp = krb_put_int(cr.kvno, p, rem, 1);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    tmp = krb_put_string(realm, p, rem);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    tmp = krb_put_int(ticket->length, p, rem, 1);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    retval = build_request(req_id, cr.pname, cr.pinst, myrealm, checksum);
+    if (retval != KSUCCESS)
+       return retval;
+    
+    encrypt_ktext(req_id, &cr.session, DES_ENCRYPT);
+
+    tmp = krb_put_int(req_id->length, p, rem, 1);
+    if (tmp < 0)
+       return KFAILURE;
+    p += tmp;
+    rem -= tmp;
+
+    if (rem < ticket->length + req_id->length)
+       return KFAILURE;
+
+    memcpy(p, ticket->dat, ticket->length);
+    p += ticket->length;
+    rem -= ticket->length;
+    memcpy(p, req_id->dat, req_id->length);
+    p += req_id->length;
+    rem -= req_id->length;
+
+    authent->length = p - authent->dat;
+    
+    memset(&cr, 0, sizeof(cr));
+    memset(&req_st, 0, sizeof(req_st));
+
+    if (krb_ap_req_debug)
+        krb_warning("Authent->length = %d\n", authent->length);
+
+    return KSUCCESS;
+}
+
+/* 
+ * krb_set_lifetime sets the default lifetime for additional tickets
+ * obtained via krb_mk_req().
+ * 
+ * It returns the previous value of the default lifetime.
+ */
+
+int
+krb_set_lifetime(int newval)
+{
+    int olife = lifetime;
+
+    lifetime = newval;
+    return(olife);
+}
diff --git a/mac/krb4_sources/mk_safe.c b/mac/krb4_sources/mk_safe.c
new file mode 100755 (executable)
index 0000000..a22f3f2
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: mk_safe.c,v 1.2 2001/12/04 02:06:08 rjs3 Exp $");
+
+/* application include files */
+#include "krb-archaeology.h"
+
+
+/* from rd_safe.c */
+extern int dqc_type;
+void fixup_quad_cksum(void*, size_t, des_cblock*, void*, void*, int);
+
+/*
+ * krb_mk_safe() constructs an AUTH_MSG_SAFE message.  It takes some
+ * user data "in" of "length" bytes and creates a packet in "out"
+ * consisting of the user data, a timestamp, and the sender's network
+ * address, followed by a checksum computed on the above, using the
+ * given "key".  The length of the resulting packet is returned.
+ *
+ * The "out" packet consists of:
+ *
+ * Size                        Variable                Field
+ * ----                        --------                -----
+ *
+ * 1 byte              KRB_PROT_VERSION        protocol version number
+ * 1 byte              AUTH_MSG_SAFE |         message type plus local
+ *                     HOST_BYTE_ORDER         byte order in low bit
+ *
+ * ===================== begin checksum ================================
+ * 
+ * 4 bytes             length                  length of user data
+ * length              in                      user data
+ * 1 byte              msg_time_5ms            timestamp milliseconds
+ * 4 bytes             sender->sin.addr.s_addr sender's IP address
+ *
+ * 4 bytes             msg_time_sec or         timestamp seconds with
+ *                     -msg_time_sec           direction in sign bit
+ *
+ * ======================= end checksum ================================
+ *
+ * 16 bytes            big_cksum               quadratic checksum of
+ *                                             above using "key"
+ */
+
+int32_t
+krb_mk_safe(void *in, void *out, u_int32_t length, des_cblock *key, 
+           struct sockaddr_in *sender, struct sockaddr_in *receiver)
+{
+    unsigned char * p = (unsigned char*)out;
+    struct timeval tv;
+    unsigned char *start;
+    u_int32_t src_addr;
+
+    p += krb_put_int(KRB_PROT_VERSION, p, 1, 1);
+    p += krb_put_int(AUTH_MSG_SAFE, p, 1, 1);
+    
+    start = p;
+
+    p += krb_put_int(length, p, 4, 4);
+
+    memcpy(p, in, length);
+    p += length;
+    
+    krb_kdctimeofday(&tv);
+
+    *p++ = tv.tv_usec/5000; /* 5ms */
+    
+    src_addr = sender->sin_addr.s_addr;
+    p += krb_put_address(src_addr, p, 4);
+
+    p += krb_put_int(lsb_time(tv.tv_sec, sender, receiver), p, 4, 4);
+
+    {
+       /* We are faking big endian mode, so we need to fix the
+        * checksum (that is byte order dependent). We always send a
+        * checksum of the new type, unless we know that we are
+        * talking to an old client (this requires a call to
+        * krb_rd_safe first).  
+        */
+       unsigned char new_checksum[16];
+       unsigned char old_checksum[16];
+       fixup_quad_cksum(start, p - start, key, new_checksum, old_checksum, 0);
+       
+       if((dqc_type == DES_QUAD_GUESS && DES_QUAD_DEFAULT == DES_QUAD_OLD) || 
+          dqc_type == DES_QUAD_OLD)
+           memcpy(p, old_checksum, 16);
+       else
+           memcpy(p, new_checksum, 16);
+    }
+    p += 16;
+
+    return p - (unsigned char*)out;
+}
diff --git a/mac/krb4_sources/rd_priv.c b/mac/krb4_sources/rd_priv.c
new file mode 100755 (executable)
index 0000000..ce580a9
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: rd_priv.c,v 1.2 2001/12/04 02:06:09 rjs3 Exp $");
+
+/* application include files */
+#include "krb-archaeology.h"
+
+/*
+ * krb_rd_priv() decrypts and checks the integrity of an
+ * AUTH_MSG_PRIVATE message.  Given the message received, "in",
+ * the length of that message, "in_length", the key "schedule"
+ * and "key", and the network addresses of the
+ * "sender" and "receiver" of the message, krb_rd_safe() returns
+ * RD_AP_OK if the message is okay, otherwise some error code.
+ *
+ * The message data retrieved from "in" are returned in the structure
+ * "m_data".  The pointer to the application data
+ * (m_data->app_data) refers back to the appropriate place in "in".
+ *
+ * See the file "mk_priv.c" for the format of the AUTH_MSG_PRIVATE
+ * message.  The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+int32_t
+krb_rd_priv(void *in, u_int32_t in_length, 
+           struct des_ks_struct *schedule, des_cblock *key, 
+           struct sockaddr_in *sender, struct sockaddr_in *receiver, 
+           MSG_DAT *m_data)
+{
+    unsigned char *p = (unsigned char*)in;
+    int little_endian;
+    u_int32_t clen;
+    struct timeval tv;
+    u_int32_t src_addr;
+    int delta_t;
+
+    unsigned char pvno, type;
+
+    pvno = *p++;
+    if(pvno != KRB_PROT_VERSION)
+       return RD_AP_VERSION;
+    
+    type = *p++;
+    little_endian = type & 1;
+    type &= ~1;
+
+    p += krb_get_int(p, &clen, 4, little_endian);
+    
+    if(clen + 2 > in_length)
+       return RD_AP_MODIFIED;
+
+    des_pcbc_encrypt((des_cblock*)p, (des_cblock*)p, clen, 
+                    schedule, key, DES_DECRYPT);
+    
+    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
+    if(m_data->app_length + 17 > in_length)
+       return RD_AP_MODIFIED;
+
+    m_data->app_data = p;
+    p += m_data->app_length;
+    
+    m_data->time_5ms = *p++;
+
+    p += krb_get_address(p, &src_addr);
+
+    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
+       return RD_AP_BADD;
+
+    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);
+
+    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
+    
+    gettimeofday(&tv, NULL);
+
+    /* check the time integrity of the msg */
+    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
+    if (delta_t > CLOCK_SKEW)
+       return RD_AP_TIME;
+    if (krb_debug)
+       krb_warning("delta_t = %d\n", (int) delta_t);
+
+    /*
+     * caller must check timestamps for proper order and
+     * replays, since server might have multiple clients
+     * each with its own timestamps and we don't assume
+     * tightly synchronized clocks.
+     */
+
+    return KSUCCESS;
+}
diff --git a/mac/krb4_sources/rd_safe.c b/mac/krb4_sources/rd_safe.c
new file mode 100755 (executable)
index 0000000..cacf44e
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: rd_safe.c,v 1.2 2001/12/04 02:06:09 rjs3 Exp $");
+
+/* application include files */
+#include "krb-archaeology.h"
+
+/* Generate two checksums in the given byteorder of the data, one
+ * new-form and one old-form. It has to be done this way to be
+ * compatible with the old version of des_quad_cksum.
+ */
+
+/* des_quad_chsum-type; 0 == unknown, 1 == new PL10++, 2 == old */
+int dqc_type = DES_QUAD_DEFAULT;
+
+void
+fixup_quad_cksum(void *start, size_t len, des_cblock *key, 
+                void *new_checksum, void *old_checksum, int little)
+{
+    des_quad_cksum((des_cblock*)start, (des_cblock*)new_checksum, len, 2, key);
+    if(HOST_BYTE_ORDER){
+       if(little){
+           memcpy(old_checksum, new_checksum, 16);
+       }else{
+           u_int32_t *tmp = (u_int32_t*)new_checksum;
+           memcpy(old_checksum, new_checksum, 16);
+           swap_u_16(old_checksum);
+           swap_u_long(tmp[0]);
+           swap_u_long(tmp[1]);
+           swap_u_long(tmp[2]);
+           swap_u_long(tmp[3]);
+       }
+    }else{
+       if(little){
+           u_int32_t *tmp = (u_int32_t*)new_checksum;
+           swap_u_long(tmp[0]);
+           swap_u_long(tmp[1]);
+           swap_u_long(tmp[2]);
+           swap_u_long(tmp[3]);
+           memcpy(old_checksum, new_checksum, 16);
+       }else{
+           u_int32_t tmp[4];
+           tmp[0] = ((u_int32_t*)new_checksum)[3];
+           tmp[1] = ((u_int32_t*)new_checksum)[2];
+           tmp[2] = ((u_int32_t*)new_checksum)[1];
+           tmp[3] = ((u_int32_t*)new_checksum)[0];
+           memcpy(old_checksum, tmp, 16);
+       }
+    }
+}
+
+/*
+ * krb_rd_safe() checks the integrity of an AUTH_MSG_SAFE message.
+ * Given the message received, "in", the length of that message,
+ * "in_length", the "key" to compute the checksum with, and the
+ * network addresses of the "sender" and "receiver" of the message,
+ * krb_rd_safe() returns RD_AP_OK if message is okay, otherwise
+ * some error code.
+ *
+ * The message data retrieved from "in" is returned in the structure
+ * "m_data".  The pointer to the application data (m_data->app_data)
+ * refers back to the appropriate place in "in".
+ *
+ * See the file "mk_safe.c" for the format of the AUTH_MSG_SAFE
+ * message.  The structure containing the extracted message
+ * information, MSG_DAT, is defined in "krb.h".
+ */
+
+int32_t
+krb_rd_safe(void *in, u_int32_t in_length, des_cblock *key, 
+           struct sockaddr_in *sender, struct sockaddr_in *receiver, 
+           MSG_DAT *m_data)
+{
+    unsigned char *p = (unsigned char*)in, *start;
+
+    unsigned char pvno, type;
+    int little_endian;
+    struct timeval tv;
+    u_int32_t src_addr;
+    int delta_t;
+    
+
+    pvno = *p++;
+    if(pvno != KRB_PROT_VERSION)
+       return RD_AP_VERSION;
+    
+    type = *p++;
+    little_endian = type & 1;
+    type &= ~1;
+    if(type != AUTH_MSG_SAFE)
+       return RD_AP_MSG_TYPE;
+
+    start = p;
+    
+    p += krb_get_int(p, &m_data->app_length, 4, little_endian);
+    
+    if(m_data->app_length + 31 > in_length)
+       return RD_AP_MODIFIED;
+    
+    m_data->app_data = p;
+
+    p += m_data->app_length;
+
+    m_data->time_5ms = *p++;
+
+    p += krb_get_address(p, &src_addr);
+
+    if (!krb_equiv(src_addr, sender->sin_addr.s_addr))
+        return RD_AP_BADD;
+
+    p += krb_get_int(p, (u_int32_t *)&m_data->time_sec, 4, little_endian);
+    m_data->time_sec = lsb_time(m_data->time_sec, sender, receiver);
+    
+    gettimeofday(&tv, NULL);
+
+    delta_t = abs((int)((long) tv.tv_sec - m_data->time_sec));
+    if (delta_t > CLOCK_SKEW) return RD_AP_TIME;
+
+    /*
+     * caller must check timestamps for proper order and replays, since
+     * server might have multiple clients each with its own timestamps
+     * and we don't assume tightly synchronized clocks.
+     */
+
+    {
+       unsigned char new_checksum[16];
+       unsigned char old_checksum[16];
+       fixup_quad_cksum(start, p - start, key, 
+                        new_checksum, old_checksum, little_endian);
+       if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_NEW) && 
+          memcmp(new_checksum, p, 16) == 0)
+           dqc_type = DES_QUAD_NEW;
+       else if((dqc_type == DES_QUAD_GUESS || dqc_type == DES_QUAD_OLD) && 
+               memcmp(old_checksum, p, 16) == 0)
+           dqc_type = DES_QUAD_OLD;
+       else
+           return RD_AP_MODIFIED;
+    }
+    return KSUCCESS;
+}
diff --git a/mac/krb4_sources/rw.c b/mac/krb4_sources/rw.c
new file mode 100755 (executable)
index 0000000..a276fcb
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the Kungliga Tekniska
+ *      H\9agskolan and its contributors.
+ * 
+ * 4. Neither the name of the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Almost all programs use these routines (implicitly) so it's a good
+ * place to put the version string. */
+
+#ifdef RUBBISH
+#include "version.h"
+#endif
+
+#include "sasl_mac_krb_locl.h"
+
+RCSID("$Id: rw.c,v 1.2 2001/12/04 02:06:09 rjs3 Exp $");
+
+int
+krb_get_int(void *f, u_int32_t *to, int size, int lsb)
+{
+    int i;
+    unsigned char *from = (unsigned char *)f;
+
+    *to = 0;
+    if(lsb){
+       for(i = size-1; i >= 0; i--)
+           *to = (*to << 8) | from[i];
+    }else{
+       for(i = 0; i < size; i++)
+           *to = (*to << 8) | from[i];
+    }
+    return size;
+}
+
+int
+krb_put_int(u_int32_t from, void *to, size_t rem, int size)
+{
+    int i;
+    unsigned char *p = (unsigned char *)to;
+
+    if (rem < size)
+       return -1;
+
+    for(i = size - 1; i >= 0; i--){
+       p[i] = from & 0xff;
+       from >>= 8;
+    }
+    return size;
+}
+
+
+/* addresses are always sent in network byte order */
+
+int
+krb_get_address(void *from, u_int32_t *to)
+{
+    unsigned char *p = (unsigned char*)from;
+    *to = htonl((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+    return 4;
+}
+
+int
+krb_put_address(u_int32_t addr, void *to, size_t rem)
+{
+    return krb_put_int(ntohl(addr), to, rem, 4);
+}
+
+int
+krb_put_string(const char *from, void *to, size_t rem)
+{
+    size_t len = strlen(from) + 1;
+
+    if (rem < len)
+       return -1;
+    memcpy(to, from, len);
+    return len;
+}
+
+int
+krb_get_string(void *from, char *to, size_t to_size)
+{
+    strcpy_truncate (to, (char *)from, to_size);
+    return strlen((char *)from) + 1;
+}
+
+int
+krb_get_nir(void *from, char *name, char *instance, char *realm)
+{
+    char *p = (char *)from;
+
+    p += krb_get_string(p, name, ANAME_SZ);
+    p += krb_get_string(p, instance, INST_SZ);
+    if(realm)
+       p += krb_get_string(p, realm, REALM_SZ);
+    return p - (char *)from;
+}
+
+int
+krb_put_nir(const char *name,const char *instance,const char *realm, void *to, size_t rem)
+{
+    char *p = (char *)to;
+    int tmp;
+    
+    tmp = krb_put_string(name, p, rem);
+    if (tmp < 0)
+       return tmp;
+    p += tmp;
+    rem -= tmp;
+
+    tmp = krb_put_string(instance, p, rem);
+    if (tmp < 0)
+       return tmp;
+    p += tmp;
+    rem -= tmp;
+    
+    if (realm) {
+       tmp = krb_put_string(realm, p, rem);
+       if (tmp < 0)
+           return tmp;
+       p += tmp;
+       rem -= tmp;
+    }
+    return p - (char *)to;
+}
diff --git a/mac/libdes/libdes_68K/libdes_68K b/mac/libdes/libdes_68K/libdes_68K
new file mode 100755 (executable)
index 0000000..e88ea87
Binary files /dev/null and b/mac/libdes/libdes_68K/libdes_68K differ
diff --git a/mac/libdes/libdes_68K/libdes_68K.exp b/mac/libdes/libdes_68K/libdes_68K.exp
new file mode 100755 (executable)
index 0000000..c9a2488
--- /dev/null
@@ -0,0 +1,29 @@
+des_key_sched
+des_set_key
+des_is_weak_key
+des_set_odd_parity
+des_quad_cksum
+des_pcbc_encrypt
+des_fcrypt
+crypt
+des_decrypt3
+des_encrypt3
+des_encrypt2
+des_encrypt
+des_fixup_key_parity
+des_xcbc_encrypt
+des_xwhite_in2out
+des_ofb_encrypt
+des_ofb64_encrypt
+des_ede3_ofb64_encrypt
+des_ncbc_encrypt
+des_ede3_cbc_encrypt
+des_ecb_encrypt
+des_options
+des_ecb3_encrypt
+des_cfb_encrypt
+des_cfb64_encrypt
+des_ede3_cfb64_encrypt
+des_cbc_encrypt
+des_cbc_cksum
+des_3cbc_encrypt
diff --git a/mac/libdes/libdes_fat/libdes_fat b/mac/libdes/libdes_fat/libdes_fat
new file mode 100755 (executable)
index 0000000..94c0b17
Binary files /dev/null and b/mac/libdes/libdes_fat/libdes_fat differ
diff --git a/mac/libdes/libdes_ppc/libdes_ppc b/mac/libdes/libdes_ppc/libdes_ppc
new file mode 100755 (executable)
index 0000000..6dec144
Binary files /dev/null and b/mac/libdes/libdes_ppc/libdes_ppc differ
diff --git a/mac/libdes/libdes_ppc/libdes_ppc.Carbon b/mac/libdes/libdes_ppc/libdes_ppc.Carbon
new file mode 100755 (executable)
index 0000000..3fc1f23
Binary files /dev/null and b/mac/libdes/libdes_ppc/libdes_ppc.Carbon differ
diff --git a/mac/libdes/libdes_ppc/libdes_ppc.Carbon.exp b/mac/libdes/libdes_ppc/libdes_ppc.Carbon.exp
new file mode 100755 (executable)
index 0000000..5661298
--- /dev/null
@@ -0,0 +1,33 @@
+des_3cbc_encrypt
+des_cbc_cksum
+des_cbc_encrypt
+des_ede3_cfb64_encrypt
+des_cfb64_encrypt
+des_cfb_encrypt
+des_ecb3_encrypt
+des_SPtrans
+libdes_version
+DES_version
+des_ecb_encrypt
+des_options
+des_ede3_cbc_encrypt
+des_ncbc_encrypt
+des_ede3_ofb64_encrypt
+des_ofb64_encrypt
+des_ofb_encrypt
+des_xcbc_encrypt
+des_xwhite_in2out
+des_fixup_key_parity
+des_decrypt3
+des_encrypt3
+des_encrypt2
+des_encrypt
+des_fcrypt
+crypt
+des_pcbc_encrypt
+des_quad_cksum
+des_check_key
+des_key_sched
+des_set_key
+des_is_weak_key
+des_set_odd_parity
diff --git a/mac/libdes/libdes_ppc/libdes_ppc.exp b/mac/libdes/libdes_ppc/libdes_ppc.exp
new file mode 100755 (executable)
index 0000000..5661298
--- /dev/null
@@ -0,0 +1,33 @@
+des_3cbc_encrypt
+des_cbc_cksum
+des_cbc_encrypt
+des_ede3_cfb64_encrypt
+des_cfb64_encrypt
+des_cfb_encrypt
+des_ecb3_encrypt
+des_SPtrans
+libdes_version
+DES_version
+des_ecb_encrypt
+des_options
+des_ede3_cbc_encrypt
+des_ncbc_encrypt
+des_ede3_ofb64_encrypt
+des_ofb64_encrypt
+des_ofb_encrypt
+des_xcbc_encrypt
+des_xwhite_in2out
+des_fixup_key_parity
+des_decrypt3
+des_encrypt3
+des_encrypt2
+des_encrypt
+des_fcrypt
+crypt
+des_pcbc_encrypt
+des_quad_cksum
+des_check_key
+des_key_sched
+des_set_key
+des_is_weak_key
+des_set_odd_parity
diff --git a/mac/libdes/public/cfm68k_import_off.h b/mac/libdes/public/cfm68k_import_off.h
new file mode 100755 (executable)
index 0000000..221f42c
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * set a macro for des.h from libdes to not turn all the des functions
+ * for cfm68k into pragma imports
+ */
+#define DESLIB_CFM68K_NO_IMPORTS 1
+
+/*
+ * compiler doesnt allow an empty file even for precompiled... go figure
+ */
+typedef int cfm68_des_enable_braindead;
diff --git a/mac/libdes/public/des.h b/mac/libdes/public/des.h
new file mode 100755 (executable)
index 0000000..8259874
--- /dev/null
@@ -0,0 +1,317 @@
+/* crypto/des/des.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@mincom.oz.au).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@mincom.oz.au).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@mincom.oz.au)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#if (defined(__MWERKS__)&&defined(__MC68K__)&&(!defined(DESLIB_CFM68K_NO_IMPORTS)))
+#pragma import on
+#define UNDO_CFM68K_IMPORT
+#endif
+
+#ifndef DES_LIB_FUNCTION
+#if defined(__BORLANDC__)
+#define DES_LIB_FUNCTION /* not-ready-definition-yet */
+#elif defined(_MSC_VER)
+#define DES_LIB_FUNCTION /* not-ready-definition-yet2 */
+#else
+#define DES_LIB_FUNCTION
+#endif
+#endif
+
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#if defined(__alpha)
+#define DES_LONG unsigned int
+#else /* Not a 64 bit machine */
+#define DES_LONG unsigned long
+#endif
+#endif
+
+typedef unsigned char des_cblock[8];
+typedef struct des_ks_struct
+       {
+       union   {
+               des_cblock _;
+               /* make sure things are correct size on machines with
+                * 8 byte longs */
+               DES_LONG pad[2];
+               } ks;
+#undef _
+#define _      ks._
+       } des_key_schedule[16];
+
+#define DES_KEY_SZ     (sizeof(des_cblock))
+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
+
+#define DES_ENCRYPT    1
+#define DES_DECRYPT    0
+
+#define DES_CBC_MODE   0
+#define DES_PCBC_MODE  1
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+       des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+       des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+       des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+       des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define C_Block des_cblock
+#define Key_schedule des_key_schedule
+#ifdef KERBEROS
+#define ENCRYPT DES_ENCRYPT
+#define DECRYPT DES_DECRYPT
+#endif
+#define KEY_SZ DES_KEY_SZ
+#define string_to_key des_string_to_key
+#define read_pw_string des_read_pw_string
+#define random_key des_random_key
+#define pcbc_encrypt des_pcbc_encrypt
+#define set_key des_set_key
+#define key_sched des_key_sched
+#define ecb_encrypt des_ecb_encrypt
+#define cbc_encrypt des_cbc_encrypt
+#define ncbc_encrypt des_ncbc_encrypt
+#define xcbc_encrypt des_xcbc_encrypt
+#define cbc_cksum des_cbc_cksum
+#define quad_cksum des_quad_cksum
+
+/* For compatibility with the MIT lib - eay 20/05/92 */
+typedef des_key_schedule bit_64;
+#define des_fixup_key_parity des_set_odd_parity
+#define des_check_key_parity check_parity
+
+extern int des_check_key;      /* defaults to false */
+extern int des_rw_mode;                /* defaults to DES_PCBC_MODE */
+
+#ifdef cplusplus
+extern "C" {
+#endif
+
+/* The next line is used to disable full ANSI prototypes, if your
+ * compiler has problems with the prototypes, make sure this line always
+ * evaluates to true :-) */
+#if defined(MSDOS) || defined(__STDC__)
+#undef NOPROTO
+#endif
+#ifndef NOPROTO
+char *DES_LIB_FUNCTION des_options(void);
+void DES_LIB_FUNCTION des_ecb3_encrypt(des_cblock *input,des_cblock *output,
+       des_key_schedule ks1,des_key_schedule ks2,
+       des_key_schedule ks3, int enc);
+DES_LONG DES_LIB_FUNCTION des_cbc_cksum(des_cblock *input,des_cblock *output,
+       long length,des_key_schedule schedule,des_cblock *ivec);
+void DES_LIB_FUNCTION des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,
+       des_cblock *inw,des_cblock *outw,int enc);
+void DES_LIB_FUNCTION des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule sk1,des_key_schedule sk2,
+       des_cblock *ivec1,des_cblock *ivec2,int enc);
+void DES_LIB_FUNCTION des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+       long length,des_key_schedule schedule,des_cblock *ivec,int enc);
+void DES_LIB_FUNCTION des_ecb_encrypt(des_cblock *input,des_cblock *output,
+       des_key_schedule ks,int enc);
+void DES_LIB_FUNCTION des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
+void DES_LIB_FUNCTION des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
+void DES_LIB_FUNCTION des_encrypt3(DES_LONG *data, des_key_schedule ks1,
+       des_key_schedule ks2, des_key_schedule ks3);
+void DES_LIB_FUNCTION des_decrypt3(DES_LONG *data, des_key_schedule ks1,
+       des_key_schedule ks2, des_key_schedule ks3);
+void DES_LIB_FUNCTION des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, 
+       long length, des_key_schedule ks1, des_key_schedule ks2, 
+       des_key_schedule ks3, des_cblock *ivec, int enc);
+void DES_LIB_FUNCTION des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+       long length, des_key_schedule ks1, des_key_schedule ks2,
+       des_key_schedule ks3, des_cblock *ivec, int *num, int encrypt);
+void DES_LIB_FUNCTION des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+       long length, des_key_schedule ks1, des_key_schedule ks2,
+       des_key_schedule ks3, des_cblock *ivec, int *num);
+
+int DES_LIB_FUNCTION des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
+       des_cblock *iv);
+int DES_LIB_FUNCTION des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
+       des_cblock *iv);
+char *DES_LIB_FUNCTION des_fcrypt(const char *buf,const char *salt, char *ret);
+#ifdef PERL5
+char *des_crypt(const char *buf,const char *salt);
+#else
+/* some stupid compilers complain because I have declared char instead
+ * of const char */
+#ifdef HEADER_DES_LOCL_H
+char *DES_LIB_FUNCTION crypt(const char *buf,const char *salt);
+#else
+char *crypt();
+#endif
+#endif
+void DES_LIB_FUNCTION des_ofb_encrypt(unsigned char *in,unsigned char *out,
+       int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
+void DES_LIB_FUNCTION des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
+       des_key_schedule schedule,des_cblock *ivec,int enc);
+DES_LONG DES_LIB_FUNCTION des_quad_cksum(des_cblock *input,des_cblock *output,
+       long length,int out_count,des_cblock *seed);
+void DES_LIB_FUNCTION des_random_seed(des_cblock key);
+void DES_LIB_FUNCTION des_random_key(des_cblock ret);
+int DES_LIB_FUNCTION des_read_password(des_cblock *key,char *prompt,int verify);
+int DES_LIB_FUNCTION des_read_2passwords(des_cblock *key1,des_cblock *key2,
+       char *prompt,int verify);
+int DES_LIB_FUNCTION des_read_pw_string(char *buf,int length,char *prompt,int verify);
+void DES_LIB_FUNCTION des_set_odd_parity(des_cblock *key);
+int DES_LIB_FUNCTION des_is_weak_key(des_cblock *key);
+int DES_LIB_FUNCTION des_set_key(des_cblock *key,des_key_schedule schedule);
+int DES_LIB_FUNCTION des_key_sched(des_cblock *key,des_key_schedule schedule);
+void DES_LIB_FUNCTION des_string_to_key(char *str,des_cblock *key);
+void DES_LIB_FUNCTION des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
+void DES_LIB_FUNCTION des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+       des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
+void DES_LIB_FUNCTION des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+       des_key_schedule schedule, des_cblock *ivec, int *num);
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+void DES_LIB_FUNCTION des_cblock_print_file(des_cblock *cb, FILE *fp);
+/* The following functions are not in the normal unix build or the
+ * SSLeay build.  When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+int DES_LIB_FUNCTION des_new_random_key(des_cblock *key);
+void DES_LIB_FUNCTION des_init_random_number_generator(des_cblock *key);
+void DES_LIB_FUNCTION des_set_random_generator_seed(des_cblock *key);
+void DES_LIB_FUNCTION des_set_sequence_number(des_cblock new_sequence_number);
+void DES_LIB_FUNCTION des_generate_random_block(des_cblock *block);
+void DES_LIB_FUNCTION des_rand_data(unsigned char *data, int size);
+
+#else
+
+char *des_options();
+void des_ecb3_encrypt();
+DES_LONG des_cbc_cksum();
+void des_cbc_encrypt();
+void des_ncbc_encrypt();
+void des_xcbc_encrypt();
+void des_3cbc_encrypt();
+void des_cfb_encrypt();
+void des_ede3_cfb64_encrypt();
+void des_ede3_ofb64_encrypt();
+void des_ecb_encrypt();
+void des_encrypt();
+void des_encrypt2();
+void des_encrypt3();
+void des_decrypt3();
+void des_ede3_cbc_encrypt();
+int des_enc_read();
+int des_enc_write();
+char *des_fcrypt();
+#ifdef PERL5
+char *des_crypt();
+#else
+char *crypt();
+#endif
+void des_ofb_encrypt();
+void des_pcbc_encrypt();
+DES_LONG des_quad_cksum();
+void des_random_seed();
+void des_random_key();
+int des_read_password();
+int des_read_2passwords();
+int des_read_pw_string();
+void des_set_odd_parity();
+int des_is_weak_key();
+int des_set_key();
+int des_key_sched();
+void des_string_to_key();
+void des_string_to_2keys();
+void des_cfb64_encrypt();
+void des_ofb64_encrypt();
+
+/* Extra functions from Mark Murray <mark@grondar.za> */
+void des_cblock_print_file();
+/* The following functions are not in the normal unix build or the
+ * SSLeay build.  When using the SSLeay build, use RAND_seed()
+ * and RAND_bytes() instead. */
+int des_new_random_key();
+void des_init_random_number_generator();
+void des_set_random_generator_seed();
+void des_set_sequence_number();
+void des_generate_random_block();
+void des_rand_data();
+
+#endif
+
+#ifdef UNDO_CFM68K_IMPORT
+#pragma import reset
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mac/libdes/public/destest.c b/mac/libdes/public/destest.c
new file mode 100755 (executable)
index 0000000..3537a29
--- /dev/null
@@ -0,0 +1,842 @@
+/* crypto/des/destest.c */
+/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@mincom.oz.au).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@mincom.oz.au).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * 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 copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@mincom.oz.au)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
+#ifndef MSDOS
+#define MSDOS
+#endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_IO_H
+#include <io.h>
+#endif
+
+#include "des.h"
+
+/* tisk tisk - the test keys don't all have odd parity :-( */
+/* test data */
+#define NUM_TESTS 34
+static unsigned char key_data[NUM_TESTS][8]={
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
+       {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
+       {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
+       {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
+       {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
+       {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
+       {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
+       {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
+       {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
+       {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
+       {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
+       {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
+       {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
+       {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
+       {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
+       {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
+       {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
+       {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
+       {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
+       {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
+       {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
+       {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
+       {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
+
+static unsigned char plain_data[NUM_TESTS][8]={
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
+       {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
+       {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
+       {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
+       {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
+       {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
+       {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
+       {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
+       {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
+       {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
+       {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
+       {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
+       {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
+       {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
+       {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
+       {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
+       {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
+       {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
+       {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
+
+static unsigned char cipher_data[NUM_TESTS][8]={
+       {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+       {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
+       {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
+       {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
+       {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
+       {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
+       {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
+       {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
+       {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
+       {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
+       {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
+       {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
+       {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
+       {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
+       {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
+       {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
+       {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
+       {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
+       {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
+       {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
+       {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
+       {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
+       {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
+       {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
+       {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
+       {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
+       {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
+       {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
+       {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
+       {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
+       {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
+       {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
+       {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
+       {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
+
+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
+       {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
+       {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
+       {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
+       {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
+       {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
+       {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
+       {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
+       {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
+       {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
+       {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
+       {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
+       {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
+       {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
+       {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
+       {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
+       {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
+       {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
+       {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
+       {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
+       {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
+       {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
+       {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
+       {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
+       {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
+       {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
+       {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
+       {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
+       {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
+       {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
+       {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
+       {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
+       {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
+       {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
+
+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static unsigned char cbc_iv  [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
+static char cbc_data[40]="7654321 Now is the time for ";
+
+static unsigned char cbc_ok[32]={
+       0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+       0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
+       0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
+       0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+static unsigned char xcbc_ok[32]={
+       0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
+       0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
+       0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
+       0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
+       };
+
+static unsigned char cbc3_ok[32]={
+       0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
+       0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
+       0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
+       0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
+
+static unsigned char pcbc_ok[32]={
+       0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
+       0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
+       0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
+       0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
+
+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
+static unsigned char plain[24]=
+       {
+       0x4e,0x6f,0x77,0x20,0x69,0x73,
+       0x20,0x74,0x68,0x65,0x20,0x74,
+       0x69,0x6d,0x65,0x20,0x66,0x6f,
+       0x72,0x20,0x61,0x6c,0x6c,0x20
+       };
+static unsigned char cfb_cipher8[24]= {
+       0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
+       0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
+static unsigned char cfb_cipher16[24]={
+       0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
+       0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
+static unsigned char cfb_cipher32[24]={
+       0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
+       0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
+static unsigned char cfb_cipher48[24]={
+       0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
+       0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
+static unsigned char cfb_cipher64[24]={
+       0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
+       0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
+
+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
+static unsigned char ofb_cipher[24]=
+       {
+       0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
+       0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
+       0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
+       };
+
+DES_LONG cbc_cksum_ret=0xB462FEF7L;
+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+
+#ifndef NOPROTO
+static char *pt(unsigned char *p);
+static int cfb_test(int bits, unsigned char *cfb_cipher);
+static int cfb64_test(unsigned char *cfb_cipher);
+static int ede_cfb64_test(unsigned char *cfb_cipher);
+#else
+static char *pt();
+static int cfb_test();
+static int cfb64_test();
+static int ede_cfb64_test();
+#endif
+
+int main(argc,argv)
+int argc;
+char *argv[];
+       {
+       int i,j,err=0;
+       des_cblock in,out,outin,iv3;
+       des_key_schedule ks,ks2,ks3;
+       unsigned char cbc_in[40];
+       unsigned char cbc_out[40];
+       DES_LONG cs;
+       unsigned char cret[8];
+       DES_LONG lqret[4];
+       int num;
+       char *str;
+
+       printf("Doing ecb\n");
+       for (i=0; i<NUM_TESTS; i++)
+               {
+               if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+1,j);
+                       err=1;
+                       }
+               memcpy(in,plain_data[i],8);
+               memset(out,0,8);
+               memset(outin,0,8);
+               des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
+               des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
+
+               if (memcmp(out,cipher_data[i],8) != 0)
+                       {
+                       printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
+                               pt(out));
+                       err=1;
+                       }
+               if (memcmp(in,outin,8) != 0)
+                       {
+                       printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+                       err=1;
+                       }
+               }
+
+#ifndef LIBDES_LIT
+       printf("Doing ede ecb\n");
+       for (i=0; i<(NUM_TESTS-1); i++)
+               {
+               if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
+                       {
+                       err=1;
+                       printf("Key error %2d:%d\n",i+1,j);
+                       }
+               if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+2,j);
+                       err=1;
+                       }
+               if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
+                       {
+                       printf("Key error %2d:%d\n",i+3,j);
+                       err=1;
+                       }
+               memcpy(in,plain_data[i],8);
+               memset(out,0,8);
+               memset(outin,0,8);
+               des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
+                       DES_ENCRYPT);
+               des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
+                       DES_DECRYPT);
+
+               if (memcmp(out,cipher_ecb2[i],8) != 0)
+                       {
+                       printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
+                               pt(out));
+                       err=1;
+                       }
+               if (memcmp(in,outin,8) != 0)
+                       {
+                       printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
+                               i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
+                       err=1;
+                       }
+               }
+#endif
+
+       printf("Doing cbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,40);
+       memset(cbc_in,0,40);
+       des_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               (long)strlen((char *)cbc_data)+1,ks,
+               (C_Block *)cbc_iv,DES_ENCRYPT);
+       if (memcmp(cbc_out,cbc_ok,32) != 0)
+               printf("cbc_encrypt encrypt error\n");
+       des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               (long)strlen((char *)cbc_data)+1,ks,
+               (C_Block *)cbc_iv,DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
+               {
+               printf("cbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+#ifndef LIBDES_LIT
+       printf("Doing desx cbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,40);
+       memset(cbc_in,0,40);
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               (long)strlen((char *)cbc_data)+1,ks,
+               (C_Block *)iv3,
+               (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
+       if (memcmp(cbc_out,xcbc_ok,32) != 0)
+               {
+               printf("des_xcbc_encrypt encrypt error\n");
+               }
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               (long)strlen((char *)cbc_data)+1,ks,
+               (C_Block *)iv3,
+               (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,32) != 0)
+               {
+               printf("des_xcbc_encrypt decrypt error\n");
+               err=1;
+               }
+#endif
+
+       printf("Doing ede cbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,40);
+       memset(cbc_in,0,40);
+       i=strlen((char *)cbc_data)+1;
+       i=((i+7)/8)*8;
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+
+       des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
+       des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
+               (C_Block *)&(cbc_out[16]),
+               (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
+       if (memcmp(cbc_out,cbc3_ok,
+               (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
+               {
+               printf("des_ede3_cbc_encrypt encrypt error\n");
+               err=1;
+               }
+
+       memcpy(iv3,cbc_iv,sizeof(cbc_iv));
+       des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
+               {
+               printf("des_ede3_cbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+#ifndef LIBDES_LIT
+       printf("Doing pcbc\n");
+       if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
+               {
+               printf("Key error %d\n",j);
+               err=1;
+               }
+       memset(cbc_out,0,40);
+       memset(cbc_in,0,40);
+       des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
+               (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
+       if (memcmp(cbc_out,pcbc_ok,32) != 0)
+               {
+               printf("pcbc_encrypt encrypt error\n");
+               err=1;
+               }
+       des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
+               (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
+       if (memcmp(cbc_in,cbc_data,32) != 0)
+               {
+               printf("pcbc_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing ");
+       printf("cfb8 ");
+       err+=cfb_test(8,cfb_cipher8);
+       printf("cfb16 ");
+       err+=cfb_test(16,cfb_cipher16);
+       printf("cfb32 ");
+       err+=cfb_test(32,cfb_cipher32);
+       printf("cfb48 ");
+       err+=cfb_test(48,cfb_cipher48);
+       printf("cfb64 ");
+       err+=cfb_test(64,cfb_cipher64);
+
+       printf("cfb64() ");
+       err+=cfb64_test(cfb_cipher64);
+
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       for (i=0; i<sizeof(plain); i++)
+               des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
+                       8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
+       if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
+               {
+               printf("cfb_encrypt small encrypt error\n");
+               err=1;
+               }
+
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       for (i=0; i<sizeof(plain); i++)
+               des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
+                       8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               printf("cfb_encrypt small decrypt error\n");
+               err=1;
+               }
+
+       printf("ede_cfb64() ");
+       err+=ede_cfb64_test(cfb_cipher64);
+
+       printf("done\n");
+
+       printf("Doing ofb\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
+               (C_Block *)ofb_tmp);
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ofb_encrypt encrypt error\n");
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
+               (C_Block *)ofb_tmp);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ofb_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing ofb64\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       memset(ofb_buf1,0,sizeof(ofb_buf1));
+       memset(ofb_buf2,0,sizeof(ofb_buf1));
+       num=0;
+       for (i=0; i<sizeof(plain); i++)
+               {
+               des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
+                       (C_Block *)ofb_tmp,&num);
+               }
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ofb64_encrypt encrypt error\n");
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       num=0;
+       des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+               (C_Block *)ofb_tmp,&num);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ofb64_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing ede_ofb64\n");
+       des_key_sched((C_Block *)ofb_key,ks);
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       memset(ofb_buf1,0,sizeof(ofb_buf1));
+       memset(ofb_buf2,0,sizeof(ofb_buf1));
+       num=0;
+       for (i=0; i<sizeof(plain); i++)
+               {
+               des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
+                       (C_Block *)ofb_tmp,&num);
+               }
+       if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
+               {
+               printf("ede_ofb64_encrypt encrypt error\n");
+               err=1;
+               }
+       memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
+       num=0;
+       des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
+               ks,ks,(C_Block *)ofb_tmp,&num);
+       if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
+               {
+               printf("ede_ofb64_encrypt decrypt error\n");
+               err=1;
+               }
+
+       printf("Doing cbc_cksum\n");
+       des_key_sched((C_Block *)cbc_key,ks);
+       cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
+               (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
+       if (cs != cbc_cksum_ret)
+               {
+               printf("bad return value (%08lX), should be %08lX\n",
+                       (unsigned long)cs,(unsigned long)cbc_cksum_ret);
+               err=1;
+               }
+       if (memcmp(cret,cbc_cksum_data,8) != 0)
+               {
+               printf("bad cbc_cksum block returned\n");
+               err=1;
+               }
+
+       printf("Doing quad_cksum\n");
+       cs=quad_cksum((C_Block *)cbc_data,(C_Block *)lqret,
+               (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
+       if (cs != 0x70d7a63aL)
+               {
+               printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
+                       (unsigned long)cs);
+               err=1;
+               }
+       if (lqret[0] != 0x327eba8dL)
+               {
+               printf("quad_cksum error, out[0] %08lx is not %08lx\n",
+                       (unsigned long)lqret[0],0x327eba8dL);
+               err=1;
+               }
+       if (lqret[1] != 0x201a49ccL)
+               {
+               printf("quad_cksum error, out[1] %08lx is not %08lx\n",
+                       (unsigned long)lqret[1],0x201a49ccL);
+               err=1;
+               }
+       if (lqret[2] != 0x70d7a63aL)
+               {
+               printf("quad_cksum error, out[2] %08lx is not %08lx\n",
+                       (unsigned long)lqret[2],0x70d7a63aL);
+               err=1;
+               }
+       if (lqret[3] != 0x501c2c26L)
+               {
+               printf("quad_cksum error, out[3] %08lx is not %08lx\n",
+                       (unsigned long)lqret[3],0x501c2c26L);
+               err=1;
+               }
+#endif
+
+       printf("input word alignment test");
+       for (i=0; i<4; i++)
+               {
+               printf(" %d",i);
+               des_cbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
+                       (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
+                       DES_ENCRYPT);
+               }
+       printf("\noutput word alignment test");
+       for (i=0; i<4; i++)
+               {
+               printf(" %d",i);
+               des_cbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
+                       (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
+                       DES_ENCRYPT);
+               }
+       printf("\n");
+       printf("fast crypt test ");
+       str=crypt("testing","ef");
+       if (strcmp("efGnQx2725bI2",str) != 0)
+               {
+               printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
+               err=1;
+               }
+       str=crypt("bca76;23","yA");
+       if (strcmp("yA1Rp/1hZXIJk",str) != 0)
+               {
+               printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
+               err=1;
+               }
+       printf("\n");
+       exit(err);
+       return(0);
+       }
+
+static char *pt(p)
+unsigned char *p;
+       {
+       static char bufs[10][20];
+       static int bnum=0;
+       char *ret;
+       int i;
+       static char *f="0123456789ABCDEF";
+
+       ret= &(bufs[bnum++][0]);
+       bnum%=10;
+       for (i=0; i<8; i++)
+               {
+               ret[i*2]=f[(p[i]>>4)&0xf];
+               ret[i*2+1]=f[p[i]&0xf];
+               }
+       ret[16]='\0';
+       return(ret);
+       }
+
+#ifndef LIBDES_LIT
+
+static int cfb_test(bits, cfb_cipher)
+int bits;
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int i,err=0;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
+               (C_Block *)cfb_tmp,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
+               (C_Block *)cfb_tmp,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       return(err);
+       }
+
+static int cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int err=0,i,n;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+               (long)sizeof(plain)-12,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+               (long)sizeof(plain)-17,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf2[i])));
+               }
+       return(err);
+       }
+
+static int ede_cfb64_test(cfb_cipher)
+unsigned char *cfb_cipher;
+       {
+       des_key_schedule ks;
+       int err=0,i,n;
+
+       des_key_sched((C_Block *)cfb_key,ks);
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
+               (long)sizeof(plain)-12,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
+       if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("ede_cfb_encrypt encrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf1[i])));
+               }
+       memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
+       n=0;
+       des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
+               (long)sizeof(plain)-17,ks,ks,ks,
+               (C_Block *)cfb_tmp,&n,DES_DECRYPT);
+       if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
+               {
+               err=1;
+               printf("ede_cfb_encrypt decrypt error\n");
+               for (i=0; i<24; i+=8)
+                       printf("%s\n",pt(&(cfb_buf2[i])));
+               }
+       return(err);
+       }
+
+#endif
+
diff --git a/mac/libdes/src/COPYRIGHT b/mac/libdes/src/COPYRIGHT
new file mode 100755 (executable)
index 0000000..00800d6
--- /dev/null
@@ -0,0 +1 @@
+Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\rAll rights reserved.\r\rThis package is an DES implementation written by Eric Young (eay@mincom.oz.au).\rThe implementation was written so as to conform with MIT's libdes.\r\rThis library is free for commercial and non-commercial use as long as\rthe following conditions are aheared to.  The following conditions\rapply to all code found in this distribution.\r\rCopyright remains Eric Young's, and as such any Copyright notices in\rthe code are not to be removed.\rIf this package is used in a product, Eric Young should be given attribution\ras the author of that the SSL library.  This can be in the form of a textual\rmessage at program startup or in documentation (online or textual) provided\rwith the package.\r\rRedistribution and use in source and binary forms, with or without\rmodification, are permitted provided that the following conditions\rare met:\r1. Redistributions of source code must retain the copyright\r   notice, this list of conditions and the following disclaimer.\r2. Redistributions in binary form must reproduce the above copyright\r   notice, this list of conditions and the following disclaimer in the\r   documentation and/or other materials provided with the distribution.\r3. All advertising materials mentioning features or use of this software\r   must display the following acknowledgement:\r   This product includes software developed by Eric Young (eay@mincom.oz.au)\r\rTHIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\rANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\rIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\rARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\rFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\rDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\rOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\rHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\rLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\rOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\rSUCH DAMAGE.\r\rThe license and distribution terms for any publically available version or\rderivative of this code cannot be changed.  i.e. this code cannot simply be\rcopied and put under another distrubution license\r[including the GNU Public License.]\r\rThe reason behind this being stated in this direct manner is past\rexperience in code simply being copied and the attribution removed\rfrom it and then being distributed as part of other packages. This\rimplementation was a non-trivial and unpaid effort.\r
\ No newline at end of file
diff --git a/mac/libdes/src/ChangeLog b/mac/libdes/src/ChangeLog
new file mode 100755 (executable)
index 0000000..22e9749
--- /dev/null
@@ -0,0 +1 @@
+Mon May 25 05:24:56 1998  Assar Westerlund  <assar@sics.se>\r\r  * Makefile.in (clean): try to remove shared library debris\r\rSun Apr 19 09:50:53 1998  Assar Westerlund  <assar@sics.se>\r\r       * Makefile.in: add symlink magic for linux\r\rSun Nov  9 07:14:45 1997  Assar Westerlund  <assar@sics.se>\r\r       * mdtest.c: print out old and new string\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/DES.pm b/mac/libdes/src/DES.pm
new file mode 100755 (executable)
index 0000000..6a175b6
--- /dev/null
@@ -0,0 +1,19 @@
+package DES;
+
+require Exporter;
+require DynaLoader;
+@ISA = qw(Exporter DynaLoader);
+# Items to export into callers namespace by default
+# (move infrequently used names to @EXPORT_OK below)
+@EXPORT = qw(
+);
+# Other items we are prepared to export if requested
+@EXPORT_OK = qw(
+crypt
+);
+
+# Preloaded methods go here.  Autoload methods go after __END__, and are
+# processed by the autosplit program.
+bootstrap DES;
+1;
+__END__
diff --git a/mac/libdes/src/DES.pod b/mac/libdes/src/DES.pod
new file mode 100755 (executable)
index 0000000..2b89e83
--- /dev/null
@@ -0,0 +1 @@
+crypt  <=      crypt(buf,salt)\rkey     <=      set_odd_parity(key)\rint <=      is_weak_key(key)\rkeysched<=     set_key(key)\rkey        <=      ecb_encrypt(string8,ks,enc)\rkey <=      ecb3_encrypt(input,ks1,ks2,enc)\rstring  <=      cbc_encrypt(input,ks,ivec,enc)                  => ivec \rstring <=      cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,enc)     => ivec1&ivec2 \rck1,ck2 <=      cbc_cksum(input,ks,ivec)                        => ivec\rstring  <=      pcbc_encrypt(input,ks,ivec,enc)                 => ivec \rstring <=      ofb_encrypt(input,numbits,ks,ivec)              => ivec\rstring  <=      cfb_encrypt(input,numbits,ks,ivec,enc)          => ivec\rkey     <=      random_key()\rkey        <=      string_to_key(string)\rkey1,key2<=       string_to_2keys(string)\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/DES.xs b/mac/libdes/src/DES.xs
new file mode 100755 (executable)
index 0000000..5191719
--- /dev/null
@@ -0,0 +1 @@
+#include "EXTERN.h"\r#include "perl.h"\r#include "XSUB.h"\r#include "des.h"\r\r#define deschar      char\rstatic STRLEN len;\r\rstatic int\rnot_here(s)\rchar *s;\r{\r    croak("%s not implemented on this architecture", s);\r    return -1;\r}\r\rMODULE = DES      PACKAGE = DES   PREFIX = des_\r\rchar *\rdes_crypt(buf,salt)\r      char *  buf\r    char *  salt\r\rvoid\rdes_set_odd_parity(key)\r     des_cblock *    key\rPPCODE:\r    {\r      SV *s;\r\r        s=sv_newmortal();\r      sv_setpvn(s,(char *)key,8);\r    des_set_odd_parity((des_cblock *)SvPV(s,na));\r  PUSHs(s);\r      }\r\rint\rdes_is_weak_key(key)\r    des_cblock *    key\r\rdes_key_schedule\rdes_set_key(key)\r des_cblock *    key\rCODE:\r      des_set_key(key,RETVAL);\rOUTPUT:\rRETVAL\r\rdes_cblock\rdes_ecb_encrypt(input,ks,encrypt)\r  des_cblock *    input\r  des_key_schedule *      ks\r     int     encrypt\rCODE:\r  des_ecb_encrypt(input,&RETVAL,*ks,encrypt);\rOUTPUT:\rRETVAL\r\rvoid\rdes_cbc_encrypt(input,ks,ivec,encrypt)\r        char *  input\r  des_key_schedule *      ks\r     des_cblock *    ivec\r   int     encrypt\rPPCODE:\r        {\r      SV *s;\r STRLEN len,l;\r  char *c;\r\r      l=SvCUR(ST(0));\r        len=((((unsigned long)l)+7)/8)*8;\r      s=sv_newmortal();\r      sv_setpvn(s,"",0);\r     SvGROW(s,len);\r SvCUR_set(s,len);\r      c=(char *)SvPV(s,na);\r  des_cbc_encrypt((des_cblock *)input,(des_cblock *)c,\r           l,*ks,ivec,encrypt);\r   sv_setpvn(ST(2),(char *)c[len-8],8);\r   PUSHs(s);\r      }\r\rvoid\rdes_cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,encrypt)\r    char *  input\r  des_key_schedule *      ks1\r    des_key_schedule *      ks2\r    des_cblock *    ivec1\r  des_cblock *    ivec2\r  int     encrypt\rPPCODE:\r        {\r      SV *s;\r STRLEN len,l;\r\r l=SvCUR(ST(0));\r        len=((((unsigned long)l)+7)/8)*8;\r      s=sv_newmortal();\r      sv_setpvn(s,"",0);\r     SvGROW(s,len);\r SvCUR_set(s,len);\r      des_3cbc_encrypt((des_cblock *)input,(des_cblock *)SvPV(s,na),\r         l,*ks1,*ks2,ivec1,ivec2,encrypt);\r      sv_setpvn(ST(3),(char *)ivec1,8);\r      sv_setpvn(ST(4),(char *)ivec2,8);\r      PUSHs(s);\r      }\r\rvoid\rdes_cbc_cksum(input,ks,ivec)\r   char *  input\r  des_key_schedule *      ks\r     des_cblock *    ivec\rPPCODE:\r   {\r      SV *s1,*s2;\r    STRLEN len,l;\r  des_cblock c;\r  unsigned long i1,i2;\r\r  s1=sv_newmortal();\r     s2=sv_newmortal();\r     l=SvCUR(ST(0));\r        des_cbc_cksum((des_cblock *)input,(des_cblock *)c,\r             l,*ks,ivec);\r   i1=c[4]|(c[5]<<8)|(c[6]<<16)|(c[7]<<24);\r       i2=c[0]|(c[1]<<8)|(c[2]<<16)|(c[3]<<24);\r       sv_setiv(s1,i1);\r       sv_setiv(s2,i2);\r       sv_setpvn(ST(2),(char *)c,8);\r  PUSHs(s1);\r     PUSHs(s2);\r     }\r\rvoid\rdes_cfb_encrypt(input,numbits,ks,ivec,encrypt)\r char *  input\r  int     numbits\r        des_key_schedule *      ks\r     des_cblock *    ivec\r   int     encrypt\rPPCODE:\r        {\r      SV *s;\r STRLEN len;\r    char *c;\r\r      len=SvCUR(ST(0));\r      s=sv_newmortal();\r      sv_setpvn(s,"",0);\r     SvGROW(s,len);\r SvCUR_set(s,len);\r      c=(char *)SvPV(s,na);\r  des_cfb_encrypt((unsigned char *)input,(unsigned char *)c,\r             (int)numbits,(long)len,*ks,ivec,encrypt);\r      sv_setpvn(ST(3),(char *)ivec,8);\r       PUSHs(s);\r      }\r\rdes_cblock *\rdes_ecb3_encrypt(input,ks1,ks2,encrypt)\r        des_cblock *    input\r  des_key_schedule *      ks1\r    des_key_schedule *      ks2\r    int     encrypt\rCODE:\r  {\r      des_cblock c;\r\r des_3ecb_encrypt((des_cblock *)input,(des_cblock *)&c,\r         *ks1,*ks2,encrypt);\r    RETVAL= &c;\r    }\rOUTPUT:\rRETVAL\r\rvoid\rdes_ofb_encrypt(input,numbits,ks,ivec)\r  unsigned char * input\r  int     numbits\r        des_key_schedule *      ks\r     des_cblock *    ivec\rPPCODE:\r   {\r      SV *s;\r STRLEN len,l;\r  unsigned char *c;\r\r     len=SvCUR(ST(0));\r      s=sv_newmortal();\r      sv_setpvn(s,"",0);\r     SvGROW(s,len);\r SvCUR_set(s,len);\r      c=(unsigned char *)SvPV(s,na);\r des_ofb_encrypt((unsigned char *)input,(unsigned char *)c,\r             numbits,len,*ks,ivec);\r sv_setpvn(ST(3),(char *)ivec,8);\r       PUSHs(s);\r      }\r\rvoid\rdes_pcbc_encrypt(input,ks,ivec,encrypt)\r        char *  input\r  des_key_schedule *      ks\r     des_cblock *    ivec\r   int     encrypt\rPPCODE:\r        {\r      SV *s;\r STRLEN len,l;\r  char *c;\r\r      l=SvCUR(ST(0));\r        len=((((unsigned long)l)+7)/8)*8;\r      s=sv_newmortal();\r      sv_setpvn(s,"",0);\r     SvGROW(s,len);\r SvCUR_set(s,len);\r      c=(char *)SvPV(s,na);\r  des_pcbc_encrypt((des_cblock *)input,(des_cblock *)c,\r          l,*ks,ivec,encrypt);\r   sv_setpvn(ST(2),(char *)c[len-8],8);\r   PUSHs(s);\r      }\r\rdes_cblock *\rdes_random_key()\rCODE:\r {\r      des_cblock c;\r\r des_random_key(c);\r     RETVAL=&c;\r     }\rOUTPUT:\rRETVAL\r\rdes_cblock *\rdes_string_to_key(str)\rchar *    str\rCODE:\r      {\r      des_cblock c;\r\r des_string_to_key(str,&c);\r     RETVAL=&c;\r     }\rOUTPUT:\rRETVAL\r\rvoid\rdes_string_to_2keys(str)\rchar *  str\rPPCODE:\r    {\r      des_cblock c1,c2;\r      SV *s1,*s2;\r\r   des_string_to_2keys(str,&c1,&c2);\r      EXTEND(sp,2);\r  s1=sv_newmortal();\r     sv_setpvn(s1,(char *)c1,8);\r    s2=sv_newmortal();\r     sv_setpvn(s2,(char *)c2,8);\r    PUSHs(s1);\r     PUSHs(s2);\r     }\r
\ No newline at end of file
diff --git a/mac/libdes/src/FILES b/mac/libdes/src/FILES
new file mode 100755 (executable)
index 0000000..2fb0071
--- /dev/null
@@ -0,0 +1 @@
+/* General stuff */\rCOPYRIGHT  - Copyright info.\rMODES.DES     - A description of the features of the different modes of DES.\rFILES            - This file.\rINSTALL            - How to make things compile.\rImakefile - For use with kerberos.\rREADME         - What this package is.\rVERSION         - Which version this is and what was changed.\rKERBEROS  - Kerberos version 4 notes.\rMakefile.PL - An old makefile to build with perl5, not current.\rMakefile.ssl        - The SSLeay makefile\rMakefile.uni      - The normal unix makefile.\rGNUmakefile - The makefile for use with glibc.\rmakefile.bc  - A Borland C makefile\rtimes            - Some outputs from 'speed' on some machines.\rvms.com           - For use when compiling under VMS\r\r/* My SunOS des(1) replacement */\rdes.c             - des(1) source code.\rdes.man           - des(1) manual.\r\r/* Testing and timing programs. */\rdestest.c  - Source for libdes.a test program.\rspeed.c             - Source for libdes.a timing program.\rrpw.c             - Source for libdes.a testing password reading routines.\r\r/* libdes.a source code */\rdes_crypt.man      - libdes.a manual page.\rdes.h           - Public libdes.a header file.\recb_enc.c        - des_ecb_encrypt() source, this contains the basic DES code.\recb3_enc.c        - des_ecb3_encrypt() source.\rcbc_ckm.c  - des_cbc_cksum() source.\rcbc_enc.c     - des_cbc_encrypt() source.\rncbc_enc.c  - des_cbc_encrypt() that is 'normal' in that it copies\r           the new iv values back in the passed iv vector.\rede_enc.c     - des_ede3_cbc_encrypt() cbc mode des using triple DES.\rcbc3_enc.c      - des_3cbc_encrypt() source, don't use this function.\rcfb_enc.c - des_cfb_encrypt() source.\rcfb64enc.c  - des_cfb64_encrypt() cfb in 64 bit mode but setup to be\r                 used as a stream cipher.\rcfb64ede.c   - des_ede3_cfb64_encrypt() cfb in 64 bit mode but setup to be\r            used as a stream cipher and using triple DES.\rofb_enc.c       - des_cfb_encrypt() source.\rofb64_enc.c - des_ofb_encrypt() ofb in 64 bit mode but setup to be\r           used as a stream cipher.\rofb64ede.c   - des_ede3_ofb64_encrypt() ofb in 64 bit mode but setup to be\r            used as a stream cipher and using triple DES.\renc_read.c      - des_enc_read() source.\renc_writ.c     - des_enc_write() source.\rpcbc_enc.c    - des_pcbc_encrypt() source.\rqud_cksm.c - quad_cksum() source.\rrand_key.c       - des_random_key() source.\rread_pwd.c   - Source for des_read_password() plus related functions.\rset_key.c      - Source for des_set_key().\rstr2key.c   - Covert a string of any length into a key.\rfcrypt.c    - A small, fast version of crypt(3).\rdes_locl.h - Internal libdes.a header file.\rpodd.h         - Odd parity tables - used in des_set_key().\rsk.h               - Lookup tables used in des_set_key().\rspr.h            - What is left of the S tables - used in ecb_encrypt().\rdes_ver.h       - header file for the external definition of the\r                 version string.\rdes.doc               - SSLeay documentation for the library.\r\r/* The perl scripts - you can ignore these files they are only\r * included for the curious */\rdes.pl           - des in perl anyone? des_set_key and des_ecb_encrypt\r            both done in a perl library.\rtestdes.pl       - Testing program for des.pl\rdoIP               - Perl script used to develop IP xor/shift code.\rdoPC1          - Perl script used to develop PC1 xor/shift code.\rdoPC2         - Generates sk.h.\rPC1           - Output of doPC1 should be the same as output from PC1.\rPC2            - used in development of doPC2.\rshifts.pl       - Perl library used by my perl scripts.\r\r/* I started making a perl5 dynamic library for libdes\r * but did not fully finish, these files are part of that effort. */\rDES.pm\rDES.pod\rDES.xs\rt\rtypemap\r\r/* The following are for use with sun RPC implementaions. */\rrpc_des.h\rrpc_enc.c\r\r/* The following are contibuted by Mark Murray <mark@grondar.za>.  They\r * are not normally built into libdes due to machine specific routines\r * contained in them.  They are for use in the most recent incarnation of\r * export kerberos v 4 (eBones). */\rsupp.c\rnew_rkey.c\r\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/INSTALL b/mac/libdes/src/INSTALL
new file mode 100755 (executable)
index 0000000..c07b159
--- /dev/null
@@ -0,0 +1 @@
+Check the CC and CFLAGS lines in the makefile\r\rIf your C library does not support the times(3) function, change the\r#define TIMES to\r#undef TIMES in speed.c\rIf it does, check the HZ value for the times(3) function.\rIf your system does not define CLK_TCK it will be assumed to\rbe 100.0.\r\rIf possible use gcc v 2.7.?\rTurn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)\rIn recent times, some system compilers give better performace.\r\rtype 'make'\r\rrun './destest' to check things are ok.\rrun './rpw' to check the tty code for reading passwords works.\rrun './speed' to see how fast those optimisations make the library run :-)\rrun './des_opts' to determin the best compile time options.\r\rThe output from des_opts should be put in the makefile options and des_enc.c\rshould be rebuilt.  For 64 bit computers, do not use the DES_PTR option.\rFor the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'\rand then you can use the 'DES_PTR' option.\r\rThe file options.txt has the options listed for best speed on quite a\rfew systems.  Look and the options (UNROLL, PTR, RISC2 etc) and then\rturn on the relevent option in the Makefile\r\rThere are some special Makefile targets that make life easier.\rmake cc               - standard cc build\rmake gcc    - standard gcc build\rmake x86-elf       - x86 assember (elf), linux-elf.\rmake x86-out   - x86 assember (a.out), FreeBSD\rmake x86-solaris- x86 assember\rmake x86-bsdi    - x86 assember (a.out with primative assember).\r\rIf at all possible use the assember (for Windows NT/95, use\rasm/win32.obj to link with).  The x86 assember is very very fast.\r\rA make install will by default install\rlibdes.a      in /usr/local/lib/libdes.a\rdes           in /usr/local/bin/des\rdes_crypt.man in /usr/local/man/man3/des_crypt.3\rdes.man       in /usr/local/man/man1/des.1\rdes.h         in /usr/include/des.h\r\rdes(1) should be compatible with sunOS's but I have been unable to\rtest it.\r\rThese routines should compile on MSDOS, most 32bit and 64bit version\rof Unix (BSD and SYSV) and VMS, without modification.\rThe only problems should be #include files that are in the wrong places.\r\rThese routines can be compiled under MSDOS.\rI have successfully encrypted files using des(1) under MSDOS and then\rdecrypted the files on a SparcStation.\rI have been able to compile and test the routines with\rMicrosoft C v 5.1 and Turbo C v 2.0.\rThe code in this library is in no way optimised for the 16bit\roperation of MSDOS.\r\rWhen building for glibc, ignore all of the above and just unpack into\rglibc-1.??/des and then gmake as per normal.\r\rAs a final note on performace.  Certain CPUs like sparcs and Alpha often give\ra %10 speed difference depending on the link order.  It is rather anoying\rwhen one program reports 'x' DES encrypts a second and another reports\r'x*0.9' the speed.\r
\ No newline at end of file
diff --git a/mac/libdes/src/Imakefile b/mac/libdes/src/Imakefile
new file mode 100755 (executable)
index 0000000..9d74a35
--- /dev/null
@@ -0,0 +1 @@
+# This Imakefile has not been tested for a while but it should still\r# work when placed in the correct directory in the kerberos v 4 distribution\r\rSRCS=   cbc_cksm.c cbc_enc.c ecb_enc.c pcbc_enc.c \\r        qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \\r        enc_read.c enc_writ.c fcrypt.c cfb_enc.c \\r      ecb3_enc.c ofb_enc.c ofb64enc.c\r\rOBJS=   cbc_cksm.o cbc_enc.o ecb_enc.o pcbc_enc.o \\r   qud_cksm.o rand_key.o read_pwd.o set_key.o str2key.o \\r enc_read.o enc_writ.o fcrypt.o cfb_enc.o \\r     ecb3_enc.o ofb_enc.o ofb64enc.o\r\rGENERAL=COPYRIGHT FILES INSTALL Imakefile README VERSION makefile times \\r     vms.com KERBEROS\rDES=    des.c des.man\rTESTING=destest.c speed.c rpw.c\rLIBDES= des_crypt.man des.h des_locl.h podd.h sk.h spr.h\r\rPERL=   des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl\r\rCODE=    $(GENERAL) $(DES) $(TESTING) $(SRCS) $(LIBDES) $(PERL)\r\rSRCDIR=$(SRCTOP)/lib/des\r\rDBG= -O\rINCLUDE= -I$(SRCDIR)\rCC= cc\r\rlibrary_obj_rule()\r\rinstall_library_target(des,$(OBJS),$(SRCS),)\r\rtest(destest,libdes.a,)\rtest(rpw,libdes.a,)\r
\ No newline at end of file
diff --git a/mac/libdes/src/KERBEROS b/mac/libdes/src/KERBEROS
new file mode 100755 (executable)
index 0000000..db3bfe4
--- /dev/null
@@ -0,0 +1 @@
+ [ This is an old file, I don't know if it is true anymore\r   but I will leave the file here - eay 21/11/95 ]\r\rTo use this library with Bones (kerberos without DES):\r1) Get my modified Bones - eBones.  It can be found on\r   gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z\r   and\r   nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z\r\r2) Unpack this library in src/lib/des, makeing sure it is version\r   3.00 or greater (libdes.tar.93-10-07.Z).  This versions differences\r   from the version in comp.sources.misc volume 29 patchlevel2.\r   The primarily difference is that it should compile under kerberos :-).\r   It can be found at.\r   ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z\r\rNow do a normal kerberos build and things should work.\r\rOne problem I found when I was build on my local sun.\r---\rFor sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c\r\r*** make_commands.c.orig Fri Jul  3 04:18:35 1987\r--- make_commands.c    Wed May 20 08:47:42 1992\r***************\r*** 98,104 ****\r       if (!rename(o_file, z_file)) {\r           if (!vfork()) {\r             chdir("/tmp");\r!                execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n",\r                     z_file+5, 0);\r            perror("/bin/ld");\r             _exit(1);\r--- 98,104 ----\r       if (!rename(o_file, z_file)) {\r           if (!vfork()) {\r             chdir("/tmp");\r!                execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r",\r                   z_file+5, 0);\r            perror("/bin/ld");\r             _exit(1);\r
\ No newline at end of file
diff --git a/mac/libdes/src/MODES.DES b/mac/libdes/src/MODES.DES
new file mode 100755 (executable)
index 0000000..63b0eb2
--- /dev/null
@@ -0,0 +1 @@
+Modes of DES\rQuite a bit of the following information has been taken from\r     AS 2805.5.2\r    Australian Standard\r    Electronic funds transfer - Requirements for interfaces,\r       Part 5.2: Modes of operation for an n-bit block cipher algorithm\r       Appendix A\r\rThere are several different modes in which DES can be used, they are\ras follows.\r\rElectronic Codebook Mode (ECB) (des_ecb_encrypt())\r- 64 bits are enciphered at a time.\r- The order of the blocks can be rearranged without detection.\r- The same plaintext block always produces the same ciphertext block\r  (for the same key) making it vulnerable to a 'dictionary attack'.\r- An error will only affect one ciphertext block.\r\rCipher Block Chaining Mode (CBC) (des_cbc_encrypt())\r- a multiple of 64 bits are enciphered at a time.\r- The CBC mode produces the same ciphertext whenever the same\r  plaintext is encrypted using the same key and starting variable.\r- The chaining operation makes the ciphertext blocks dependent on the\r  current and all preceding plaintext blocks and therefore blocks can not\r  be rearranged.\r- The use of different starting variables prevents the same plaintext\r  enciphering to the same ciphertext.\r- An error will affect the current and the following ciphertext blocks.\r\rCipher Feedback Mode (CFB) (des_cfb_encrypt())\r- a number of bits (j) <= 64 are enciphered at a time.\r- The CFB mode produces the same ciphertext whenever the same\r  plaintext is encrypted using the same key and starting variable.\r- The chaining operation makes the ciphertext variables dependent on the\r  current and all preceding variables and therefore j-bit variables are\r  chained together and con not be rearranged.\r- The use of different starting variables prevents the same plaintext\r  enciphering to the same ciphertext.\r- The strength of the CFB mode depends on the size of k (maximal if\r  j == k).  In my implementation this is always the case.\r- Selection of a small value for j will require more cycles through\r  the encipherment algorithm per unit of plaintext and thus cause\r  greater processing overheads.\r- Only multiples of j bits can be enciphered.\r- An error will affect the current and the following ciphertext variables.\r\rOutput Feedback Mode (OFB) (des_ofb_encrypt())\r- a number of bits (j) <= 64 are enciphered at a time.\r- The OFB mode produces the same ciphertext whenever the same\r  plaintext enciphered using the same key and starting variable.  More\r  over, in the OFB mode the same key stream is produced when the same\r  key and start variable are used.  Consequently, for security reasons\r  a specific start variable should be used only once for a given key.\r- The absence of chaining makes the OFB more vulnerable to specific attacks.\r- The use of different start variables values prevents the same\r  plaintext enciphering to the same ciphertext, by producing different\r  key streams.\r- Selection of a small value for j will require more cycles through\r  the encipherment algorithm per unit of plaintext and thus cause\r  greater processing overheads.\r- Only multiples of j bits can be enciphered.\r- OFB mode of operation does not extend ciphertext errors in the\r  resultant plaintext output.  Every bit error in the ciphertext causes\r  only one bit to be in error in the deciphered plaintext.\r- OFB mode is not self-synchronising.  If the two operation of\r  encipherment and decipherment get out of synchronism, the system needs\r  to be re-initialised.\r- Each re-initialisation should use a value of the start variable\rdifferent from the start variable values used before with the same\rkey.  The reason for this is that an identical bit stream would be\rproduced each time from the same parameters.  This would be\rsusceptible to a 'known plaintext' attack.\r\rTriple ECB Mode (des_3ecb_encrypt())\r- Encrypt with key1, decrypt with key2 and encrypt with key1 again.\r- As for ECB encryption but increases the effective key length to 112 bits.\r- If both keys are the same it is equivalent to encrypting once with\r  just one key.\r\rTriple CBC Mode (des_3cbc_encrypt())\r- Encrypt with key1, decrypt with key2 and encrypt with key1 again.\r- As for CBC encryption but increases the effective key length to 112 bits.\r- If both keys are the same it is equivalent to encrypting once with\r  just one key.\r
\ No newline at end of file
diff --git a/mac/libdes/src/Makefile.PL b/mac/libdes/src/Makefile.PL
new file mode 100755 (executable)
index 0000000..d68b89d
--- /dev/null
@@ -0,0 +1 @@
+use ExtUtils::MakeMaker;\r# See lib/ExtUtils/MakeMaker.pm for details of how to influence\r# the contents of the Makefile being created.\r&writeMakefile(\r        'potential_libs' => '',   # e.g., '-lm' \r       'INC' => '',     # e.g., '-I/usr/include/other' \r       'DISTNAME' => 'DES',\r   'VERSION' => '0.1',\r    'DEFINE' => '-DPERL5',\r 'OBJECT' => 'DES.o cbc_cksm.o cbc_enc.o ecb_enc.o pcbc_enc.o \\r rand_key.o set_key.o str2key.o \\r       enc_read.o enc_writ.o fcrypt.o cfb_enc.o \\r     ecb3_enc.o ofb_enc.o cbc3_enc.o des_enc.o',\r    );\r
\ No newline at end of file
diff --git a/mac/libdes/src/Makefile.am b/mac/libdes/src/Makefile.am
new file mode 100755 (executable)
index 0000000..82fd07f
--- /dev/null
@@ -0,0 +1 @@
+# $Id: Makefile.am,v 1.2 2001/12/04 02:06:26 rjs3 Exp $\r\rAUTOMAKE_OPTIONS = no-dependencies foreign\r\rINCLUDES = -I$(top_builddir)/include\r\r#lib_LIBRARIES = libdes.a\rlib_LTLIBRARIES = libdes.la\rinclude_HEADERS = des.h\r\rnoinst_PROGRAMS = destest mdtest\r\rbin_PROGRAMS = des rpw speed\r\rLDADD = $(lib_LTLIBRARIES)\r\rlibdes_la_SOURCES = \\r   cbc3_enc.c cbc_cksm.c cbc_enc.c \\r      cfb64ede.c cfb64enc.c cfb_enc.c des_enc.c \\r    ecb3_enc.c ecb_enc.c ede_enc.c enc_read.c \\r    enc_writ.c fcrypt.c key_par.c md4.c md5.c \\r    ncbc_enc.c ofb64ede.c ofb64enc.c ofb_enc.c \\r   pcbc_enc.c qud_cksm.c read_pwd.c rnd_keys.c \\r  set_key.c sha.c str2key.c xcbc_enc.c\r
\ No newline at end of file
diff --git a/mac/libdes/src/Makefile.in b/mac/libdes/src/Makefile.in
new file mode 100755 (executable)
index 0000000..cf16b25
--- /dev/null
@@ -0,0 +1 @@
+#\r# $Id: Makefile.in,v 1.2 2001/12/04 02:06:26 rjs3 Exp $\r#\r\rSHELL = /bin/sh\r\rsrcdir = @srcdir@\rVPATH = @srcdir@\r\rCC = @CC@\rLINK = @LINK@\rAR = ar\rRANLIB = @RANLIB@\rLN_S = @LN_S@\rDEFS = @DEFS@\rCFLAGS = @CFLAGS@\rLD_FLAGS = @LD_FLAGS@\rLDSHARED = @LDSHARED@\r\rINSTALL = @INSTALL@\rINSTALL_DATA        = @INSTALL_DATA@\rINSTALL_PROGRAM = @INSTALL_PROGRAM@\rMKINSTALLDIRS = @top_srcdir@/mkinstalldirs\r\rprefix = @prefix@\rexec_prefix = @exec_prefix@\rbindir = @bindir@\rlibdir = @libdir@\rtransform=@program_transform_name@\rEXECSUFFIX=@EXECSUFFIX@\r\rPICFLAGS = @PICFLAGS@\r \rLIB_DEPS = @lib_deps_yes@ -lc\rbuild_symlink_command   = @build_symlink_command@\rinstall_symlink_command = @install_symlink_command@\r\rPROGS = destest$(EXECSUFFIX) \\r     mdtest$(EXECSUFFIX) \\r  des$(EXECSUFFIX) \\r     rpw$(EXECSUFFIX) \\r     speed$(EXECSUFFIX)\rPROGS2INSTALL = des$(EXECSUFFIX)\rLIBNAME = $(LIBPREFIX)des\rLIBEXT = @LIBEXT@\rLIBPREFIX = @LIBPREFIX@\rSHLIBEXT = @SHLIBEXT@\rLIB = $(LIBNAME).$(LIBEXT)\r\r# Generated with lorder *.o | tsort | xargs echo\r\rLIBSRC = xcbc_enc.c sha.c rnd_keys.c read_pwd.c qud_cksm.c pcbc_enc.c \\r    ofb_enc.c ofb64enc.c ofb64ede.c ncbc_enc.c md4.c key_par.c fcrypt.c \\r  ede_enc.c ecb3_enc.c cfb_enc.c cfb64enc.c cfb64ede.c cbc3_enc.c \\r      str2key.c set_key.c md5.c cbc_enc.c cbc_cksm.c ecb_enc.c des_enc.c\r\rLIBOBJ = xcbc_enc.o sha.o rnd_keys.o read_pwd.o qud_cksm.o pcbc_enc.o \\r    ofb_enc.o ofb64enc.o ofb64ede.o ncbc_enc.o md4.o key_par.o fcrypt.o \\r  ede_enc.o ecb3_enc.o cfb_enc.o cfb64enc.o cfb64ede.o cbc3_enc.o \\r      str2key.o set_key.o md5.o cbc_enc.o cbc_cksm.o ecb_enc.o des_enc.o\r\rall: $(LIB) $(PROGS)\r\rWall:\r        make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"\r\rCOM = $(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(PICFLAGS)\r\r.c.o:\r  $(COM) $(CFLAGS) $<\r\r# Compile this file without debug if using gcc\rdes_enc.o: des_enc.c\r       @if test "$(CC)" = gcc; then\\r    echo "$(COM) -fomit-frame-pointer -O3 $(srcdir)/des_enc.c"; \\r          $(COM) -fomit-frame-pointer -O3 $(srcdir)/des_enc.c; \\r       else \\r   echo "$(COM) $(CFLAGS) $(srcdir)/des_enc.c"; \\r         $(COM) $(CFLAGS) $(srcdir)/des_enc.c; \\r      fi\r\rinstall: all\r       $(MKINSTALLDIRS) $(DESTDIR)$(libdir)\r   $(INSTALL_DATA) -m 0555 $(LIB) $(DESTDIR)$(libdir)/$(LIB)\r      @install_symlink_command@\r      $(MKINSTALLDIRS) $(DESTDIR)$(bindir)\r   for x in $(PROGS2INSTALL); do \\r          $(INSTALL_PROGRAM) $$x $(DESTDIR)$(bindir)/`echo $$x | sed '$(transform)'`; \\r        done\r\runinstall:\r       rm -f $(DESTDIR)$(libdir)/$(LIB)\r       for x in $(PROGS2INSTALL); do \\r          rm -f $(DESTDIR)$(bindir)/`echo $$x | sed '$(transform)'`; \\r done\r\rTAGS: $(LIBSRC)\r  etags $(LIBSRC)\r\rcheck: destest$(EXECSUFFIX) mdtest$(EXECSUFFIX)\r       ./destest$(EXECSUFFIX)\r ./mdtest$(EXECSUFFIX)\r\rclean:\r  rm -f $(LIB) *.so *.so.* so_locations *.o *.a $(PROGS)\r\rmostlyclean: clean\r\rdistclean: clean\r   rm -f Makefile *.tab.c *~\r\rrealclean: distclean\r        rm -f TAGS\r\r$(LIBNAME).a: $(LIBOBJ)\r    rm -f $@\r       $(AR) cr $@ $(LIBOBJ)\r  -$(RANLIB) $@\r\r$(LIBNAME).$(SHLIBEXT): $(LIBOBJ)\r       rm -f $@\r       $(LDSHARED) -o $@ $(LIBOBJ) $(LIB_DEPS)\r        @build_symlink_command@\r\r# To make psoriaris make happy we have to mention these files in some\r# rule, so we might as well put them here.\r\rmdtest.o: mdtest.c\rdes_opts.o: des_opts.c\rdestest.o: destest.c\rdes.o: des.c\rrpw.o: rpw.c\rspeed.o: speed.c\r\rmdtest$(EXECSUFFIX): mdtest.o $(LIB)\r     $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ mdtest.o -L. -ldes\r\rdes_opts$(EXECSUFFIX): des_opts.o set_key.o\r   $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ des_opts.o set_key.o\r\rdestest$(EXECSUFFIX): destest.o $(LIB)\r      $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ destest.o -L. -ldes\r\rdes$(EXECSUFFIX): des.o $(LIB)\r       $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ des.o -L. -ldes\r\rrpw$(EXECSUFFIX): rpw.o $(LIB)\r   $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ rpw.o -L. -ldes\r\rspeed$(EXECSUFFIX): speed.o $(LIB)\r       $(LINK) $(LD_FLAGS) $(LDFLAGS) -o $@ speed.o -L. -ldes\r\r$(LIBOBJ): ../../include/config.h\r\r.PHONY: all Wall install uninstall check clean mostlyclean distclean realclean\r
\ No newline at end of file
diff --git a/mac/libdes/src/Makefile.ssl b/mac/libdes/src/Makefile.ssl
new file mode 100755 (executable)
index 0000000..68e76a6
--- /dev/null
@@ -0,0 +1 @@
+#\r# SSLeay/crypto/des/Makefile\r#\r\rDIR= des\rTOP=        ../..\rCC=       cc\rCPP= cc -E\rINCLUDES=\rCFLAG=-g\rINSTALLTOP=/usr/local/ssl\rMAKE=                make -f Makefile.ssl\rMAKEDEPEND=        makedepend -fMakefile.ssl\rMAKEFILE=     Makefile.ssl\rDES_ENC=   des_enc.o\r\rCFLAGS= $(INCLUDES) $(CFLAG)\r\rGENERAL=Makefile des.org des_locl.org\rTEST=destest.c\rAPPS=\r\rLIB=$(TOP)/libcrypto.a\rLIBSRC=     cbc3_enc.c cbc_cksm.c cbc_enc.c  cfb64enc.c cfb_enc.c  \\r       ecb3_enc.c ecb_enc.c  ede_enc.c  enc_read.c enc_writ.c \\r       fcrypt.c   ncbc_enc.c ofb64enc.c ofb_enc.c  pcbc_enc.c \\r       qud_cksm.c rand_key.c read_pwd.c rpc_enc.c  set_key.c  \\r       xcbc_enc.c des_enc.c \\r str2key.c  cfb64ede.c ofb64ede.c supp.c\r\rLIBOBJ= set_key.o  ecb_enc.o  ede_enc.o  cbc_enc.o  cbc3_enc.o \\r      ecb3_enc.o cfb64enc.o cfb64ede.o cfb_enc.o  ofb64ede.o \\r       enc_read.o enc_writ.o fcrypt.o   ncbc_enc.o ofb64enc.o \\r       ofb_enc.o  str2key.o  pcbc_enc.o qud_cksm.o rand_key.o \\r       xcbc_enc.o ${DES_ENC} \\r        read_pwd.o rpc_enc.o  cbc_cksm.o supp.o\r\rSRC= $(LIBSRC)\r\rEXHEADER= des.h\rHEADER=        des_locl.h rpc_des.h podd.h sk.h spr.h des_ver.h $(EXHEADER)\r\rALL=    $(GENERAL) $(SRC) $(HEADER)\r\rtop:\r        (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)\r\rall:      lib\r\rlib:       $(LIBOBJ)\r      ar r $(LIB) $(LIBOBJ)\r  sh $(TOP)/util/ranlib.sh $(LIB)\r        @touch lib\r\rasm/dx86-elf.o: asm/dx86-cpp.s asm/dx86unix.cpp\r    $(CPP) -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o\r\rasm/dx86-sol.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o\r\rasm/dx86-out.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o\r\rasm/dx86bsdi.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o\r\rfiles:\r  perl $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO\r\rlinks:\r /bin/rm -f Makefile\r    $(TOP)/util/point.sh Makefile.ssl Makefile ;\r   /bin/rm -f des.doc\r     $(TOP)/util/point.sh ../../doc/des.doc des.doc ;\r       $(TOP)/util/mklink.sh ../../include $(EXHEADER)\r        $(TOP)/util/mklink.sh ../../test $(TEST)\r       $(TOP)/util/mklink.sh ../../apps $(APPS)\r\rinstall: installs\r\rinstalls:\r @for i in $(EXHEADER) ; \\r      do  \\r  (cp $$i $(INSTALLTOP)/include/$$i; \\r   chmod 644 $(INSTALLTOP)/include/$$i ) \\r        done;\r\rtags:\r   ctags $(SRC)\r\rtests:\r\rlint:\r    lint -DLINT $(INCLUDES) $(SRC)>fluff\r\rdepend:\r  $(MAKEDEPEND) $(INCLUDES) $(PROGS) $(LIBSRC)\r\rdclean:\r  perl -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new\r       mv -f Makefile.new $(MAKEFILE)\r\rclean:\r /bin/rm -f *.o asm/*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff\r\rerrors:\r\r# DO NOT DELETE THIS LINE -- make depend depends on it.\r
\ No newline at end of file
diff --git a/mac/libdes/src/Makefile.uni b/mac/libdes/src/Makefile.uni
new file mode 100755 (executable)
index 0000000..16787a7
--- /dev/null
@@ -0,0 +1 @@
+# You must select the correct terminal control system to be used to\r# turn character echo off when reading passwords.  There a 5 systems\r# SGTTY   - the old BSD system\r# TERMIO  - most system V boxes\r# TERMIOS - SGI (ala IRIX).\r# VMS     - the DEC operating system\r# MSDOS   - we all know what it is :-)\r# read_pwd.c makes a reasonable guess at what is correct.\r\r# If you are on a DEC Alpha, edit des.h and change the DES_LONG\r# define to 'unsigned int'.  I have seen this give a %20 speedup.\r\rOPTS0= -DRAND -DTERMIO #-DNOCONST\r\r# Version 1.94 has changed the strings_to_key function so that it is\r# now compatible with MITs when the string is longer than 8 characters.\r# If you wish to keep the old version, uncomment the following line.\r# This will affect the -E/-D options on des(1).\r#OPTS1= -DOLD_STR_TO_KEY\r\r# There are 4 possible performance options\r# -DDES_PTR\r# -DDES_RISC1\r# -DDES_RISC2 (only one of DES_RISC1 and DES_RISC2)\r# -DDES_UNROLL\r# after the initial build, run 'des_opts' to see which options are best\r# for your platform.  There are some listed in options.txt\r#OPTS2= -DDES_PTR \r#OPTS3= -DDES_RISC1 # or DES_RISC2\rOPTS4= -DDES_UNROLL\r\rOPTS= $(OPTS0) $(OPTS1) $(OPTS2) $(OPTS3) $(OPTS4)\r\rCC=cc\rCFLAGS= -D_HPUX_SOURCE -Aa +O2 $(OPTS) $(CFLAG)\r\r#CC=gcc\r#CFLAGS= -O3 -fomit-frame-pointer $(OPTS) $(CFLAG)\r\rCPP=$(CC) -E\r\rDES_ENC=des_enc.o      # normal C version\r#DES_ENC=asm/dx86-elf.o      # elf format x86\r#DES_ENC=asm/dx86-out.o        # a.out format x86\r#DES_ENC=asm/dx86-sol.o      # solaris format x86 \r#DES_ENC=asm/dx86bsdi.o   # bsdi format x86 \r\rLIBDIR=/usr/local/lib\rBINDIR=/usr/local/bin\rINCDIR=/usr/local/include\rMANDIR=/usr/local/man\rMAN1=1\rMAN3=3\rSHELL=/bin/sh\rOBJS=       cbc3_enc.o cbc_cksm.o cbc_enc.o ncbc_enc.o pcbc_enc.o qud_cksm.o \\r     cfb64ede.o cfb64enc.o cfb_enc.o ecb3_enc.o ecb_enc.o  ede_enc.o  \\r     enc_read.o enc_writ.o fcrypt.o  ofb64ede.o ofb64enc.o ofb_enc.o  \\r     rand_key.o read_pwd.o set_key.o rpc_enc.o  str2key.o supp.o \\r  $(DES_ENC) xcbc_enc.o\r\rGENERAL=$(GENERAL_LIT) FILES Imakefile times vms.com KERBEROS MODES.DES \\r       GNUmakefile des.man DES.pm DES.pod DES.xs Makefile.PL \\r        Makefile.uni typemap t Makefile.ssl makefile.bc Makefile.lit \\r des.org des_locl.org\rDES=       des.c\rTESTING=rpw.c $(TESTING_LIT)\rHEADERS= $(HEADERS_LIT) rpc_des.h\rLIBDES= cbc_cksm.c pcbc_enc.c qud_cksm.c \\r        cfb64ede.c cfb64enc.c cfb_enc.c ecb3_enc.c  cbc3_enc.c  \\r      enc_read.c enc_writ.c ofb64ede.c ofb64enc.c ofb_enc.c  \\r       rand_key.c rpc_enc.c  str2key.c  supp.c \\r      xcbc_enc.c $(LIBDES_LIT) read_pwd.c\r\rTESTING_LIT=destest.c speed.c des_opts.c\rGENERAL_LIT=COPYRIGHT INSTALL README VERSION Makefile des_crypt.man \\r    des.doc options.txt asm\rHEADERS_LIT=des_ver.h des.h des_locl.h podd.h sk.h spr.h\rLIBDES_LIT=ede_enc.c cbc_enc.c ncbc_enc.c ecb_enc.c fcrypt.c set_key.c des_enc.c\r\rPERL=        des.pl testdes.pl doIP doIP2 doPC1 doPC2 PC1 PC2 shifts.pl\r\rALL=        $(GENERAL) $(DES) $(TESTING) $(LIBDES) $(PERL) $(HEADERS)\r\rDLIB=        libdes.a\r\rall: $(DLIB) destest rpw des speed des_opts\r\rcc:\r     make CC=cc CFLAGS="-O $(OPTS) $(CFLAG)" all\r\rgcc:\r      make CC=gcc CFLAGS="-O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all\r\rx86-elf:\r   make DES_ENC=asm/dx86-elf.o CC=gcc CFLAGS="-DELF -O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all\r\rx86-out:\r      make DES_ENC=asm/dx86-out.o CC=gcc CFLAGS="-DOUT -O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all\r\rx86-solaris:\r  make DES_ENC=asm/dx86-sol.o CFLAGS="-DSOL -O  $(OPTS) $(CFLAG)" all\r\rx86-bsdi:\r make DES_ENC=asm/dx86bsdi.o CC=gcc CFLAGS="-DBSDI -O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all\r\rasm/dx86-elf.o: asm/dx86-cpp.s asm/dx86unix.cpp\r      $(CPP) -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o\r\rasm/dx86-sol.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o\r\rasm/dx86-out.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o\r\rasm/dx86bsdi.o: asm/dx86-cpp.s asm/dx86unix.cpp\r  $(CPP) -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o\r\rtest:    all\r    ./destest\r\r$(DLIB): $(OBJS)\r    /bin/rm -f $(DLIB)\r     ar cr $(DLIB) $(OBJS)\r  -if test -s /bin/ranlib; then /bin/ranlib $(DLIB); \\r   else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(DLIB); \\r       else exit 0; fi; fi\r\rdes_opts: des_opts.o libdes.a\r     $(CC) $(CFLAGS) -o des_opts des_opts.o libdes.a\r\rdestest: destest.o libdes.a\r   $(CC) $(CFLAGS) -o destest destest.o libdes.a\r\rrpw: rpw.o libdes.a\r     $(CC) $(CFLAGS) -o rpw rpw.o libdes.a\r\rspeed: speed.o libdes.a\r $(CC) $(CFLAGS) -o speed speed.o libdes.a\r\rdes: des.o libdes.a\r $(CC) $(CFLAGS) -o des des.o libdes.a\r\rtags:\r   ctags $(DES) $(TESTING) $(LIBDES)\r\rtar_lit:\r    /bin/mv Makefile Makefile.tmp\r  /bin/cp Makefile.lit Makefile\r  tar chf libdes-l.tar $(LIBDES_LIT) $(HEADERS_LIT) \\r            $(GENERAL_LIT) $(TESTING_LIT)\r  /bin/rm -f Makefile\r    /bin/mv Makefile.tmp Makefile\r\rtar:\r    tar chf libdes.tar $(ALL)\r\rshar:\r       shar $(ALL) >libdes.shar\r\rdepend:\r      makedepend $(LIBDES) $(DES) $(TESTING)\r\rclean:\r /bin/rm -f *.o tags core rpw destest des speed $(DLIB) .nfs* *.old \\r   *.bak destest rpw des_opts asm/*.o \r\rdclean:\r   sed -e '/^# DO NOT DELETE THIS LINE/ q' Makefile >Makefile.new\r mv -f Makefile.new Makefile\r\r# Eric is probably going to choke when he next looks at this --tjh\rinstall: $(DLIB) des\r   if test $(INSTALLTOP); then \\r      echo SSL style install; \\r      cp $(DLIB) $(INSTALLTOP)/lib; \\r        if test -s /bin/ranlib; then \\r             /bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \\r           else \\r             if test -s /usr/bin/ranlib; then \\r             /usr/bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \\r       fi; fi; \\r      chmod 644 $(INSTALLTOP)/lib/$(DLIB); \\r         cp des.h $(INSTALLTOP)/include; \\r      chmod 644 $(INSTALLTOP)/include/des.h; \\r       cp des $(INSTALLTOP)/bin; \\r            chmod 755 $(INSTALLTOP)/bin/des; \\r else \\r     echo Standalone install; \\r     cp $(DLIB) $(LIBDIR)/$(DLIB); \\r        if test -s /bin/ranlib; then \\r           /bin/ranlib $(LIBDIR)/$(DLIB); \\r     else \\r           if test -s /usr/bin/ranlib; then \\r               /usr/bin/ranlib $(LIBDIR)/$(DLIB); \\r         fi; \\r        fi; \\r          chmod 644 $(LIBDIR)/$(DLIB); \\r         cp des $(BINDIR)/des; \\r        chmod 711 $(BINDIR)/des; \\r     cp des_crypt.man $(MANDIR)/man$(MAN3)/des_crypt.$(MAN3); \\r     chmod 644 $(MANDIR)/man$(MAN3)/des_crypt.$(MAN3); \\r            cp des.man $(MANDIR)/man$(MAN1)/des.$(MAN1); \\r         chmod 644 $(MANDIR)/man$(MAN1)/des.$(MAN1); \\r          cp des.h $(INCDIR)/des.h; \\r            chmod 644 $(INCDIR)/des.h; \\r       fi\r# DO NOT DELETE THIS LINE -- make depend depends on it.\r
\ No newline at end of file
diff --git a/mac/libdes/src/PC1 b/mac/libdes/src/PC1
new file mode 100755 (executable)
index 0000000..a6ea13d
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r@PC1=(  57,49,41,33,25,17, 9,\r   1,58,50,42,34,26,18,\r  10, 2,59,51,43,35,27,\r  19,11, 3,60,52,44,36,\r  "-","-","-","-",\r       63,55,47,39,31,23,15,\r   7,62,54,46,38,30,22,\r  14, 6,61,53,45,37,29,\r  21,13, 5,28,20,12, 4,\r  "-","-","-","-",\r       );\r\rforeach (@PC1)\r     {\r      if ($_ ne "-")\r         {\r              $_--;\r          $_=int($_/8)*8+7-($_%8);\r               printf "%2d  ",$_;\r             }\r      else\r           { print "--  "; }\r      print "\n" if (((++$i) % 8) == 0);\r     print "\n" if ((($i) % 32) == 0);\r      }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/PC2 b/mac/libdes/src/PC2
new file mode 100755 (executable)
index 0000000..3256041
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r@PC2_C=(14,17,11,24, 1, 5,\r      3,28,15, 6,21,10,\r     23,19,12, 4,26, 8,\r     16, 7,27,20,13, 2,\r     );\r\r@PC2_D=(41,52,31,37,47,55,\r 30,40,51,45,33,48,\r     44,49,39,56,34,53,\r     46,42,50,36,29,32,\r     );\r\rforeach (@PC2_C) {\r if ($_ ne "-")\r         {\r              $_--;\r          printf "%2d  ",$_; }\r   else { print "--  "; }\r $C{$_}=1;\r      print "\n" if (((++$i) % 8) == 0);\r     }\r$i=0;\rprint "\n";\rforeach (@PC2_D) {\r if ($_ ne "-")\r         {\r              $_-=29;\r                printf "%2d  ",$_; }\r   else { print "--  "; }\r $D{$_}=1;\r      print "\n" if (((++$i) % 8) == 0); }\r\rprint "\n";\rforeach $i (0 .. 27)\r {\r      $_=$C{$i};\r     if ($_ ne "-") {printf "%2d ",$_;}\r     else { print "--  "; }\r print "\n" if (((++$i) % 8) == 0);\r     }\rprint "\n";\r\rprint "\n";\rforeach $i (0 .. 27)\r        {\r      $_=$D{$i};\r     if ($_ ne "-") {printf "%2d  ",$_;}\r    else { print "--  "; }\r print "\n" if (((++$i) % 8) == 0);\r     }\rprint "\n";\rsub numsort\r      {\r      $a-$b;\r }\r
\ No newline at end of file
diff --git a/mac/libdes/src/README b/mac/libdes/src/README
new file mode 100755 (executable)
index 0000000..a72b0d0
--- /dev/null
@@ -0,0 +1 @@
+\r              libdes, Version 4.01 13-Jan-97\r\r                Copyright (c) 1997, Eric Young\r                   All rights reserved.\r\r    This program is free software; you can redistribute it and/or modify\r    it under the terms specified in COPYRIGHT.\r    \r--\rThe primary ftp site for this library is\rftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz\rlibdes is now also shipped with SSLeay.  Primary ftp site of\rftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz\r\rThe best way to build this library is to build it as part of SSLeay.\r\rThis kit builds a DES encryption library and a DES encryption program.\rIt supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,\rtriple cfb, desx, and MIT's pcbc encryption modes and also has a fast\rimplementation of crypt(3).\rIt contains support routines to read keys from a terminal,\rgenerate a random key, generate a key from an arbitrary length string,\rread/write encrypted data from/to a file descriptor.\r\rThe implementation was written so as to conform with the manual entry\rfor the des_crypt(3) library routines from MIT's project Athena.\r\rdestest should be run after compilation to test the des routines.\rrpw should be run after compilation to test the read password routines.\rThe des program is a replacement for the sun des command.  I believe it\rconforms to the sun version.\r\rThe Imakefile is setup for use in the kerberos distribution.\r\rThese routines are best compiled with gcc or any other good\roptimising compiler.\rJust turn you optimiser up to the highest settings and run destest\rafter the build to make sure everything works.\r\rI believe these routines are close to the fastest and most portable DES\rroutines that use small lookup tables (4.5k) that are publicly available.\rThe fcrypt routine is faster than ufc's fcrypt (when compiling with\rgcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines\r(on a sun3/260 168 vs 336).  It is a function of CPU on chip cache size.\r[ 10-Jan-97 and a function of an incorrect speed testing program in\r  ufc which gave much better test figures that reality ].\r\rIt is worth noting that on sparc and Alpha CPUs, performance of the DES\rlibrary can vary by upto %10 due to the positioning of files after application\rlinkage.\r\rEric Young (eay@mincom.oz.au)\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/VERSION b/mac/libdes/src/VERSION
new file mode 100755 (executable)
index 0000000..110bb61
--- /dev/null
@@ -0,0 +1 @@
+Version 4.01 14/01/97\r Even faster inner loop in the DES assember for x86 and a modification\r  for IP/FP which is faster on x86.  Both of these changes are\r   from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>.  His\r changes make the assember run %40 faster on a pentium.  This is just\r   a case of getting the instruction sequence 'just right'.\r       All credit to 'Svend' :-)\r      Quite a few special x86 'make' targets.\r        A libdes-l (lite) distribution.\r\rVersion 4.00\r  After a bit of a pause, I'll up the major version number since this\r    is mostly a performace release.  I've added x86 assember and\r   added more options for performance.  A %28 speedup for gcc \r    on a pentium and the assember is a %50 speedup.\r        MIPS CPU's, sparc and Alpha are the main CPU's with speedups.\r  Run des_opts to work out which options should be used.\r DES_RISC1/DES_RISC2 use alternative inner loops which use\r      more registers but should give speedups on any CPU that does\r   dual issue (pentium).  DES_UNROLL unrolls the inner loop,\r      which costs in code size.\r\rVersion 3.26\r        I've finally removed one of the shifts in D_ENCRYPT.  This\r     meant I've changed the des_SPtrans table (spr.h), the set_key()\r        function and some things in des_enc.c.  This has definitly\r     made things faster :-).  I've known about this one for some\r    time but I've been too lazy to follow it up :-).\r       Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..\r  instead of L^=((..)|(..)|(..)..  This should save a register at\r        least.\r Assember for x86.  The file to replace is des_enc.c, which is replaced\r by one of the assember files found in asm.  Look at des/asm/readme\r     for more info.\r\r        /* Modification to fcrypt so it can be compiled to support\r     HPUX 10.x's long password format, define -DLONGCRYPT to use this.\r      Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */\r\r     SIGWINCH case put in des_read_passwd() so the function does not\r        'exit' if this function is recieved.\r\rVersion 3.25 17/07/96\r    Modified read_pwd.c so that stdin can be read if not a tty.\r    Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.\r des_init_random_number_generator() shortened due to VMS linker\r limits.\r        Added RSA's DESX cbc mode.  It is a form of cbc encryption, with 2\r     8 byte quantites xored before and after encryption.\r    des_xcbc_encryption() - the name is funny to preserve the des_\r prefix on all functions.\r\rVersion 3.24 20/04/96\r        The DES_PTR macro option checked and used by SSLeay configuration\r\rVersion 3.23 11/04/96\r       Added DES_LONG.  If defined to 'unsigned int' on the DEC Alpha,\r        it gives a %20 speedup :-)\r     Fixed the problem with des.pl under perl5.  The patches were\r   sent by Ed Kubaitis (ejk@uiuc.edu).\r    if fcrypt.c, changed values to handle illegal salt values the way\r      normal crypt() implementations do.  Some programs apparently use\r       them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>\r\rVersion 3.22 29/11/95\r     Bug in des(1), an error with the uuencoding stuff when the\r     'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>\r   for the patch.\r\rVersion 3.21 22/11/95\r  After some emailing back and forth with \r       Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things\r and in a future version I will probably put in some of the\r     optimisation he suggested for use with the DES_USE_PTR option.\r Extra routines from Mark Murray <mark@grondar.za> for use in\r   freeBSD.  They mostly involve random number generation for use\r with kerberos.  They involve evil machine specific system calls\r        etc so I would normally suggest pushing this stuff into the\r    application and/or using RAND_seed()/RAND_bytes() if you are\r   using this DES library as part of SSLeay.\r      Redone the read_pw() function so that it is cleaner and\r        supports termios, thanks to Sameer Parekh <sameer@c2.org>\r      for the initial patches for this.\r      Renamed 3ecb_encrypt() to ecb3_encrypt().  This has been\r        done just to make things more consistent.\r     I have also now added triple DES versions of cfb and ofb.\r\rVersion 3.20\r        Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,\r     my des_random_seed() function was only copying 4 bytes of the\r  passed seed into the init structure.  It is now fixed to copy 8.\r       My own suggestion is to used something like MD5 :-)\r\rVersion 3.19 \r     While looking at my code one day, I though, why do I keep on\r   calling des_encrypt(in,out,ks,enc) when every function that\r    calls it has in and out the same.  So I dropped the 'out'\r      parameter, people should not be using this function.\r\rVersion 3.18 30/08/95\r    Fixed a few bit with the distribution and the filenames.\r       3.17 had been munged via a move to DOS and back again.\r NO CODE CHANGES\r\rVersion 3.17 14/07/95\r Fixed ede3 cbc which I had broken in 3.16.  I have also\r        removed some unneeded variables in 7-8 of the routines.\r\rVersion 3.16 26/06/95\r Added des_encrypt2() which does not use IP/FP, used by triple\r  des routines.  Tweaked things a bit elsewhere. %13 speedup on\r  sparc and %6 on a R4400 for ede3 cbc mode.\r\rVersion 3.15 06/06/95\r      Added des_ncbc_encrypt(), it is des_cbc mode except that it is\r 'normal' and copies the new iv value back over the top of the\r  passed parameter.\r      CHANGED des_ede3_cbc_encrypt() so that it too now overwrites\r   the iv.  THIS WILL BREAK EXISTING CODE, but since this function\r        only new, I feel I can change it, not so with des_cbc_encrypt :-(.\r     I need to update the documentation.\r\rVersion 3.14 31/05/95\r     New release upon the world, as part of my SSL implementation.\r  New copyright and usage stuff.  Basically free for all to use\r  as long as you say it came from me :-)\r\rVersion 3.13 31/05/95\r  A fix in speed.c, if HZ is not defined, I set it to 100.0\r      which is reasonable for most unixes except SunOS 4.x.\r  I now have a #ifdef sun but timing for SunOS 4.x looked very\r   good :-(.  At my last job where I used SunOS 4.x, it was\r       defined to be 60.0 (look at the old INSTALL documentation), at\r the last release had it changed to 100.0 since I now work with\r Solaris2 and SVR4 boxes.\r       Thanks to  Rory Chisholm <rchishol@math.ethz.ch> for pointing this\r     one out.\r\rVersion 3.12 08/05/95\r        As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,\r        my D_ENCRYPT macro in crypt() had an un-necessary variable.\r    It has been removed.\r\rVersion 3.11 03/05/95\r    Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys\r and one iv.  It is a standard and I needed it for my SSL code.\r It makes more sense to use this for triple DES than\r    3cbc_encrypt().  I have also added (or should I say tested :-)\r cfb64_encrypt() which is cfb64 but it will encrypt a partial\r   number of bytes - 3 bytes in 3 bytes out.  Again this is for\r   my SSL library, as a form of encryption to use with SSL\r        telnet.\r\rVersion 3.10 22/03/95\r Fixed a bug in 3cbc_encrypt() :-(.  When making repeated calls\r to cbc3_encrypt, the 2 iv values that were being returned to\r   be used in the next call were reversed :-(.\r    Many thanks to Bill Wade <wade@Stoner.COM> for pointing out\r    this error.\r\rVersion 3.09 01/02/95\r     Fixed des_random_key to far more random, it was rather feeble\r  with regards to picking the initial seed.  The problem was\r     pointed out by Olaf Kirch <okir@monad.swb.de>.\r\rVersion 3.08 14/12/94\r  Added Makefile.PL so libdes can be built into perl5.\r   Changed des_locl.h so RAND is always defined.\r\rVersion 3.07 05/12/94\r   Added GNUmake and stuff so the library can be build with\r       glibc.\r\rVersion 3.06 30/08/94\r  Added rpc_enc.c which contains _des_crypt.  This is for use in\r secure_rpc v 4.0\r       Finally fixed the cfb_enc problems.\r    Fixed a few parameter parsing bugs in des (-3 and -b), thanks\r  to Rob McMillan <R.McMillan@its.gu.edu.au>\r\rVersion 3.05 21/04/94\r      for unsigned long l; gcc does not produce ((l>>34) == 0)\r       This causes bugs in cfb_enc.\r   Thanks to Hadmut Danisch <danisch@ira.uka.de>\r\rVersion 3.04 20/04/94\r   Added a version number to des.c and libdes.a\r\rVersion 3.03 12/01/94\r    Fixed a bug in non zero iv in 3cbc_enc.\r\rVersion 3.02 29/10/93\r I now work in a place where there are 6+ architectures and 14+\r OS versions :-).\r       Fixed TERMIO definition so the most sys V boxes will work :-)\r\rRelease upon comp.sources.misc\rVersion 3.01 08/10/93\r    Added des_3cbc_encrypt()\r\rVersion 3.00 07/10/93\r        Fixed up documentation.\r        quad_cksum definitely compatible with MIT's now.\r\rVersion 2.30 24/08/93\r        Triple DES now defaults to triple cbc but can do triple ecb\r     with the -b flag.\r     Fixed some MSDOS uuen/uudecoding problems, thanks to\r   Added prototypes.\r      \rVersion 2.22 29/06/93\r Fixed a bug in des_is_weak_key() which stopped it working :-(\r  thanks to engineering@MorningStar.Com.\r\rVersion 2.21 03/06/93\r  des(1) with no arguments gives quite a bit of help.\r    Added -c (generate ckecksum) flag to des(1).\r   Added -3 (triple DES) flag to des(1).\r  Added cfb and ofb routines to the library.\r\rVersion 2.20 11/03/93\r      Added -u (uuencode) flag to des(1).\r    I have been playing with byte order in quad_cksum to make it\r    compatible with MIT's version.  All I can say is avid this\r     function if possible since MIT's output is endian dependent.\r\rVersion 2.12 14/10/92\r   Added MSDOS specific macro in ecb_encrypt which gives a %70\r     speed up when the code is compiled with turbo C.\r\rVersion 2.11 12/10/92\r       Speedup in set_key (recoding of PC-1)\r   I now do it in 47 simple operations, down from 60.\r     Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)\r   for motivating me to look for a faster system :-)\r      The speedup is probably less that 1% but it is still 13\r        instructions less :-).\r\rVersion 2.10 06/10/92\r The code now works on the 64bit ETA10 and CRAY without modifications or\r         #defines.  I believe the code should work on any machine that\r  defines long, int or short to be 8 bytes long.\r        Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)\r       for helping me fix the code to run on 64bit machines (he had\r   access to an ETA10).\r  Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>\r       for testing the routines on a CRAY.\r   read_password.c has been renamed to read_passwd.c\r      string_to_key.c has been renamed to string2key.c\r\rVersion 2.00 14/09/92\r        Made mods so that the library should work on 64bit CPU's.\r      Removed all my uchar and ulong defs.  To many different\r         versions of unix define them in their header files in too many\r         different combinations :-)\r    IRIX - Sillicon Graphics mods (mostly in read_password.c).\r      Thanks to Andrew Daviel (advax@erich.triumf.ca)\r\rVersion 1.99 26/08/92\r        Fixed a bug or 2 in enc_read.c\r Fixed a bug in enc_write.c\r     Fixed a pseudo bug in fcrypt.c (very obscure).\r\rVersion 1.98 31/07/92\r  Support for the ETA10.  This is a strange machine that defines\r longs and ints as 8 bytes and shorts as 4 bytes.\r       Since I do evil things with long * that assume that they are 4\r bytes.  Look in the Makefile for the option to compile for\r     this machine.  quad_cksum appears to have problems but I\r       will don't have the time to fix it right now, and this is not\r  a function that uses DES and so will not effect the main uses\r  of the library.\r\rVersion 1.97 20/05/92 eay\r     Fixed the Imakefile and made some changes to des.h to fix some\r problems when building this package with Kerberos v 4.\r\rVersion 1.96 18/05/92 eay\r      Fixed a small bug in string_to_key() where problems could\r      occur if des_check_key was set to true and the string\r  generated a weak key.\r\rPatch2 posted to comp.sources.misc\rVersion 1.95 13/05/92 eay\r    Added an alternative version of the D_ENCRYPT macro in\r ecb_encrypt and fcrypt.  Depending on the compiler, one version or the\r other will be faster.  This was inspired by \r   Dana How <how@isl.stanford.edu>, and her pointers about doing the\r      *(ulong *)((uchar *)ptr+(value&0xfc))\r  vs\r     ptr[value&0x3f]\r        to stop the C compiler doing a <<2 to convert the long array index.\r\rVersion 1.94 05/05/92 eay\r Fixed an incompatibility between my string_to_key and the MIT\r   version.  When the key is longer than 8 chars, I was wrapping\r  with a different method.  To use the old version, define\r       OLD_STR_TO_KEY in the makefile.  Thanks to\r     viktor@newsu.shearson.com (Viktor Dukhovni).\r\rVersion 1.93 28/04/92 eay\r       Fixed the VMS mods so that echo is now turned off in\r    read_password.  Thanks again to brennan@coco.cchs.su.oz.AU.\r   MSDOS support added.  The routines can be compiled with\r         Turbo C (v2.0) and MSC (v5.1).  Make sure MSDOS is defined.\r\rPatch1 posted to comp.sources.misc\rVersion 1.92 13/04/92 eay\r     Changed D_ENCRYPT so that the rotation of R occurs outside of\r   the loop.  This required rotating all the longs in sp.h (now\r   called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>\r       speed.c has been changed so it will work without SIGALRM.  If\r   times(3) is not present it will try to use ftime() instead.\r\rVersion 1.91 08/04/92 eay\r        Added -E/-D options to des(1) so it can use string_to_key.\r     Added SVR4 mods suggested by witr@rwwa.COM\r     Added VMS mods suggested by brennan@coco.cchs.su.oz.AU.  If\r    anyone knows how to turn of tty echo in VMS please tell me or\r  implement it yourself :-).\r     Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS\r does not like IN/OUT being used.\r\rLibdes posted to comp.sources.misc\rVersion 1.9 24/03/92 eay\r  Now contains a fast small crypt replacement.\r   Added des(1) command.\r  Added des_rw_mode so people can use cbc encryption with\r        enc_read and enc_write.\r\rVersion 1.8 15/10/91 eay\r      Bug in cbc_cksum.\r      Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this\r       one out.\r\rVersion 1.7 24/09/91 eay\r     Fixed set_key :-)\r      set_key is 4 times faster and takes less space.\r        There are a few minor changes that could be made.\r\rVersion 1.6 19/09/1991 eay\r  Finally go IP and FP finished.\r Now I need to fix set_key.\r     This version is quite a bit faster that 1.51\r\rVersion 1.52 15/06/1991 eay\r      20% speedup in ecb_encrypt by changing the E bit selection\r     to use 2 32bit words.  This also required modification of the\r  sp table.  There is still a way to speedup the IP and IP-1\r     (hints from outer@sq.com) still working on this one :-(.\r\rVersion 1.51 07/06/1991 eay\r  Faster des_encrypt by loop unrolling\r   Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)\r\rVersion 1.50 28/05/1991 eay\r        Optimised the code a bit more for the sparc.  I have improved the\r      speed of the inner des_encrypt by speeding up the initial and\r  final permutations.\r\rVersion 1.40 23/10/1990 eay\r       Fixed des_random_key, it did not produce a random key :-(\r\rVersion 1.30  2/10/1990 eay\r Have made des_quad_cksum the same as MIT's, the full package\r   should be compatible with MIT's\r        Have tested on a DECstation 3100\r       Still need to fix des_set_key (make it faster).\r        Does des_cbc_encrypts at 70.5k/sec on a 3100.\r\rVersion 1.20 18/09/1990 eay\r     Fixed byte order dependencies.\r Fixed (I hope) all the word alignment problems.\r        Speedup in des_ecb_encrypt.\r\rVersion 1.10 11/09/1990 eay\r       Added des_enc_read and des_enc_write.\r  Still need to fix des_quad_cksum.\r      Still need to document des_enc_read and des_enc_write.\r\rVersion 1.00 27/08/1990 eay\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/cbc3_enc.c b/mac/libdes/src/cbc3_enc.c
new file mode 100755 (executable)
index 0000000..1f5b235
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cbc3_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* HAS BUGS? DON'T USE */\rvoid des_3cbc_encrypt(input, output, length, ks1, ks2, iv1, iv2, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_cblock (*iv1);\rdes_cblock (*iv2);\rint encrypt;\r    {\r      int off=((int)length-1)/8;\r     long l8=((length+7)/8)*8;\r      des_cblock niv1,niv2;\r\r if (encrypt == DES_ENCRYPT)\r            {\r              des_cbc_encrypt(input,output,length,ks1,iv1,encrypt);\r          if (length >= sizeof(des_cblock))\r                      memcpy(niv1,output[off],sizeof(des_cblock));\r           des_cbc_encrypt(output,output,l8,ks2,iv1,!encrypt);\r            des_cbc_encrypt(output,output,l8,ks1,iv2, encrypt);\r            if (length >= sizeof(des_cblock))\r                      memcpy(niv2,output[off],sizeof(des_cblock));\r           }\r      else\r           {\r              if (length >= sizeof(des_cblock))\r                      memcpy(niv2,input[off],sizeof(des_cblock));\r            des_cbc_encrypt(input,output,l8,ks1,iv2,encrypt);\r              des_cbc_encrypt(output,output,l8,ks2,iv1,!encrypt);\r            if (length >= sizeof(des_cblock))\r                      memcpy(niv1,output[off],sizeof(des_cblock));\r           des_cbc_encrypt(output,output,length,ks1,iv1, encrypt);\r                }\r      memcpy(*iv1,niv1,sizeof(des_cblock));\r  memcpy(*iv2,niv2,sizeof(des_cblock));\r  }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/cbc_cksm.c b/mac/libdes/src/cbc_cksm.c
new file mode 100755 (executable)
index 0000000..bed308b
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cbc_cksm.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rDES_LONG des_cbc_cksum(input, output, length, schedule, ivec)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\r  {\r      register DES_LONG tout0,tout1,tin0,tin1;\r       register long l=length;\r        DES_LONG tin[2];\r       unsigned char *in,*out,*iv;\r\r   in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     c2l(iv,tout0);\r c2l(iv,tout1);\r for (; l>0; l-=8)\r              {\r              if (l >= 8)\r                    {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r                  }\r              else\r                   c2ln(in,tin0,tin1,l);\r                  \r               tin0^=tout0; tin[0]=tin0;\r              tin1^=tout1; tin[1]=tin1;\r              des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r             /* fix 15/10/91 eay - thanks to keithr@sco.COM */\r              tout0=tin[0];\r          tout1=tin[1];\r          }\r      if (out != NULL)\r               {\r              l2c(tout0,out);\r                l2c(tout1,out);\r                }\r      tout0=tin0=tin1=tin[0]=tin[1]=0;\r       return(tout1);\r }\r
\ No newline at end of file
diff --git a/mac/libdes/src/cbc_enc.c b/mac/libdes/src/cbc_enc.c
new file mode 100755 (executable)
index 0000000..dd79911
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cbc_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_cbc_encrypt(input, output, length, schedule, ivec, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint encrypt;\r       {\r      register DES_LONG tin0,tin1;\r   register DES_LONG tout0,tout1,xor0,xor1;\r       register unsigned char *in,*out;\r       register long l=length;\r        DES_LONG tin[2];\r       unsigned char *iv;\r\r    in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     if (encrypt)\r           {\r              c2l(iv,tout0);\r         c2l(iv,tout1);\r         for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r                  tin0^=tout0; tin[0]=tin0;\r                      tin1^=tout1; tin[1]=tin1;\r                      des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]; l2c(tout0,out);\r                  tout1=tin[1]; l2c(tout1,out);\r                  }\r              if (l != -8)\r                   {\r                      c2ln(in,tin0,tin1,l+8);\r                        tin0^=tout0; tin[0]=tin0;\r                      tin1^=tout1; tin[1]=tin1;\r                      des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]; l2c(tout0,out);\r                  tout1=tin[1]; l2c(tout1,out);\r                  }\r              }\r      else\r           {\r              c2l(iv,xor0);\r          c2l(iv,xor1);\r          for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0); tin[0]=tin0;\r                     c2l(in,tin1); tin[1]=tin1;\r                     des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0;\r                     tout1=tin[1]^xor1;\r                     l2c(tout0,out);\r                        l2c(tout1,out);\r                        xor0=tin0;\r                     xor1=tin1;\r                     }\r              if (l != -8)\r                   {\r                      c2l(in,tin0); tin[0]=tin0;\r                     c2l(in,tin1); tin[1]=tin1;\r                     des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0;\r                     tout1=tin[1]^xor1;\r                     l2cn(tout0,tout1,out,l+8);\r             /*      xor0=tin0;\r                     xor1=tin1; */\r                  }\r              }\r      tin0=tin1=tout0=tout1=xor0=xor1=0;\r     tin[0]=tin[1]=0;\r       }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/cfb64ede.c b/mac/libdes/src/cfb64ede.c
new file mode 100755 (executable)
index 0000000..4ece765
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cfb64ede.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output encrypted as though 64bit cfb mode is being\r * used.  The extra state information to record how much of the\r * 64bit block we have used is contained in *num;\r */\r\rvoid des_ede3_cfb64_encrypt(in, out, length, ks1,ks2,ks3, ivec, num, encrypt)\runsigned char *in;\runsigned char *out;\rlong length;\rdes_key_schedule ks1,ks2,ks3;\rdes_cblock (*ivec);\rint *num;\rint encrypt;\r {\r      register DES_LONG v0,v1;\r       register long l=length;\r        register int n= *num;\r  DES_LONG ti[2];\r        unsigned char *iv,c,cc;\r\r       iv=(unsigned char *)ivec;\r      if (encrypt)\r           {\r              while (l--)\r                    {\r                      if (n == 0)\r                            {\r                              c2l(iv,v0);\r                            c2l(iv,v1);\r\r                           ti[0]=v0;\r                              ti[1]=v1;\r                              des_encrypt3((DES_LONG *)ti,ks1,ks2,ks3);\r                              v0=ti[0];\r                              v1=ti[1];\r\r                             iv=(unsigned char *)ivec;\r                              l2c(v0,iv);\r                            l2c(v1,iv);\r                            iv=(unsigned char *)ivec;\r                              }\r                      c= *(in++)^iv[n];\r                      *(out++)=c;\r                    iv[n]=c;\r                       n=(n+1)&0x07;\r                  }\r              }\r      else\r           {\r              while (l--)\r                    {\r                      if (n == 0)\r                            {\r                              c2l(iv,v0);\r                            c2l(iv,v1);\r\r                           ti[0]=v0;\r                              ti[1]=v1;\r                              des_encrypt3((DES_LONG *)ti,ks1,ks2,ks3);\r                              v0=ti[0];\r                              v1=ti[1];\r\r                             iv=(unsigned char *)ivec;\r                              l2c(v0,iv);\r                            l2c(v1,iv);\r                            iv=(unsigned char *)ivec;\r                              }\r                      cc= *(in++);\r                   c=iv[n];\r                       iv[n]=cc;\r                      *(out++)=c^cc;\r                 n=(n+1)&0x07;\r                  }\r              }\r      v0=v1=ti[0]=ti[1]=c=cc=0;\r      *num=n;\r        }\r\r#ifdef undef /* MACRO */\rvoid des_ede2_cfb64_encrypt(in, out, length, ks1,ks2, ivec, num, encrypt)\runsigned char *in;\runsigned char *out;\rlong length;\rdes_key_schedule ks1,ks2;\rdes_cblock (*ivec);\rint *num;\rint encrypt;\r {\r      des_ede3_cfb64_encrypt(in,out,length,ks1,ks2,ks1,ivec,num,encrypt);\r    }\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/cfb64enc.c b/mac/libdes/src/cfb64enc.c
new file mode 100755 (executable)
index 0000000..20caaf2
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cfb64enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output encrypted as though 64bit cfb mode is being\r * used.  The extra state information to record how much of the\r * 64bit block we have used is contained in *num;\r */\r\rvoid des_cfb64_encrypt(in, out, length, schedule, ivec, num, encrypt)\runsigned char *in;\runsigned char *out;\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint *num;\rint encrypt;\r    {\r      register DES_LONG v0,v1;\r       register long l=length;\r        register int n= *num;\r  DES_LONG ti[2];\r        unsigned char *iv,c,cc;\r\r       iv=(unsigned char *)ivec;\r      if (encrypt)\r           {\r              while (l--)\r                    {\r                      if (n == 0)\r                            {\r                              c2l(iv,v0); ti[0]=v0;\r                          c2l(iv,v1); ti[1]=v1;\r                          des_encrypt((DES_LONG *)ti,\r                                    schedule,DES_ENCRYPT);\r                         iv=(unsigned char *)ivec;\r                              v0=ti[0]; l2c(v0,iv);\r                          v0=ti[1]; l2c(v0,iv);\r                          iv=(unsigned char *)ivec;\r                              }\r                      c= *(in++)^iv[n];\r                      *(out++)=c;\r                    iv[n]=c;\r                       n=(n+1)&0x07;\r                  }\r              }\r      else\r           {\r              while (l--)\r                    {\r                      if (n == 0)\r                            {\r                              c2l(iv,v0); ti[0]=v0;\r                          c2l(iv,v1); ti[1]=v1;\r                          des_encrypt((DES_LONG *)ti,\r                                    schedule,DES_ENCRYPT);\r                         iv=(unsigned char *)ivec;\r                              v0=ti[0]; l2c(v0,iv);\r                          v0=ti[1]; l2c(v0,iv);\r                          iv=(unsigned char *)ivec;\r                              }\r                      cc= *(in++);\r                   c=iv[n];\r                       iv[n]=cc;\r                      *(out++)=c^cc;\r                 n=(n+1)&0x07;\r                  }\r              }\r      v0=v1=ti[0]=ti[1]=c=cc=0;\r      *num=n;\r        }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/cfb_enc.c b/mac/libdes/src/cfb_enc.c
new file mode 100755 (executable)
index 0000000..32172e3
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/cfb_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output are loaded in multiples of 8 bits.\r * What this means is that if you hame numbits=12 and length=2\r * the first 12 bits will be retrieved from the first byte and half\r * the second.  The second 12 bits will come from the 3rd and half the 4th\r * byte.\r */\rvoid des_cfb_encrypt(in, out, numbits, length, schedule, ivec, encrypt)\runsigned char *in;\runsigned char *out;\rint numbits;\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint encrypt;\r     {\r      register DES_LONG d0,d1,v0,v1,n=(numbits+7)/8;\r register DES_LONG mask0,mask1;\r register unsigned long l=length;\r       register int num=numbits;\r      DES_LONG ti[2];\r        unsigned char *iv;\r\r    if (num > 64) return;\r  if (num > 32)\r          {\r              mask0=0xffffffffL;\r             if (num == 64)\r                 mask1=mask0;\r           else    mask1=(1L<<(num-32))-1;\r                }\r      else\r           {\r              if (num == 32)\r                 mask0=0xffffffffL;\r             else    mask0=(1L<<num)-1;\r             mask1=0x00000000;\r              }\r\r     iv=(unsigned char *)ivec;\r      c2l(iv,v0);\r    c2l(iv,v1);\r    if (encrypt)\r           {\r              while (l >= n)\r                 {\r                      l-=n;\r                  ti[0]=v0;\r                      ti[1]=v1;\r                      des_encrypt((DES_LONG *)ti,schedule,DES_ENCRYPT);\r                      c2ln(in,d0,d1,n);\r                      in+=n;\r                 d0=(d0^ti[0])&mask0;\r                   d1=(d1^ti[1])&mask1;\r                   l2cn(d0,d1,out,n);\r                     out+=n;\r                        /* 30-08-94 - eay - changed because l>>32 and\r                   * l<<32 are bad under gcc :-( */\r                      if (num == 32)\r                         { v0=v1; v1=d0; }\r                      else if (num == 64)\r                            { v0=d0; v1=d1; }\r                      else if (num > 32) /* && num != 64 */\r                          {\r                              v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffffL;\r                                v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffffL;\r                                }\r                      else /* num < 32 */\r                            {\r                              v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL;\r                             v1=((v1>>num)|(d0<<(32-num)))&0xffffffffL;\r                             }\r                      }\r              }\r      else\r           {\r              while (l >= n)\r                 {\r                      l-=n;\r                  ti[0]=v0;\r                      ti[1]=v1;\r                      des_encrypt((DES_LONG *)ti,schedule,DES_ENCRYPT);\r                      c2ln(in,d0,d1,n);\r                      in+=n;\r                 /* 30-08-94 - eay - changed because l>>32 and\r                   * l<<32 are bad under gcc :-( */\r                      if (num == 32)\r                         { v0=v1; v1=d0; }\r                      else if (num == 64)\r                            { v0=d0; v1=d1; }\r                      else if (num > 32) /* && num != 64 */\r                          {\r                              v0=((v1>>(num-32))|(d0<<(64-num)))&0xffffffffL;\r                                v1=((d0>>(num-32))|(d1<<(64-num)))&0xffffffffL;\r                                }\r                      else /* num < 32 */\r                            {\r                              v0=((v0>>num)|(v1<<(32-num)))&0xffffffffL;\r                             v1=((v1>>num)|(d0<<(32-num)))&0xffffffffL;\r                             }\r                      d0=(d0^ti[0])&mask0;\r                   d1=(d1^ti[1])&mask1;\r                   l2cn(d0,d1,out,n);\r                     out+=n;\r                        }\r              }\r      iv=(unsigned char *)ivec;\r      l2c(v0,iv);\r    l2c(v1,iv);\r    v0=v1=d0=d1=ti[0]=ti[1]=0;\r     }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.c b/mac/libdes/src/des.c
new file mode 100755 (executable)
index 0000000..12284c5
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\r#endif\r\r#include <stdio.h>\r#include <stdlib.h>\r#include <string.h>\r#ifdef HAVE_UNISTD_H\r#include <unistd.h>\r#endif\r#ifdef HAVE_IO_H\r#include <io.h>\r#endif\r\r#include <time.h>\r#include "des_ver.h"\r\r#ifdef VMS\r#include <types.h>\r#include <stat.h>\r#endif\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r#ifdef HAVE_SYS_STAT_H\r#include <sys/stat.h>\r#endif\r#include "des.h"\r\r#ifndef HAVE_RANDOM\r#define random rand\r#define srandom(s) srand(s)\r#endif\r\r#ifndef NOPROTO\rvoid usage(void);\rvoid doencryption(void);\rint uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);\rvoid uufwriteEnd(FILE *fp);\rint uufread(unsigned char *out,int size,unsigned int num,FILE *fp);\rint uuencode(unsigned char *in,int num,unsigned char *out);\rint uudecode(unsigned char *in,int num,unsigned char *out);\r#else\rvoid usage();\rvoid doencryption();\rint uufwrite();\rvoid uufwriteEnd();\rint uufread();\rint uuencode();\rint uudecode();\r#endif\r\r#ifdef VMS\r#define EXIT(a) exit(a&0x10000000)\r#else\r#define EXIT(a) exit(a)\r#endif\r\r#define BUFSIZE (8*1024)\r#define VERIFY  1\r#define KEYSIZ  8\r#define KEYSIZB 1024 /* should hit tty line limit first :-) */\rchar key[KEYSIZB+1];\rint do_encrypt,longk=0;\rFILE *DES_IN,*DES_OUT,*CKSUM_OUT;\rchar uuname[200];\runsigned char uubuf[50];\rint uubufnum=0;\r#define INUUBUFN     (45*100)\r#define OUTUUBUF       (65*100)\runsigned char b[OUTUUBUF];\runsigned char bb[300];\rdes_cblock cksum={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};\rchar cksumname[200]="";\r\rint vflag,cflag,eflag,dflag,kflag,bflag,fflag,sflag,uflag,flag3,hflag,error;\r\rint main(argc, argv)\rint argc;\rchar **argv;\r      {\r      int i;\r struct stat ins,outs;\r  char *p;\r       char *in=NULL,*out=NULL;\r\r      vflag=cflag=eflag=dflag=kflag=hflag=bflag=fflag=sflag=uflag=flag3=0;\r   error=0;\r       memset(key,0,sizeof(key));\r\r    for (i=1; i<argc; i++)\r         {\r              p=argv[i];\r             if ((p[0] == '-') && (p[1] != '\0'))\r                   {\r                      p++;\r                   while (*p)\r                             {\r                              switch (*(p++))\r                                        {\r                              case '3':\r                                      flag3=1;\r                                       longk=1;\r                                       break;\r                         case 'c':\r                                      cflag=1;\r                                       strncpy(cksumname,p,200);\r                                      p+=strlen(cksumname);\r                                  break;\r                         case 'C':\r                                      cflag=1;\r                                       longk=1;\r                                       strncpy(cksumname,p,200);\r                                      p+=strlen(cksumname);\r                                  break;\r                         case 'e':\r                                      eflag=1;\r                                       break;\r                         case 'v':\r                                      vflag=1;\r                                       break;\r                         case 'E':\r                                      eflag=1;\r                                       longk=1;\r                                       break;\r                         case 'd':\r                                      dflag=1;\r                                       break;\r                         case 'D':\r                                      dflag=1;\r                                       longk=1;\r                                       break;\r                         case 'b':\r                                      bflag=1;\r                                       break;\r                         case 'f':\r                                      fflag=1;\r                                       break;\r                         case 's':\r                                      sflag=1;\r                                       break;\r                         case 'u':\r                                      uflag=1;\r                                       strncpy(uuname,p,200);\r                                 p+=strlen(uuname);\r                                     break;\r                         case 'h':\r                                      hflag=1;\r                                       break;\r                         case 'k':\r                                      kflag=1;\r                                       if ((i+1) == argc)\r                                             {\r                                              fputs("must have a key with the -k option\n",stderr);\r                                          error=1;\r                                               }\r                                      else\r                                           {\r                                              int j;\r\r                                                i++;\r                                           strncpy(key,argv[i],KEYSIZB);\r                                          for (j=strlen(argv[i])-1; j>=0; j--)\r                                                   argv[i][j]='\0';\r                                               }\r                                      break;\r                         default:\r                                       fprintf(stderr,"'%c' unknown flag\n",p[-1]);\r                                   error=1;\r                                       break;\r                                 }\r                              }\r                      }\r              else\r                   {\r                      if (in == NULL)\r                                in=argv[i];\r                    else if (out == NULL)\r                          out=argv[i];\r                   else\r                           error=1;\r                       }\r              }\r      if (error) usage();\r    /* We either\r    * do checksum or\r       * do encrypt or\r        * do decrypt or\r        * do decrypt then ckecksum or\r  * do checksum then encrypt\r     */\r    if (((eflag+dflag) == 1) || cflag)\r             {\r              if (eflag) do_encrypt=DES_ENCRYPT;\r             if (dflag) do_encrypt=DES_DECRYPT;\r             }\r      else\r           {\r              if (vflag) \r                    {\r#ifndef _Windows                      \r                       fprintf(stderr,"des(1) built with %s\n",libdes_version);\r#endif                 \r                       EXIT(1);\r                       }\r              else usage();\r          }\r\r#ifndef _Windows                     \r       if (vflag) fprintf(stderr,"des(1) built with %s\n",libdes_version);\r#endif                      \r       if (    (in != NULL) &&\r                (out != NULL) &&\r#ifndef MSDOS\r         (stat(in,&ins) != -1) &&\r               (stat(out,&outs) != -1) &&\r             (ins.st_dev == outs.st_dev) &&\r         (ins.st_ino == outs.st_ino))\r#else /* MSDOS */\r         (strcmp(in,out) == 0))\r#endif\r                  {\r                      fputs("input and output file are the same\n",stderr);\r                  EXIT(3);\r                       }\r\r     if (!kflag)\r            if (des_read_pw_string(key,KEYSIZB+1,"Enter key:",eflag?VERIFY:0))\r                     {\r                      fputs("password error\n",stderr);\r                      EXIT(2);\r                       }\r\r     if (in == NULL)\r                DES_IN=stdin;\r  else if ((DES_IN=fopen(in,"r")) == NULL)\r               {\r              perror("opening input file");\r          EXIT(4);\r               }\r\r     CKSUM_OUT=stdout;\r      if (out == NULL)\r               {\r              DES_OUT=stdout;\r                CKSUM_OUT=stderr;\r              }\r      else if ((DES_OUT=fopen(out,"w")) == NULL)\r             {\r              perror("opening output file");\r         EXIT(5);\r               }\r\r#ifdef MSDOS\r        /* This should set the file to binary mode. */\r {\r#include <fcntl.h>\r   if (!(uflag && dflag))\r         setmode(fileno(DES_IN),O_BINARY);\r      if (!(uflag && eflag))\r         setmode(fileno(DES_OUT),O_BINARY);\r     }\r#endif\r\r      doencryption();\r        fclose(DES_IN);\r        fclose(DES_OUT);\r       EXIT(0);\r       }\r\rvoid usage()\r        {\r      char **u;\r      static const char *Usage[]={\r"des <options> [input-file [output-file]]",\r"options:",\r"-v         : des(1) version number",\r"-e         : encrypt using sunOS compatible user key to DES key conversion.",\r"-E         : encrypt ",\r"-d         : decrypt using sunOS compatible user key to DES key conversion.",\r"-D         : decrypt ",\r"-c[ckname] : generate a cbc_cksum using sunOS compatible user key to",\r"             DES key conversion and output to ckname (stdout default,",\r"             stderr if data being output on stdout).  The checksum is",\r"             generated before encryption and after decryption if used",\r"             in conjunction with -[eEdD].",\r"-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",\r"-k key     : use key 'key'",\r"-h         : the key that is entered will be a hexidecimal number",\r"             that is used directly as the des key",\r"-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",\r"             (uuname is the filename to put in the uuencode header).",\r"-b         : encrypt using DES in ecb encryption mode, the defaut is cbc mode.",\r"-3         : encrypt using tripple DES encryption.  This uses 2 keys",\r"             generated from the input key.  If the input key is less",\r"             than 8 characters long, this is equivelent to normal",\r"             encryption.  Default is tripple cbc, -b makes it tripple ecb.",\rNULL\r};\r   for (u=(char **)Usage; *u; u++)\r                {\r              fputs(*u,stderr);\r              fputc('\n',stderr);\r            }\r\r     EXIT(1);\r       }\r\rvoid doencryption()\r {\r#ifdef _LIBC\r extern int srandom();\r  extern int random();\r   extern unsigned long time();\r#endif\r\r   register int i;\r        des_key_schedule ks,ks2;\r       unsigned char iv[8],iv2[8];\r    char *p;\r       int num=0,j,k,l,rem,ll,len,last,ex=0;\r  des_cblock kk,k2;\r      FILE *O;\r       int Exit=0;\r#ifndef MSDOS\r      static unsigned char buf[BUFSIZE+8],obuf[BUFSIZE+8];\r#else\r     static unsigned char *buf=NULL,*obuf=NULL;\r\r    if (buf == NULL)\r               {\r              if (    (( buf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL) ||\r                 ((obuf=(unsigned char *)Malloc(BUFSIZE+8)) == NULL))\r                   {\r                      fputs("Not enough memory\n",stderr);\r                   Exit=10;\r                       goto problems;\r                 }\r              }\r#endif\r\r      if (hflag)\r             {\r              j=(flag3?16:8);\r                p=key;\r         for (i=0; i<j; i++)\r                    {\r                      k=0;\r                   if ((*p <= '9') && (*p >= '0'))\r                                k=(*p-'0')<<4;\r                 else if ((*p <= 'f') && (*p >= 'a'))\r                           k=(*p-'a'+10)<<4;\r                      else if ((*p <= 'F') && (*p >= 'A'))\r                           k=(*p-'A'+10)<<4;\r                      else\r                           {\r                              fputs("Bad hex key\n",stderr);\r                         Exit=9;\r                                goto problems;\r                         }\r                      p++;\r                   if ((*p <= '9') && (*p >= '0'))\r                                k|=(*p-'0');\r                   else if ((*p <= 'f') && (*p >= 'a'))\r                           k|=(*p-'a'+10);\r                        else if ((*p <= 'F') && (*p >= 'A'))\r                           k|=(*p-'A'+10);\r                        else\r                           {\r                              fputs("Bad hex key\n",stderr);\r                         Exit=9;\r                                goto problems;\r                         }\r                      p++;\r                   if (i < 8)\r                             kk[i]=k;\r                       else\r                           k2[i-8]=k;\r                     }\r              des_set_key((C_Block *)k2,ks2);\r                memset(k2,0,sizeof(k2));\r               }\r      else if (longk || flag3)\r               {\r              if (flag3)\r                     {\r                      des_string_to_2keys(key,(C_Block *)kk,(C_Block *)k2);\r                  des_set_key((C_Block *)k2,ks2);\r                        memset(k2,0,sizeof(k2));\r                       }\r              else\r                   des_string_to_key(key,(C_Block *)kk);\r          }\r      else\r           for (i=0; i<KEYSIZ; i++)\r                       {\r                      l=0;\r                   k=key[i];\r                      for (j=0; j<8; j++)\r                            {\r                              if (k&1) l++;\r                          k>>=1;\r                         }\r                      if (l & 1)\r                             kk[i]=key[i]&0x7f;\r                     else\r                           kk[i]=key[i]|0x80;\r                     }\r\r     des_set_key((C_Block *)kk,ks);\r memset(key,0,sizeof(key));\r     memset(kk,0,sizeof(kk));\r       /* woops - A bug that does not showup under unix :-( */\r        memset(iv,0,sizeof(iv));\r       memset(iv2,0,sizeof(iv2));\r\r    l=1;\r   rem=0;\r /* first read */\r       if (eflag || (!dflag && cflag))\r                {\r              for (;;)\r                       {\r                      num=l=fread(&(buf[rem]),1,BUFSIZE,DES_IN);\r                     l+=rem;\r                        num+=rem;\r                      if (l < 0)\r                             {\r                              perror("read error");\r                          Exit=6;\r                                goto problems;\r                         }\r\r                     rem=l%8;\r                       len=l-rem;\r                     if (feof(DES_IN))\r                              {\r                              srandom((unsigned int)time(NULL));\r                             for (i=7-rem; i>0; i--)\r                                        buf[l++]=random()&0xff;\r                                buf[l++]=rem;\r                          ex=1;\r                          len+=rem;\r                              }\r                      else\r                           l-=rem;\r\r                       if (cflag)\r                             {\r                              des_cbc_cksum((C_Block *)buf,(C_Block *)cksum,\r                                 (long)len,ks,(C_Block *)cksum);\r                                if (!eflag)\r                                    {\r                                      if (feof(DES_IN)) break;\r                                       else continue;\r                                 }\r                              }\r\r                     if (bflag && !flag3)\r                           for (i=0; i<l; i+=8)\r                                   des_ecb_encrypt(\r                                               (des_cblock *)&(buf[i]),\r                                               (des_cblock *)&(obuf[i]),\r                                              ks,do_encrypt);\r                        else if (flag3 && bflag)\r                               for (i=0; i<l; i+=8)\r                                   des_ecb2_encrypt(\r                                              (des_cblock *)&(buf[i]),\r                                               (des_cblock *)&(obuf[i]),\r                                              ks,ks2,do_encrypt);\r                    else if (flag3 && !bflag)\r                              {\r                              char tmpbuf[8];\r\r                               if (rem) memcpy(tmpbuf,&(buf[l]),\r                                      (unsigned int)rem);\r                            des_3cbc_encrypt(\r                                      (des_cblock *)buf,(des_cblock *)obuf,\r                                  (long)l,ks,ks2,(des_cblock *)iv,\r                                       (des_cblock *)iv2,do_encrypt);\r                         if (rem) memcpy(&(buf[l]),tmpbuf,\r                                      (unsigned int)rem);\r                            }\r                      else\r                           {\r                              des_cbc_encrypt(\r                                       (des_cblock *)buf,(des_cblock *)obuf,\r                                  (long)l,ks,(des_cblock *)iv,do_encrypt);\r                               if (l >= 8) memcpy(iv,&(obuf[l-8]),8);\r                         }\r                      if (rem) memcpy(buf,&(buf[l]),(unsigned int)rem);\r\r                     i=0;\r                   while (i < l)\r                          {\r                              if (uflag)\r                                     j=uufwrite(obuf,1,(unsigned int)l-i,\r                                           DES_OUT);\r                              else\r                                   j=fwrite(obuf,1,(unsigned int)l-i,\r                                             DES_OUT);\r                              if (j == -1)\r                                   {\r                                      perror("Write error");\r                                 Exit=7;\r                                        goto problems;\r                                 }\r                              i+=j;\r                          }\r                      if (feof(DES_IN))\r                              {\r                              if (uflag) uufwriteEnd(DES_OUT);\r                               break;\r                         }\r                      }\r              }\r      else /* decrypt */\r             {\r              ex=1;\r          for (;;)\r                       {\r                      if (ex) {\r                              if (uflag)\r                                     l=uufread(buf,1,BUFSIZE,DES_IN);\r                               else\r                                   l=fread(buf,1,BUFSIZE,DES_IN);\r                         ex=0;\r                          rem=l%8;\r                               l-=rem;\r                                }\r                      if (l < 0)\r                             {\r                              perror("read error");\r                          Exit=6;\r                                goto problems;\r                         }\r\r                     if (bflag && !flag3)\r                           for (i=0; i<l; i+=8)\r                                   des_ecb_encrypt(\r                                               (des_cblock *)&(buf[i]),\r                                               (des_cblock *)&(obuf[i]),\r                                              ks,do_encrypt);\r                        else if (flag3 && bflag)\r                               for (i=0; i<l; i+=8)\r                                   des_ecb2_encrypt(\r                                              (des_cblock *)&(buf[i]),\r                                               (des_cblock *)&(obuf[i]),\r                                              ks,ks2,do_encrypt);\r                    else if (flag3 && !bflag)\r                              {\r                              des_3cbc_encrypt(\r                                      (des_cblock *)buf,(des_cblock *)obuf,\r                                  (long)l,ks,ks2,(des_cblock *)iv,\r                                       (des_cblock *)iv2,do_encrypt);\r                         }\r                      else\r                           {\r                              des_cbc_encrypt(\r                                       (des_cblock *)buf,(des_cblock *)obuf,\r                                  (long)l,ks,(des_cblock *)iv,do_encrypt);\r                               if (l >= 8) memcpy(iv,&(buf[l-8]),8);\r                          }\r\r                     if (uflag)\r                             ll=uufread(&(buf[rem]),1,BUFSIZE,DES_IN);\r                      else\r                           ll=fread(&(buf[rem]),1,BUFSIZE,DES_IN);\r                        ll+=rem;\r                       rem=ll%8;\r                      ll-=rem;\r                       if (feof(DES_IN) && (ll == 0))\r                         {\r                              last=obuf[l-1];\r\r                               if ((last > 7) || (last < 0))\r                                  {\r                                      fputs("The file was not decrypted correctly.\n",\r                                               stderr);\r                                       Exit=8;\r                                        last=0;\r                                        }\r                              l=l-8+last;\r                            }\r                      i=0;\r                   if (cflag) des_cbc_cksum((C_Block *)obuf,\r                              (C_Block *)cksum,(long)l/8*8,ks,\r                               (C_Block *)cksum);\r                     while (i != l)\r                         {\r                              j=fwrite(obuf,1,(unsigned int)l-i,DES_OUT);\r                            if (j == -1)\r                                   {\r                                      perror("Write error");\r                                 Exit=7;\r                                        goto problems;\r                                 }\r                              i+=j;\r                          }\r                      l=ll;\r                  if ((l == 0) && feof(DES_IN)) break;\r                   }\r              }\r      if (cflag)\r             {\r              l=0;\r           if (cksumname[0] != '\0')\r                      {\r                      if ((O=fopen(cksumname,"w")) != NULL)\r                          {\r                              CKSUM_OUT=O;\r                           l=1;\r                           }\r                      }\r              for (i=0; i<8; i++)\r                    fprintf(CKSUM_OUT,"%02X",cksum[i]);\r            fprintf(CKSUM_OUT,"\n");\r               if (l) fclose(CKSUM_OUT);\r              }\rproblems:\r    memset(buf,0,sizeof(buf));\r     memset(obuf,0,sizeof(obuf));\r   memset(ks,0,sizeof(ks));\r       memset(ks2,0,sizeof(ks2));\r     memset(iv,0,sizeof(iv));\r       memset(iv2,0,sizeof(iv2));\r     memset(kk,0,sizeof(kk));\r       memset(k2,0,sizeof(k2));\r       memset(uubuf,0,sizeof(uubuf));\r memset(b,0,sizeof(b));\r memset(bb,0,sizeof(bb));\r       memset(cksum,0,sizeof(cksum));\r if (Exit) EXIT(Exit);\r  }\r\rint uufwrite(data, size, num, fp)\runsigned char *data;\rint size;\runsigned int num;\rFILE *fp;\r      \r     /* We ignore this parameter but it should be > ~50 I believe */\r   \r    \r   {\r      int i,j,left,rem,ret=num;\r      static int start=1;\r\r   if (start)\r             {\r              fprintf(fp,"begin 600 %s\n",\r                   (uuname[0] == '\0')?"text.d":uuname);\r          start=0;\r               }\r\r     if (uubufnum)\r          {\r              if (uubufnum+num < 45)\r                 {\r                      memcpy(&(uubuf[uubufnum]),data,(unsigned int)num);\r                     uubufnum+=num;\r                 return(num);\r                   }\r              else\r                   {\r                      i=45-uubufnum;\r                 memcpy(&(uubuf[uubufnum]),data,(unsigned int)i);\r                       j=uuencode((unsigned char *)uubuf,45,b);\r                       fwrite(b,1,(unsigned int)j,fp);\r                        uubufnum=0;\r                    data+=i;\r                       num-=i;\r                        }\r              }\r\r     for (i=0; i<(((int)num)-INUUBUFN); i+=INUUBUFN)\r                {\r              j=uuencode(&(data[i]),INUUBUFN,b);\r             fwrite(b,1,(unsigned int)j,fp);\r                }\r      rem=(num-i)%45;\r        left=(num-i-rem);\r      if (left)\r              {\r              j=uuencode(&(data[i]),left,b);\r         fwrite(b,1,(unsigned int)j,fp);\r                i+=left;\r               }\r      if (i != num)\r          {\r              memcpy(uubuf,&(data[i]),(unsigned int)rem);\r            uubufnum=rem;\r          }\r      return(ret);\r   }\r\rvoid uufwriteEnd(fp)\rFILE *fp;\r      {\r      int j;\r static const char *end=" \nend\n";\r\r    if (uubufnum != 0)\r             {\r              uubuf[uubufnum]='\0';\r          uubuf[uubufnum+1]='\0';\r                uubuf[uubufnum+2]='\0';\r                j=uuencode(uubuf,uubufnum,b);\r          fwrite(b,1,(unsigned int)j,fp);\r                }\r      fwrite(end,1,strlen(end),fp);\r  }\r\rint uufread(out, size, num, fp)\runsigned char *out;\rint size; /* should always be > ~ 60; I actually ignore this parameter :-) */\runsigned int num;\rFILE *fp;\r       {\r      int i,j,tot;\r   static int done=0;\r     static int valid=0;\r    static int start=1;\r\r   if (start)\r             {\r              for (;;)\r                       {\r                      b[0]='\0';\r                     fgets((char *)b,300,fp);\r                       if (b[0] == '\0')\r                              {\r                              fprintf(stderr,"no 'begin' found in uuencoded input\n");\r                               return(-1);\r                            }\r                      if (strncmp((char *)b,"begin ",6) == 0) break;\r                 }\r              start=0;\r               }\r      if (done) return(0);\r   tot=0;\r if (valid)\r             {\r              memcpy(out,bb,(unsigned int)valid);\r            tot=valid;\r             valid=0;\r               }\r      for (;;)\r               {\r              b[0]='\0';\r             fgets((char *)b,300,fp);\r               if (b[0] == '\0') break;\r               i=strlen((char *)b);\r           if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd'))\r                   {\r                      done=1;\r                        while (!feof(fp))\r                              {\r                              fgets((char *)b,300,fp);\r                               }\r                      break;\r                 }\r              i=uudecode(b,i,bb);\r            if (i < 0) break;\r              if ((i+tot+8) > num)\r                   {\r                      /* num to copy to make it a multiple of 8 */\r                   j=(num/8*8)-tot-8;\r                     memcpy(&(out[tot]),bb,(unsigned int)j);\r                        tot+=j;\r                        memcpy(bb,&(bb[j]),(unsigned int)i-j);\r                 valid=i-j;\r                     break;\r                 }\r              memcpy(&(out[tot]),bb,(unsigned int)i);\r                tot+=i;\r                }\r      return(tot);\r   }\r\r#define ccc2l(c,l)      (l =((DES_LONG)(*((c)++)))<<16, \\r                    l|=((DES_LONG)(*((c)++)))<< 8, \\r                       l|=((DES_LONG)(*((c)++))))\r\r#define l2ccc(l,c)      (*((c)++)=(unsigned char)(((l)>>16)&0xff), \\r                    *((c)++)=(unsigned char)(((l)>> 8)&0xff), \\r                    *((c)++)=(unsigned char)(((l)    )&0xff))\r\r\rint uuencode(in, num, out)\runsigned char *in;\rint num;\runsigned char *out;\r   {\r      int j,i,n,tot=0;\r       DES_LONG l;\r    register unsigned char *p;\r     p=out;\r\r        for (j=0; j<num; j+=45)\r                {\r              if (j+45 > num)\r                        i=(num-j);\r             else    i=45;\r          *(p++)=i+' ';\r          for (n=0; n<i; n+=3)\r                   {\r                      ccc2l(in,l);\r                   *(p++)=((l>>18)&0x3f)+' ';\r                     *(p++)=((l>>12)&0x3f)+' ';\r                     *(p++)=((l>> 6)&0x3f)+' ';\r                     *(p++)=((l    )&0x3f)+' ';\r                     tot+=4;\r                        }\r              *(p++)='\n';\r           tot+=2;\r                }\r      *p='\0';\r       l=0;\r   return(tot);\r   }\r\rint uudecode(in, num, out)\runsigned char *in;\rint num;\runsigned char *out;\r  {\r      int j,i,k;\r     unsigned int n=0,space=0;\r      DES_LONG l;\r    DES_LONG w,x,y,z;\r      unsigned int blank=(unsigned int)'\n'-' ';\r\r    for (j=0; j<num; )\r             {\r              n= *(in++)-' ';\r                if (n == blank)\r                        {\r                      n=0;\r                   in--;\r                  }\r              if (n > 60)\r                    {\r                      fprintf(stderr,"uuencoded line length too long\n");\r                    return(-1);\r                    }\r              j++;\r\r          for (i=0; i<n; j+=4,i+=3)\r                      {\r                      /* the following is for cases where spaces are\r                  * removed from lines.\r                  */\r                    if (space)\r                             {\r                              w=x=y=z=0;\r                             }\r                      else\r                           {\r                              w= *(in++)-' ';\r                                x= *(in++)-' ';\r                                y= *(in++)-' ';\r                                z= *(in++)-' ';\r                                }\r                      if ((w > 63) || (x > 63) || (y > 63) || (z > 63))\r                              {\r                              k=0;\r                           if (w == blank) k=1;\r                           if (x == blank) k=2;\r                           if (y == blank) k=3;\r                           if (z == blank) k=4;\r                           space=1;\r                               switch (k) {\r                           case 1: w=0; in--;\r                             case 2: x=0; in--;\r                             case 3: y=0; in--;\r                             case 4: z=0; in--;\r                                     break;\r                         case 0:\r                                        space=0;\r                                       fprintf(stderr,"bad uuencoded data values\n");\r                                 w=x=y=z=0;\r                                     return(-1);\r                                    break;\r                                 }\r                              }\r                      l=(w<<18)|(x<<12)|(y<< 6)|(z    );\r                     l2ccc(l,out);\r                  }\r              if (*(in++) != '\n')\r                   {\r                      fprintf(stderr,"missing nl in uuencoded line\n");\r                      w=x=y=z=0;\r                     return(-1);\r                    }\r              j++;\r           }\r      *out='\0';\r     w=x=y=z=0;\r     return(n);\r     }\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.def b/mac/libdes/src/des.def
new file mode 100755 (executable)
index 0000000..f056ecf
--- /dev/null
@@ -0,0 +1 @@
+LIBRARY        des BASE=0x06000000\rEXPORTS\r    des_ecb3_encrypt\r       des_cbc_cksum\r  des_cbc_encrypt\r        des_ncbc_encrypt\r       des_3cbc_encrypt\r       des_cfb_encrypt\r        des_ede3_cfb64_encrypt\r des_ede3_ofb64_encrypt\r des_ecb_encrypt\r        des_encrypt\r    des_encrypt2\r   des_ede3_cbc_encrypt\r   des_enc_read\r   des_enc_write\r  crypt\r  des_ofb_encrypt\r        des_pcbc_encrypt\r       des_quad_cksum\r des_read_password\r      des_read_2passwords\r    des_read_pw_string\r     des_set_odd_parity\r     des_is_weak_key\r        des_set_key\r    des_key_sched\r  des_string_to_key\r      des_string_to_2keys\r    des_cfb64_encrypt\r      des_ofb64_encrypt\r      des_cblock_print_file\r  des_new_random_key\r     des_init_random_number_generator\r       des_set_random_generator_seed\r  des_set_sequence_number\r        des_generate_random_block\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.doc b/mac/libdes/src/des.doc
new file mode 100755 (executable)
index 0000000..1e30158
--- /dev/null
@@ -0,0 +1,505 @@
+The DES library.
+
+Please note that this library was originally written to operate with
+eBones, a version of Kerberos that had had encryption removed when it left
+the USA and then put back in.  As such there are some routines that I will
+advise not using but they are still in the library for historical reasons.
+For all calls that have an 'input' and 'output' variables, they can be the
+same.
+
+This library requires the inclusion of 'des.h'.
+
+All of the encryption functions take what is called a des_key_schedule as an 
+argument.  A des_key_schedule is an expanded form of the des key.
+A des_key is 8 bytes of odd parity, the type used to hold the key is a
+des_cblock.  A des_cblock is an array of 8 bytes, often in this library
+description I will refer to input bytes when the function specifies
+des_cblock's as input or output, this just means that the variable should
+be a multiple of 8 bytes.
+
+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
+specify decryption.  The functions and global variable are as follows:
+
+int des_check_key;
+       DES keys are supposed to be odd parity.  If this variable is set to
+       a non-zero value, des_set_key() will check that the key has odd
+       parity and is not one of the known weak DES keys.  By default this
+       variable is turned off;
+       
+void des_set_odd_parity(
+des_cblock *key );
+       This function takes a DES key (8 bytes) and sets the parity to odd.
+       
+int des_is_weak_key(
+des_cblock *key );
+       This function returns a non-zero value if the DES key passed is a
+       weak, DES key.  If it is a weak key, don't use it, try a different
+       one.  If you are using 'random' keys, the chances of hitting a weak
+       key are 1/2^52 so it is probably not worth checking for them.
+       
+int des_set_key(
+des_cblock *key,
+des_key_schedule schedule);
+       Des_set_key converts an 8 byte DES key into a des_key_schedule.
+       A des_key_schedule is an expanded form of the key which is used to
+       perform actual encryption.  It can be regenerated from the DES key
+       so it only needs to be kept when encryption or decryption is about
+       to occur.  Don't save or pass around des_key_schedule's since they
+       are CPU architecture dependent, DES keys are not.  If des_check_key
+       is non zero, zero is returned if the key has the wrong parity or
+       the key is a weak key, else 1 is returned.
+       
+int des_key_sched(
+des_cblock *key,
+des_key_schedule schedule);
+       An alternative name for des_set_key().
+
+int des_rw_mode;               /* defaults to DES_PCBC_MODE */
+       This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
+       This specifies the function to use in the enc_read() and enc_write()
+       functions.
+
+void des_encrypt(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+       This is the DES encryption function that gets called by just about
+       every other DES routine in the library.  You should not use this
+       function except to implement 'modes' of DES.  I say this because the
+       functions that call this routine do the conversion from 'char *' to
+       long, and this needs to be done to make sure 'non-aligned' memory
+       access do not occur.  The characters are loaded 'little endian',
+       have a look at my source code for more details on how I use this
+       function.
+       Data is a pointer to 2 unsigned long's and ks is the
+       des_key_schedule to use.  enc, is non zero specifies encryption,
+       zero if decryption.
+
+void des_encrypt2(
+unsigned long *data,
+des_key_schedule ks,
+int enc);
+       This functions is the same as des_encrypt() except that the DES
+       initial permutation (IP) and final permutation (FP) have been left
+       out.  As for des_encrypt(), you should not use this function.
+       It is used by the routines in my library that implement triple DES.
+       IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
+       as des_encrypt() des_encrypt() des_encrypt() except faster :-).
+
+void des_ecb_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks,
+int enc);
+       This is the basic Electronic Code Book form of DES, the most basic
+       form.  Input is encrypted into output using the key represented by
+       ks.  If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
+       decryption occurs.  Input is 8 bytes long and output is 8 bytes.
+       (the des_cblock structure is 8 chars).
+       
+void des_ecb3_encrypt(
+des_cblock *input,
+des_cblock *output,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+int enc);
+       This is the 3 key EDE mode of ECB DES.  What this means is that 
+       the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
+       then encrypted again with ks3, before being put into output;
+       C=E(ks3,D(ks2,E(ks1,M))).  There is a macro, des_ecb2_encrypt()
+       that only takes 2 des_key_schedules that implements,
+       C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
+       
+void des_cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+       This routine implements DES in Cipher Block Chaining mode.
+       Input, which should be a multiple of 8 bytes is encrypted
+       (or decrypted) to output which will also be a multiple of 8 bytes.
+       The number of bytes is in length (and from what I've said above,
+       should be a multiple of 8).  If length is not a multiple of 8, I'm
+       not being held responsible :-).  ivec is the initialisation vector.
+       This function does not modify this variable.  To correctly implement
+       cbc mode, you need to do one of 2 things; copy the last 8 bytes of
+       cipher text for use as the next ivec in your application,
+       or use des_ncbc_encrypt(). 
+       Only this routine has this problem with updating the ivec, all
+       other routines that are implementing cbc mode update ivec.
+       
+void des_ncbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+int enc);
+       For historical reasons, des_cbc_encrypt() did not update the
+       ivec with the value requires so that subsequent calls to
+       des_cbc_encrypt() would 'chain'.  This was needed so that the same
+       'length' values would not need to be used when decrypting.
+       des_ncbc_encrypt() does the right thing.  It is the same as
+       des_cbc_encrypt accept that ivec is updates with the correct value
+       to pass in subsequent calls to des_ncbc_encrypt().  I advise using
+       des_ncbc_encrypt() instead of des_cbc_encrypt();
+
+void des_xcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk,
+des_cblock *ivec,
+des_cblock *inw,
+des_cblock *outw,
+int enc);
+       This is RSA's DESX mode of DES.  It uses inw and outw to
+       'whiten' the encryption.  inw and outw are secret (unlike the iv)
+       and are as such, part of the key.  So the key is sort of 24 bytes.
+       This is much better than cbc des.
+       
+void des_3cbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule sk1,
+des_key_schedule sk2,
+des_cblock *ivec1,
+des_cblock *ivec2,
+int enc);
+       This function is flawed, do not use it.  I have left it in the
+       library because it is used in my des(1) program and will function
+       correctly when used by des(1).  If I removed the function, people
+       could end up unable to decrypt files.
+       This routine implements outer triple cbc encryption using 2 ks and
+       2 ivec's.  Use des_ede2_cbc_encrypt() instead.
+       
+void des_ede3_cbc_encrypt(
+des_cblock *input,
+des_cblock *output, 
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2, 
+des_key_schedule ks3, 
+des_cblock *ivec,
+int enc);
+       This function implements inner triple CBC DES encryption with 3
+       keys.  What this means is that each 'DES' operation
+       inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
+       Again, this is cbc mode so an ivec is requires.
+       This mode is used by SSL.
+       There is also a des_ede2_cbc_encrypt() that only uses 2
+       des_key_schedule's, the first being reused for the final
+       encryption.  C=E(ks1,D(ks2,E(ks1,M))).  This form of triple DES
+       is used by the RSAref library.
+       
+void des_pcbc_encrypt(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+       This is Propagating Cipher Block Chaining mode of DES.  It is used
+       by Kerberos v4.  It's parameters are the same as des_ncbc_encrypt().
+       
+void des_cfb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int enc);
+       Cipher Feedback Back mode of DES.  This implementation 'feeds back'
+       in numbit blocks.  The input (and output) is in multiples of numbits
+       bits.  numbits should to be a multiple of 8 bits.  Length is the
+       number of bytes input.  If numbits is not a multiple of 8 bits,
+       the extra bits in the bytes will be considered padding.  So if
+       numbits is 12, for each 2 input bytes, the 4 high bits of the
+       second byte will be ignored.  So to encode 72 bits when using
+       a numbits of 12 take 12 bytes.  To encode 72 bits when using
+       numbits of 9 will take 16 bytes.  To encode 80 bits when using
+       numbits of 16 will take 10 bytes. etc, etc.  This padding will
+       apply to both input and output.
+
+       
+void des_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num,
+int enc);
+       This is one of the more useful functions in this DES library, it
+       implements CFB mode of DES with 64bit feedback.  Why is this
+       useful you ask?  Because this routine will allow you to encrypt an
+       arbitrary number of bytes, no 8 byte padding.  Each call to this
+       routine will encrypt the input bytes to output and then update ivec
+       and num.  num contains 'how far' we are though ivec.  If this does
+       not make much sense, read more about cfb mode of DES :-).
+       
+void des_ede3_cfb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num,
+int enc);
+       Same as des_cfb64_encrypt() accept that the DES operation is
+       triple DES.  As usual, there is a macro for
+       des_ede2_cfb64_encrypt() which reuses ks1.
+
+void des_ofb_encrypt(
+unsigned char *in,
+unsigned char *out,
+int numbits,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+       This is a implementation of Output Feed Back mode of DES.  It is
+       the same as des_cfb_encrypt() in that numbits is the size of the
+       units dealt with during input and output (in bits).
+       
+void des_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks,
+des_cblock *ivec,
+int *num);
+       The same as des_cfb64_encrypt() except that it is Output Feed Back
+       mode.
+
+void des_ede3_ofb64_encrypt(
+unsigned char *in,
+unsigned char *out,
+long length,
+des_key_schedule ks1,
+des_key_schedule ks2,
+des_key_schedule ks3,
+des_cblock *ivec,
+int *num);
+       Same as des_ofb64_encrypt() accept that the DES operation is
+       triple DES.  As usual, there is a macro for
+       des_ede2_ofb64_encrypt() which reuses ks1.
+
+int des_read_pw_string(
+char *buf,
+int length,
+char *prompt,
+int verify);
+       This routine is used to get a password from the terminal with echo
+       turned off.  Buf is where the string will end up and length is the
+       size of buf.  Prompt is a string presented to the 'user' and if
+       verify is set, the key is asked for twice and unless the 2 copies
+       match, an error is returned.  A return code of -1 indicates a
+       system error, 1 failure due to use interaction, and 0 is success.
+
+unsigned long des_cbc_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+des_key_schedule ks,
+des_cblock *ivec);
+       This function produces an 8 byte checksum from input that it puts in
+       output and returns the last 4 bytes as a long.  The checksum is
+       generated via cbc mode of DES in which only the last 8 byes are
+       kept.  I would recommend not using this function but instead using
+       the EVP_Digest routines, or at least using MD5 or SHA.  This
+       function is used by Kerberos v4 so that is why it stays in the
+       library.
+       
+char *des_fcrypt(
+const char *buf,
+const char *salt
+char *ret);
+       This is my fast version of the unix crypt(3) function.  This version
+       takes only a small amount of space relative to other fast
+       crypt() implementations.  This is different to the normal crypt
+       in that the third parameter is the buffer that the return value
+       is written into.  It needs to be at least 14 bytes long.  This
+       function is thread safe, unlike the normal crypt.
+
+char *crypt(
+const char *buf,
+const char *salt);
+       This function calls des_fcrypt() with a static array passed as the
+       third parameter.  This emulates the normal non-thread safe semantics
+       of crypt(3).
+
+void des_string_to_key(
+char *str,
+des_cblock *key);
+       This function takes str and converts it into a DES key.  I would
+       recommend using MD5 instead and use the first 8 bytes of output.
+       When I wrote the first version of these routines back in 1990, MD5
+       did not exist but I feel these routines are still sound.  This
+       routines is compatible with the one in MIT's libdes.
+       
+void des_string_to_2keys(
+char *str,
+des_cblock *key1,
+des_cblock *key2);
+       This function takes str and converts it into 2 DES keys.
+       I would recommend using MD5 and using the 16 bytes as the 2 keys.
+       I have nothing against these 2 'string_to_key' routines, it's just
+       that if you say that your encryption key is generated by using the
+       16 bytes of an MD5 hash, every-one knows how you generated your
+       keys.
+
+int des_read_password(
+des_cblock *key,
+char *prompt,
+int verify);
+       This routine combines des_read_pw_string() with des_string_to_key().
+
+int des_read_2passwords(
+des_cblock *key1,
+des_cblock *key2,
+char *prompt,
+int verify);
+       This routine combines des_read_pw_string() with des_string_to_2key().
+
+void des_random_seed(
+des_cblock key);
+       This routine sets a starting point for des_random_key().
+       
+void des_random_key(
+des_cblock ret);
+       This function return a random key.  Make sure to 'seed' the random
+       number generator (with des_random_seed()) before using this function.
+       I personally now use a MD5 based random number system.
+
+int des_enc_read(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+       This function will write to a file descriptor the encrypted data
+       from buf.  This data will be preceded by a 4 byte 'byte count' and
+       will be padded out to 8 bytes.  The encryption is either CBC of
+       PCBC depending on the value of des_rw_mode.  If it is DES_PCBC_MODE,
+       pcbc is used, if DES_CBC_MODE, cbc is used.  The default is to use
+       DES_PCBC_MODE.
+
+int des_enc_write(
+int fd,
+char *buf,
+int len,
+des_key_schedule ks,
+des_cblock *iv);
+       This routines read stuff written by des_enc_read() and decrypts it.
+       I have used these routines quite a lot but I don't believe they are
+       suitable for non-blocking io.  If you are after a full
+       authentication/encryption over networks, have a look at SSL instead.
+
+unsigned long des_quad_cksum(
+des_cblock *input,
+des_cblock *output,
+long length,
+int out_count,
+des_cblock *seed);
+       This is a function from Kerberos v4 that is not anything to do with
+       DES but was needed.  It is a cksum that is quicker to generate than
+       des_cbc_cksum();  I personally would use MD5 routines now.
+=====
+Modes of DES
+Quite a bit of the following information has been taken from
+       AS 2805.5.2
+       Australian Standard
+       Electronic funds transfer - Requirements for interfaces,
+       Part 5.2: Modes of operation for an n-bit block cipher algorithm
+       Appendix A
+
+There are several different modes in which DES can be used, they are
+as follows.
+
+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
+- 64 bits are enciphered at a time.
+- The order of the blocks can be rearranged without detection.
+- The same plaintext block always produces the same ciphertext block
+  (for the same key) making it vulnerable to a 'dictionary attack'.
+- An error will only affect one ciphertext block.
+
+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
+- a multiple of 64 bits are enciphered at a time.
+- The CBC mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext blocks dependent on the
+  current and all preceding plaintext blocks and therefore blocks can not
+  be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- An error will affect the current and the following ciphertext blocks.
+
+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The CFB mode produces the same ciphertext whenever the same
+  plaintext is encrypted using the same key and starting variable.
+- The chaining operation makes the ciphertext variables dependent on the
+  current and all preceding variables and therefore j-bit variables are
+  chained together and can not be rearranged.
+- The use of different starting variables prevents the same plaintext
+  enciphering to the same ciphertext.
+- The strength of the CFB mode depends on the size of k (maximal if
+  j == k).  In my implementation this is always the case.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- An error will affect the current and the following ciphertext variables.
+
+Output Feedback Mode (OFB) (des_ofb_encrypt())
+- a number of bits (j) <= 64 are enciphered at a time.
+- The OFB mode produces the same ciphertext whenever the same
+  plaintext enciphered using the same key and starting variable.  More
+  over, in the OFB mode the same key stream is produced when the same
+  key and start variable are used.  Consequently, for security reasons
+  a specific start variable should be used only once for a given key.
+- The absence of chaining makes the OFB more vulnerable to specific attacks.
+- The use of different start variables values prevents the same
+  plaintext enciphering to the same ciphertext, by producing different
+  key streams.
+- Selection of a small value for j will require more cycles through
+  the encipherment algorithm per unit of plaintext and thus cause
+  greater processing overheads.
+- Only multiples of j bits can be enciphered.
+- OFB mode of operation does not extend ciphertext errors in the
+  resultant plaintext output.  Every bit error in the ciphertext causes
+  only one bit to be in error in the deciphered plaintext.
+- OFB mode is not self-synchronising.  If the two operation of
+  encipherment and decipherment get out of synchronism, the system needs
+  to be re-initialised.
+- Each re-initialisation should use a value of the start variable
+ different from the start variable values used before with the same
+ key.  The reason for this is that an identical bit stream would be
+ produced each time from the same parameters.  This would be
+ susceptible to a ' known plaintext' attack.
+
+Triple ECB Mode (des_ecb3_encrypt())
+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
+- As for ECB encryption but increases the key length to 168 bits.
+  There are theoretic attacks that can be used that make the effective
+  key length 112 bits, but this attack also requires 2^56 blocks of
+  memory, not very likely, even for the NSA.
+- If both keys are the same it is equivalent to encrypting once with
+  just one key.
+- If the first and last key are the same, the key length is 112 bits.
+  There are attacks that could reduce the key space to 55 bit's but it
+  requires 2^56 blocks of memory.
+- If all 3 keys are the same, this is effectively the same as normal
+  ecb mode.
+
+Triple CBC Mode (des_ede3_cbc_encrypt())
+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
+- As for CBC encryption but increases the key length to 168 bits with
+  the same restrictions as for triple ecb mode.
diff --git a/mac/libdes/src/des.dsp b/mac/libdes/src/des.dsp
new file mode 100755 (executable)
index 0000000..f669b4f
--- /dev/null
@@ -0,0 +1 @@
+# Microsoft Developer Studio Project File - Name="des" - Package Owner=<4>\r# Microsoft Developer Studio Generated Build File, Format Version 5.00\r# ** DO NOT EDIT **\r\r# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102\r\rCFG=des - Win32 Release\r!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r!MESSAGE use the Export Makefile command and run\r!MESSAGE \r!MESSAGE NMAKE /f "des.mak".\r!MESSAGE \r!MESSAGE You can specify a configuration when running NMAKE\r!MESSAGE by defining the macro CFG on the command line. For example:\r!MESSAGE \r!MESSAGE NMAKE /f "des.mak" CFG="des - Win32 Release"\r!MESSAGE \r!MESSAGE Possible choices for configuration are:\r!MESSAGE \r!MESSAGE "des - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r!MESSAGE "des - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r!MESSAGE \r\r# Begin Project\r# PROP Scc_ProjName ""\r# PROP Scc_LocalPath ""\rCPP=cl.exe\rMTL=midl.exe\rRSC=rc.exe\r\r!IF  "$(CFG)" == "des - Win32 Release"\r\r# PROP BASE Use_MFC 0\r# PROP BASE Use_Debug_Libraries 0\r# PROP BASE Output_Dir ".\Release"\r# PROP BASE Intermediate_Dir ".\Release"\r# PROP BASE Target_Dir ""\r# PROP Use_MFC 0\r# PROP Use_Debug_Libraries 0\r# PROP Output_Dir ".\Release"\r# PROP Intermediate_Dir ".\Release"\r# PROP Ignore_Export_Lib 0\r# PROP Target_Dir ""\r# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c\r# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\roken" /I "." /I "..\..\include" /I "..\..\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c\r# ADD BASE MTL /nologo /D "NDEBUG" /win32\r# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32\r# ADD BASE RSC /l 0x409 /d "NDEBUG"\r# ADD RSC /l 0x409 /d "NDEBUG"\rBSC32=bscmake.exe\r# ADD BASE BSC32 /nologo\r# ADD BSC32 /nologo\rLINK32=link.exe\r# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386\r# ADD LINK32 ..\roken\Release\roken.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /machine:I386\r\r!ELSEIF  "$(CFG)" == "des - Win32 Debug"\r\r# PROP BASE Use_MFC 0\r# PROP BASE Use_Debug_Libraries 1\r# PROP BASE Output_Dir ".\Debug"\r# PROP BASE Intermediate_Dir ".\Debug"\r# PROP BASE Target_Dir ""\r# PROP Use_MFC 0\r# PROP Use_Debug_Libraries 1\r# PROP Output_Dir ".\Debug"\r# PROP Intermediate_Dir ".\Debug"\r# PROP Ignore_Export_Lib 0\r# PROP Target_Dir ""\r# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c\r# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\roken" /I "." /I "..\..\include" /I "..\..\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H" /YX /FD /c\r# ADD BASE MTL /nologo /D "_DEBUG" /win32\r# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32\r# ADD BASE RSC /l 0x409 /d "_DEBUG"\r# ADD RSC /l 0x409 /d "_DEBUG"\rBSC32=bscmake.exe\r# ADD BASE BSC32 /nologo\r# ADD BSC32 /nologo\rLINK32=link.exe\r# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386\r# ADD LINK32 ..\roken\Debug\roken.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib /nologo /subsystem:windows /dll /debug /machine:I386\r\r!ENDIF \r\r# Begin Target\r\r# Name "des - Win32 Release"\r# Name "des - Win32 Debug"\r# Begin Group "Source Files"\r\r# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"\r# Begin Source File\r\rSOURCE=.\cbc3_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\cbc_cksm.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\cbc_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\cfb64ede.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\cfb64enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\cfb_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\des.def\r# End Source File\r# Begin Source File\r\rSOURCE=.\des_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\dllmain.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ecb3_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ecb_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ede_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\enc_read.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\enc_writ.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\fcrypt.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\key_par.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ncbc_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ofb64ede.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ofb64enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\ofb_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\passwd_dlg.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\pcbc_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\qud_cksm.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\read_pwd.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\rnd_keys.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\rpc_enc.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\set_key.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\str2key.c\r# End Source File\r# Begin Source File\r\rSOURCE=.\supp.c\r# End Source File\r# End Group\r# Begin Group "Header Files"\r\r# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"\r# Begin Source File\r\rSOURCE=.\des.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\des_locl.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\des_ver.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\md5.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\passwd_dlg.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\podd.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\rpc_des.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\sk.h\r# End Source File\r# Begin Source File\r\rSOURCE=.\spr.h\r# End Source File\r# End Group\r# Begin Group "Resource Files"\r\r# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"\r# Begin Source File\r\rSOURCE=.\passwd_dialog.rc\r# End Source File\r# End Group\r# End Target\r# End Project\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.mak b/mac/libdes/src/des.mak
new file mode 100755 (executable)
index 0000000..0552507
--- /dev/null
@@ -0,0 +1 @@
+# Microsoft Developer Studio Generated NMAKE File, Based on des.dsp\r!IF "$(CFG)" == ""\rCFG=des - Win32 Release\r!MESSAGE No configuration specified. Defaulting to des - Win32 Release.\r!ENDIF \r\r!IF "$(CFG)" != "des - Win32 Release" && "$(CFG)" != "des - Win32 Debug"\r!MESSAGE Invalid configuration "$(CFG)" specified.\r!MESSAGE You can specify a configuration when running NMAKE\r!MESSAGE by defining the macro CFG on the command line.  For example:\r!MESSAGE \r!MESSAGE NMAKE /f "des.mak" CFG="des - Win32 Release"\r!MESSAGE \r!MESSAGE Possible choices for configuration are:\r!MESSAGE \r!MESSAGE "des - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")\r!MESSAGE "des - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")\r!MESSAGE \r!ERROR An invalid configuration is specified.\r!ENDIF \r\r!IF "$(OS)" == "Windows_NT"\rNULL=\r!ELSE \rNULL=nul\r!ENDIF \r\r!IF  "$(CFG)" == "des - Win32 Release"\r\rOUTDIR=.\Release\rINTDIR=.\Release\r# Begin Custom Macros\rOutDir=.\.\Release\r# End Custom Macros\r\r!IF "$(RECURSE)" == "0" \r\rALL : "$(OUTDIR)\des.dll"\r\r!ELSE \r\rALL : "roken - Win32 Release" "$(OUTDIR)\des.dll"\r\r!ENDIF \r\r!IF "$(RECURSE)" == "1" \rCLEAN :"roken - Win32 ReleaseCLEAN" \r!ELSE \rCLEAN : \r!ENDIF \r -@erase "$(INTDIR)\cbc3_enc.obj"\r       -@erase "$(INTDIR)\cbc_cksm.obj"\r       -@erase "$(INTDIR)\cbc_enc.obj"\r        -@erase "$(INTDIR)\cfb64ede.obj"\r       -@erase "$(INTDIR)\cfb64enc.obj"\r       -@erase "$(INTDIR)\cfb_enc.obj"\r        -@erase "$(INTDIR)\des_enc.obj"\r        -@erase "$(INTDIR)\dllmain.obj"\r        -@erase "$(INTDIR)\ecb3_enc.obj"\r       -@erase "$(INTDIR)\ecb_enc.obj"\r        -@erase "$(INTDIR)\ede_enc.obj"\r        -@erase "$(INTDIR)\enc_read.obj"\r       -@erase "$(INTDIR)\enc_writ.obj"\r       -@erase "$(INTDIR)\fcrypt.obj"\r -@erase "$(INTDIR)\key_par.obj"\r        -@erase "$(INTDIR)\ncbc_enc.obj"\r       -@erase "$(INTDIR)\ofb64ede.obj"\r       -@erase "$(INTDIR)\ofb64enc.obj"\r       -@erase "$(INTDIR)\ofb_enc.obj"\r        -@erase "$(INTDIR)\passwd_dialog.res"\r  -@erase "$(INTDIR)\passwd_dlg.obj"\r     -@erase "$(INTDIR)\pcbc_enc.obj"\r       -@erase "$(INTDIR)\qud_cksm.obj"\r       -@erase "$(INTDIR)\read_pwd.obj"\r       -@erase "$(INTDIR)\rnd_keys.obj"\r       -@erase "$(INTDIR)\rpc_enc.obj"\r        -@erase "$(INTDIR)\set_key.obj"\r        -@erase "$(INTDIR)\str2key.obj"\r        -@erase "$(INTDIR)\supp.obj"\r   -@erase "$(INTDIR)\vc50.idb"\r   -@erase "$(OUTDIR)\des.dll"\r    -@erase "$(OUTDIR)\des.exp"\r    -@erase "$(OUTDIR)\des.lib"\r\r"$(OUTDIR)" :\r    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r\rCPP=cl.exe\rCPP_PROJ=/nologo /MT /W3 /GX /O2 /I "..\roken" /I "." /I "..\..\include" /I\\r "..\..\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "HAVE_CONFIG_H"\\r /Fp"$(INTDIR)\des.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c \rCPP_OBJS=.\Release/\rCPP_SBRS=.\r\r.c{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cpp{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cxx{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.c{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cpp{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cxx{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\rMTL=midl.exe\rMTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 \rRSC=rc.exe\rRSC_PROJ=/l 0x409 /fo"$(INTDIR)\passwd_dialog.res" /d "NDEBUG" \rBSC32=bscmake.exe\rBSC32_FLAGS=/nologo /o"$(OUTDIR)\des.bsc" \rBSC32_SBRS= \\r        \rLINK32=link.exe\rLINK32_FLAGS=..\roken\Release\roken.lib kernel32.lib user32.lib gdi32.lib\\r winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\\r uuid.lib /nologo /subsystem:windows /dll /incremental:no\\r /pdb:"$(OUTDIR)\des.pdb" /machine:I386 /def:".\des.def"\\r /out:"$(OUTDIR)\des.dll" /implib:"$(OUTDIR)\des.lib" \rDEF_FILE= \\r        ".\des.def"\rLINK32_OBJS= \\r     "$(INTDIR)\cbc3_enc.obj" \\r     "$(INTDIR)\cbc_cksm.obj" \\r     "$(INTDIR)\cbc_enc.obj" \\r      "$(INTDIR)\cfb64ede.obj" \\r     "$(INTDIR)\cfb64enc.obj" \\r     "$(INTDIR)\cfb_enc.obj" \\r      "$(INTDIR)\des_enc.obj" \\r      "$(INTDIR)\dllmain.obj" \\r      "$(INTDIR)\ecb3_enc.obj" \\r     "$(INTDIR)\ecb_enc.obj" \\r      "$(INTDIR)\ede_enc.obj" \\r      "$(INTDIR)\enc_read.obj" \\r     "$(INTDIR)\enc_writ.obj" \\r     "$(INTDIR)\fcrypt.obj" \\r       "$(INTDIR)\key_par.obj" \\r      "$(INTDIR)\ncbc_enc.obj" \\r     "$(INTDIR)\ofb64ede.obj" \\r     "$(INTDIR)\ofb64enc.obj" \\r     "$(INTDIR)\ofb_enc.obj" \\r      "$(INTDIR)\passwd_dialog.res" \\r        "$(INTDIR)\passwd_dlg.obj" \\r   "$(INTDIR)\pcbc_enc.obj" \\r     "$(INTDIR)\qud_cksm.obj" \\r     "$(INTDIR)\read_pwd.obj" \\r     "$(INTDIR)\rnd_keys.obj" \\r     "$(INTDIR)\rpc_enc.obj" \\r      "$(INTDIR)\set_key.obj" \\r      "$(INTDIR)\str2key.obj" \\r      "$(INTDIR)\supp.obj" \\r "..\roken\Release\roken.lib"\r\r"$(OUTDIR)\des.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r    $(LINK32) @<<\r  $(LINK32_FLAGS) $(LINK32_OBJS)\r<<\r\r!ELSEIF  "$(CFG)" == "des - Win32 Debug"\r\rOUTDIR=.\Debug\rINTDIR=.\Debug\r# Begin Custom Macros\rOutDir=.\.\Debug\r# End Custom Macros\r\r!IF "$(RECURSE)" == "0" \r\rALL : "$(OUTDIR)\des.dll"\r\r!ELSE \r\rALL : "roken - Win32 Debug" "$(OUTDIR)\des.dll"\r\r!ENDIF \r\r!IF "$(RECURSE)" == "1" \rCLEAN :"roken - Win32 DebugCLEAN" \r!ELSE \rCLEAN : \r!ENDIF \r       -@erase "$(INTDIR)\cbc3_enc.obj"\r       -@erase "$(INTDIR)\cbc_cksm.obj"\r       -@erase "$(INTDIR)\cbc_enc.obj"\r        -@erase "$(INTDIR)\cfb64ede.obj"\r       -@erase "$(INTDIR)\cfb64enc.obj"\r       -@erase "$(INTDIR)\cfb_enc.obj"\r        -@erase "$(INTDIR)\des_enc.obj"\r        -@erase "$(INTDIR)\dllmain.obj"\r        -@erase "$(INTDIR)\ecb3_enc.obj"\r       -@erase "$(INTDIR)\ecb_enc.obj"\r        -@erase "$(INTDIR)\ede_enc.obj"\r        -@erase "$(INTDIR)\enc_read.obj"\r       -@erase "$(INTDIR)\enc_writ.obj"\r       -@erase "$(INTDIR)\fcrypt.obj"\r -@erase "$(INTDIR)\key_par.obj"\r        -@erase "$(INTDIR)\ncbc_enc.obj"\r       -@erase "$(INTDIR)\ofb64ede.obj"\r       -@erase "$(INTDIR)\ofb64enc.obj"\r       -@erase "$(INTDIR)\ofb_enc.obj"\r        -@erase "$(INTDIR)\passwd_dialog.res"\r  -@erase "$(INTDIR)\passwd_dlg.obj"\r     -@erase "$(INTDIR)\pcbc_enc.obj"\r       -@erase "$(INTDIR)\qud_cksm.obj"\r       -@erase "$(INTDIR)\read_pwd.obj"\r       -@erase "$(INTDIR)\rnd_keys.obj"\r       -@erase "$(INTDIR)\rpc_enc.obj"\r        -@erase "$(INTDIR)\set_key.obj"\r        -@erase "$(INTDIR)\str2key.obj"\r        -@erase "$(INTDIR)\supp.obj"\r   -@erase "$(INTDIR)\vc50.idb"\r   -@erase "$(INTDIR)\vc50.pdb"\r   -@erase "$(OUTDIR)\des.dll"\r    -@erase "$(OUTDIR)\des.exp"\r    -@erase "$(OUTDIR)\des.ilk"\r    -@erase "$(OUTDIR)\des.lib"\r    -@erase "$(OUTDIR)\des.pdb"\r\r"$(OUTDIR)" :\r    if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r\rCPP=cl.exe\rCPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\roken" /I "." /I\\r "..\..\include" /I "..\..\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS"\\r /D "HAVE_CONFIG_H" /Fp"$(INTDIR)\des.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\"\\r /FD /c \rCPP_OBJS=.\Debug/\rCPP_SBRS=.\r\r.c{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cpp{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cxx{$(CPP_OBJS)}.obj::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.c{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cpp{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\r.cxx{$(CPP_SBRS)}.sbr::\r   $(CPP) @<<\r   $(CPP_PROJ) $< \r<<\r\rMTL=midl.exe\rMTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 \rRSC=rc.exe\rRSC_PROJ=/l 0x409 /fo"$(INTDIR)\passwd_dialog.res" /d "_DEBUG" \rBSC32=bscmake.exe\rBSC32_FLAGS=/nologo /o"$(OUTDIR)\des.bsc" \rBSC32_SBRS= \\r       \rLINK32=link.exe\rLINK32_FLAGS=..\roken\Debug\roken.lib kernel32.lib user32.lib gdi32.lib\\r winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib\\r uuid.lib /nologo /subsystem:windows /dll /incremental:yes\\r /pdb:"$(OUTDIR)\des.pdb" /debug /machine:I386 /def:".\des.def"\\r /out:"$(OUTDIR)\des.dll" /implib:"$(OUTDIR)\des.lib" \rDEF_FILE= \\r  ".\des.def"\rLINK32_OBJS= \\r     "$(INTDIR)\cbc3_enc.obj" \\r     "$(INTDIR)\cbc_cksm.obj" \\r     "$(INTDIR)\cbc_enc.obj" \\r      "$(INTDIR)\cfb64ede.obj" \\r     "$(INTDIR)\cfb64enc.obj" \\r     "$(INTDIR)\cfb_enc.obj" \\r      "$(INTDIR)\des_enc.obj" \\r      "$(INTDIR)\dllmain.obj" \\r      "$(INTDIR)\ecb3_enc.obj" \\r     "$(INTDIR)\ecb_enc.obj" \\r      "$(INTDIR)\ede_enc.obj" \\r      "$(INTDIR)\enc_read.obj" \\r     "$(INTDIR)\enc_writ.obj" \\r     "$(INTDIR)\fcrypt.obj" \\r       "$(INTDIR)\key_par.obj" \\r      "$(INTDIR)\ncbc_enc.obj" \\r     "$(INTDIR)\ofb64ede.obj" \\r     "$(INTDIR)\ofb64enc.obj" \\r     "$(INTDIR)\ofb_enc.obj" \\r      "$(INTDIR)\passwd_dialog.res" \\r        "$(INTDIR)\passwd_dlg.obj" \\r   "$(INTDIR)\pcbc_enc.obj" \\r     "$(INTDIR)\qud_cksm.obj" \\r     "$(INTDIR)\read_pwd.obj" \\r     "$(INTDIR)\rnd_keys.obj" \\r     "$(INTDIR)\rpc_enc.obj" \\r      "$(INTDIR)\set_key.obj" \\r      "$(INTDIR)\str2key.obj" \\r      "$(INTDIR)\supp.obj" \\r "..\roken\Debug\roken.lib"\r\r"$(OUTDIR)\des.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r    $(LINK32) @<<\r  $(LINK32_FLAGS) $(LINK32_OBJS)\r<<\r\r!ENDIF \r\r\r!IF "$(CFG)" == "des - Win32 Release" || "$(CFG)" == "des - Win32 Debug"\rSOURCE=.\cbc3_enc.c\rDEP_CPP_CBC3_=\\r "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r\r\r"$(INTDIR)\cbc3_enc.obj" : $(SOURCE) $(DEP_CPP_CBC3_) "$(INTDIR)"\r\r\rSOURCE=.\cbc_cksm.c\rDEP_CPP_CBC_C=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\cbc_cksm.obj" : $(SOURCE) $(DEP_CPP_CBC_C) "$(INTDIR)"\r\r\rSOURCE=.\cbc_enc.c\rDEP_CPP_CBC_E=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\cbc_enc.obj" : $(SOURCE) $(DEP_CPP_CBC_E) "$(INTDIR)"\r\r\rSOURCE=.\cfb64ede.c\rDEP_CPP_CFB64=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\cfb64ede.obj" : $(SOURCE) $(DEP_CPP_CFB64) "$(INTDIR)"\r\r\rSOURCE=.\cfb64enc.c\rDEP_CPP_CFB64E=\\r     "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\cfb64enc.obj" : $(SOURCE) $(DEP_CPP_CFB64E) "$(INTDIR)"\r\r\rSOURCE=.\cfb_enc.c\rDEP_CPP_CFB_E=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\cfb_enc.obj" : $(SOURCE) $(DEP_CPP_CFB_E) "$(INTDIR)"\r\r\rSOURCE=.\des_enc.c\rDEP_CPP_DES_E=\\r        "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\des_enc.obj" : $(SOURCE) $(DEP_CPP_DES_E) "$(INTDIR)"\r\r\rSOURCE=.\dllmain.c\rDEP_CPP_DLLMA=\\r        "..\..\include\win32\config.h"\\r        \r\r"$(INTDIR)\dllmain.obj" : $(SOURCE) $(DEP_CPP_DLLMA) "$(INTDIR)"\r\r\rSOURCE=.\ecb3_enc.c\rDEP_CPP_ECB3_=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r\r\r"$(INTDIR)\ecb3_enc.obj" : $(SOURCE) $(DEP_CPP_ECB3_) "$(INTDIR)"\r\r\rSOURCE=.\ecb_enc.c\rDEP_CPP_ECB_E=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        ".\spr.h"\\r     \r\r"$(INTDIR)\ecb_enc.obj" : $(SOURCE) $(DEP_CPP_ECB_E) "$(INTDIR)"\r\r\rSOURCE=.\ede_enc.c\rDEP_CPP_EDE_E=\\r        "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\ede_enc.obj" : $(SOURCE) $(DEP_CPP_EDE_E) "$(INTDIR)"\r\r\rSOURCE=.\enc_read.c\rDEP_CPP_ENC_R=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\enc_read.obj" : $(SOURCE) $(DEP_CPP_ENC_R) "$(INTDIR)"\r\r\rSOURCE=.\enc_writ.c\rDEP_CPP_ENC_W=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\enc_writ.obj" : $(SOURCE) $(DEP_CPP_ENC_W) "$(INTDIR)"\r\r\rSOURCE=.\fcrypt.c\rDEP_CPP_FCRYP=\\r        "..\..\include\win32\config.h"\\r        "..\..\include\win32\ktypes.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        ".\md5.h"\\r     {$(INCLUDE)}"sys\types.h"\\r     \r\r"$(INTDIR)\fcrypt.obj" : $(SOURCE) $(DEP_CPP_FCRYP) "$(INTDIR)"\r\r\rSOURCE=.\key_par.c\rDEP_CPP_KEY_P=\\r "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\key_par.obj" : $(SOURCE) $(DEP_CPP_KEY_P) "$(INTDIR)"\r\r\rSOURCE=.\ncbc_enc.c\rDEP_CPP_NCBC_=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\ncbc_enc.obj" : $(SOURCE) $(DEP_CPP_NCBC_) "$(INTDIR)"\r\r\rSOURCE=.\ofb64ede.c\rDEP_CPP_OFB64=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\ofb64ede.obj" : $(SOURCE) $(DEP_CPP_OFB64) "$(INTDIR)"\r\r\rSOURCE=.\ofb64enc.c\rDEP_CPP_OFB64E=\\r     "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\ofb64enc.obj" : $(SOURCE) $(DEP_CPP_OFB64E) "$(INTDIR)"\r\r\rSOURCE=.\ofb_enc.c\rDEP_CPP_OFB_E=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\ofb_enc.obj" : $(SOURCE) $(DEP_CPP_OFB_E) "$(INTDIR)"\r\r\rSOURCE=.\passwd_dlg.c\rDEP_CPP_PASSW=\\r     "..\..\include\win32\config.h"\\r        ".\passwd_dlg.h"\\r      \r\r"$(INTDIR)\passwd_dlg.obj" : $(SOURCE) $(DEP_CPP_PASSW) "$(INTDIR)"\r\r\rSOURCE=.\pcbc_enc.c\rDEP_CPP_PCBC_=\\r    "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\pcbc_enc.obj" : $(SOURCE) $(DEP_CPP_PCBC_) "$(INTDIR)"\r\r\rSOURCE=.\qud_cksm.c\rDEP_CPP_QUD_C=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\qud_cksm.obj" : $(SOURCE) $(DEP_CPP_QUD_C) "$(INTDIR)"\r\r\rSOURCE=.\read_pwd.c\rDEP_CPP_READ_=\\r      "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\read_pwd.obj" : $(SOURCE) $(DEP_CPP_READ_) "$(INTDIR)"\r\r\rSOURCE=.\rnd_keys.c\rDEP_CPP_RND_K=\\r      "..\..\include\win32\config.h"\\r        "..\..\include\win32\ktypes.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        {$(INCLUDE)}"sys\types.h"\\r     \r\r"$(INTDIR)\rnd_keys.obj" : $(SOURCE) $(DEP_CPP_RND_K) "$(INTDIR)"\r\r\rSOURCE=.\rpc_enc.c\rDEP_CPP_RPC_E=\\r       "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        ".\des_ver.h"\\r ".\rpc_des.h"\\r \r\r"$(INTDIR)\rpc_enc.obj" : $(SOURCE) $(DEP_CPP_RPC_E) "$(INTDIR)"\r\r\rSOURCE=.\set_key.c\rDEP_CPP_SET_K=\\r        "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        ".\podd.h"\\r    ".\sk.h"\\r      \r\r"$(INTDIR)\set_key.obj" : $(SOURCE) $(DEP_CPP_SET_K) "$(INTDIR)"\r\r\rSOURCE=.\str2key.c\rDEP_CPP_STR2K=\\r        "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\str2key.obj" : $(SOURCE) $(DEP_CPP_STR2K) "$(INTDIR)"\r\r\rSOURCE=.\supp.c\rDEP_CPP_SUPP_=\\r   "..\..\include\win32\config.h"\\r        ".\des.h"\\r     ".\des_locl.h"\\r        \r\r"$(INTDIR)\supp.obj" : $(SOURCE) $(DEP_CPP_SUPP_) "$(INTDIR)"\r\r\rSOURCE=.\passwd_dialog.rc\r\r"$(INTDIR)\passwd_dialog.res" : $(SOURCE) "$(INTDIR)"\r     $(RSC) $(RSC_PROJ) $(SOURCE)\r   \r\r!IF  "$(CFG)" == "des - Win32 Release"\r\r"roken - Win32 Release" : \r   cd "\tmp\wirus-krb\krb4-pre-0.9.9\lib\roken"\r   $(MAKE) /$(MAKEFLAGS) /F ".\roken.mak" CFG="roken - Win32 Release" \r   cd "..\des"\r\r"roken - Win32 ReleaseCLEAN" : \r   cd "\tmp\wirus-krb\krb4-pre-0.9.9\lib\roken"\r   $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\roken.mak" CFG="roken - Win32 Release"\\r RECURSE=1 \r   cd "..\des"\r\r!ELSEIF  "$(CFG)" == "des - Win32 Debug"\r\r"roken - Win32 Debug" : \r   cd "\tmp\wirus-krb\krb4-pre-0.9.9\lib\roken"\r   $(MAKE) /$(MAKEFLAGS) /F ".\roken.mak" CFG="roken - Win32 Debug" \r   cd "..\des"\r\r"roken - Win32 DebugCLEAN" : \r   cd "\tmp\wirus-krb\krb4-pre-0.9.9\lib\roken"\r   $(MAKE) /$(MAKEFLAGS) CLEAN /F ".\roken.mak" CFG="roken - Win32 Debug"\\r RECURSE=1 \r   cd "..\des"\r\r!ENDIF \r\r\r!ENDIF \r\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.man b/mac/libdes/src/des.man
new file mode 100755 (executable)
index 0000000..658bf92
--- /dev/null
@@ -0,0 +1 @@
+.TH DES 1 \r.SH NAME\rdes - encrypt or decrypt data using Data Encryption Standard\r.SH SYNOPSIS\r.B des\r(\r.B \-e\r|\r.B \-E\r) | (\r.B \-d\r|\r.B \-D\r) | (\r.B \-\fR[\fPcC\fR][\fPckname\fR]\fP\r) |\r[\r.B \-b3hfs\r] [\r.B \-k\r.I key\r]\r] [\r.B \-u\fR[\fIuuname\fR]\r[\r.I input-file\r[\r.I output-file\r] ]\r.SH DESCRIPTION\r.B des\rencrypts and decrypts data using the\rData Encryption Standard algorithm.\rOne of\r.B \-e, \-E\r(for encrypt) or\r.B \-d, \-D\r(for decrypt) must be specified.\rIt is also possible to use\r.B \-c\ror\r.B \-C\rin conjunction or instead of the a encrypt/decrypt option to generate\ra 16 character hexadecimal checksum, generated via the\r.I des_cbc_cksum.\r.LP\rTwo standard encryption modes are supported by the\r.B des\rprogram, Cipher Block Chaining (the default) and Electronic Code Book\r(specified with\r.B \-b\r).\r.LP\rThe key used for the DES\ralgorithm is obtained by prompting the user unless the\r.B `\-k\r.I key'\roption is given.\rIf the key is an argument to the\r.B des\rcommand, it is potentially visible to users executing\r.BR ps (1)\ror a derivative.  To minimise this possibility,\r.B des\rtakes care to destroy the key argument immediately upon entry.\rIf your shell keeps a history file be careful to make sure it is not\rworld readable.\r.LP\rSince this program attempts to maintain compatability with sunOS's\rdes(1) command, there are 2 different methods used to convert the user\rsupplied key to a des key.\rWhenever and one or more of\r.B \-E, \-D, \-C\ror\r.B \-3\roptions are used, the key conversion procedure will not be compatible\rwith the sunOS des(1) version but will use all the user supplied\rcharacter to generate the des key.\r.B des\rcommand reads from standard input unless\r.I input-file\ris specified and writes to standard output unless\r.I output-file\ris given.\r.SH OPTIONS\r.TP\r.B \-b\rSelect ECB\r(eight bytes at a time) encryption mode.\r.TP\r.B \-3\rEncrypt using triple encryption.\rBy default triple cbc encryption is used but if the\r.B \-b\roption is used then triple ecb encryption is performed.\rIf the key is less than 8 characters long, the flag has no effect.\r.TP\r.B \-e\rEncrypt data using an 8 byte key in a manner compatible with sunOS\rdes(1).\r.TP\r.B \-E\rEncrypt data using a key of nearly unlimited length (1024 bytes).\rThis will product a more secure encryption.\r.TP\r.B \-d\rDecrypt data that was encrypted with the \-e option.\r.TP\r.B \-D\rDecrypt data that was encrypted with the \-E option.\r.TP\r.B \-c\rGenerate a 16 character hexadecimal cbc checksum and output this to\rstderr.\rIf a filename was specified after the\r.B \-c\roption, the checksum is output to that file.\rThe checksum is generated using a key generated in a sunOS compatible\rmanner.\r.TP\r.B \-C\rA cbc checksum is generated in the same manner as described for the\r.B \-c\roption but the DES key is generated in the same manner as used for the\r.B \-E\rand\r.B \-D\roptions\r.TP\r.B \-f\rDoes nothing - allowed for compatibility with sunOS des(1) command.\r.TP\r.B \-s\rDoes nothing - allowed for compatibility with sunOS des(1) command.\r.TP\r.B "\-k \fIkey\fP"\rUse the encryption \r.I key\rspecified.\r.TP\r.B "\-h"\rThe\r.I key\ris assumed to be a 16 character hexadecimal number.\rIf the\r.B "\-3"\roption is used the key is assumed to be a 32 character hexadecimal\rnumber.\r.TP\r.B \-u\rThis flag is used to read and write uuencoded files.  If decrypting,\rthe input file is assumed to contain uuencoded, DES encrypted data.\rIf encrypting, the characters following the -u are used as the name of\rthe uuencoded file to embed in the begin line of the uuencoded\routput.  If there is no name specified after the -u, the name text.des\rwill be embedded in the header.\r.SH SEE ALSO\r.B ps (1)\r.B des_crypt(3)\r.SH BUGS\r.LP\rThe problem with using the\r.B -e\roption is the short key length.\rIt would be better to use a real 56-bit key rather than an\rASCII-based 56-bit pattern.  Knowing that the key was derived from ASCII\rradically reduces the time necessary for a brute-force cryptographic attack.\rMy attempt to remove this problem is to add an alternative text-key to\rDES-key function.  This alternative function (accessed via\r.B -E, -D, -S\rand\r.B -3\r)\ruses DES to help generate the key.\r.LP\rBe carefully when using the -u option.  Doing des -ud <filename> will\rnot decrypt filename (the -u option will gobble the d option).\r.LP\rThe VMS operating system operates in a world where files are always a\rmultiple of 512 bytes.  This causes problems when encrypted data is\rsend from unix to VMS since a 88 byte file will suddenly be padded\rwith 424 null bytes.  To get around this problem, use the -u option\rto uuencode the data before it is send to the VMS system.\r.SH AUTHOR\r.LP\rEric Young (eay@mincom.oz.au or eay@psych.psy.uq.oz.au)\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.org b/mac/libdes/src/des.org
new file mode 100755 (executable)
index 0000000..dcf79a5
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#ifndef HEADER_DES_H\r#define HEADER_DES_H\r\r#ifdef  __cplusplus\rextern "C" {\r#endif\r\r#include <stdio.h>\r\r/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a\r * %20 speed up (longs are 8 bytes, int's are 4). */\r#ifndef DES_LONG\r#define DES_LONG unsigned long\r#endif\r\rtypedef unsigned char des_cblock[8];\rtypedef struct des_ks_struct\r     {\r      union   {\r              des_cblock _;\r          /* make sure things are correct size on machines with\r           * 8 byte longs */\r             DES_LONG pad[2];\r               } ks;\r#undef _\r#define _        ks._\r   } des_key_schedule[16];\r\r#define DES_KEY_SZ     (sizeof(des_cblock))\r#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))\r\r#define DES_ENCRYPT    1\r#define DES_DECRYPT   0\r\r#define DES_CBC_MODE 0\r#define DES_PCBC_MODE 1\r\r#define des_ecb2_encrypt(i,o,k1,k2,e) \\r     des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))\r\r#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \\r des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))\r\r#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \\r        des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))\r\r#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \\r    des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))\r\r#define C_Block des_cblock\r#define Key_schedule des_key_schedule\r#ifdef KERBEROS\r#define ENCRYPT DES_ENCRYPT\r#define DECRYPT DES_DECRYPT\r#endif\r#define KEY_SZ DES_KEY_SZ\r#define string_to_key des_string_to_key\r#define read_pw_string des_read_pw_string\r#define random_key des_random_key\r#define pcbc_encrypt des_pcbc_encrypt\r#define set_key des_set_key\r#define key_sched des_key_sched\r#define ecb_encrypt des_ecb_encrypt\r#define cbc_encrypt des_cbc_encrypt\r#define ncbc_encrypt des_ncbc_encrypt\r#define xcbc_encrypt des_xcbc_encrypt\r#define cbc_cksum des_cbc_cksum\r#define quad_cksum des_quad_cksum\r\r/* For compatibility with the MIT lib - eay 20/05/92 */\rtypedef des_key_schedule bit_64;\r#define des_fixup_key_parity des_set_odd_parity\r#define des_check_key_parity check_parity\r\rextern int des_check_key;       /* defaults to false */\rextern int des_rw_mode;         /* defaults to DES_PCBC_MODE */\r\r/* The next line is used to disable full ANSI prototypes, if your\r * compiler has problems with the prototypes, make sure this line always\r * evaluates to true :-) */\r#if defined(MSDOS) || defined(__STDC__)\r#undef NOPROTO\r#endif\r#ifndef NOPROTO\rchar *des_options(void);\rvoid des_ecb3_encrypt(des_cblock *input,des_cblock *output,\r     des_key_schedule ks1,des_key_schedule ks2,\r     des_key_schedule ks3, int enc);\rDES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,\r   long length,des_key_schedule schedule,des_cblock *ivec);\rvoid des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,\r        des_key_schedule schedule,des_cblock *ivec,int enc);\rvoid des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,\r   des_key_schedule schedule,des_cblock *ivec,int enc);\rvoid des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,\r   des_key_schedule schedule,des_cblock *ivec,\r    des_cblock *inw,des_cblock *outw,int enc);\rvoid des_3cbc_encrypt(des_cblock *input,des_cblock *output,long length,\r     des_key_schedule sk1,des_key_schedule sk2,\r     des_cblock *ivec1,des_cblock *ivec2,int enc);\rvoid des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,\r   long length,des_key_schedule schedule,des_cblock *ivec,int enc);\rvoid des_ecb_encrypt(des_cblock *input,des_cblock *output,\r    des_key_schedule ks,int enc);\rvoid des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);\rvoid des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);\rvoid des_encrypt3(DES_LONG *data, des_key_schedule ks1,\r   des_key_schedule ks2, des_key_schedule ks3);\rvoid des_decrypt3(DES_LONG *data, des_key_schedule ks1,\r   des_key_schedule ks2, des_key_schedule ks3);\rvoid des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, \r long length, des_key_schedule ks1, des_key_schedule ks2, \r      des_key_schedule ks3, des_cblock *ivec, int enc);\rvoid des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,\r   long length, des_key_schedule ks1, des_key_schedule ks2,\r       des_key_schedule ks3, des_cblock *ivec, int *num, int encrypt);\rvoid des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,\r     long length, des_key_schedule ks1, des_key_schedule ks2,\r       des_key_schedule ks3, des_cblock *ivec, int *num);\r\rint des_enc_read(int fd,char *buf,int len,des_key_schedule sched,\r  des_cblock *iv);\rint des_enc_write(int fd,char *buf,int len,des_key_schedule sched,\r    des_cblock *iv);\rchar *des_fcrypt(const char *buf,const char *salt, char *ret);\r#ifdef PERL5\rchar *des_crypt(const char *buf,const char *salt);\r#else\r/* some stupid compilers complain because I have declared char instead\r * of const char */\r#ifdef HEADER_DES_LOCL_H\rchar *crypt(const char *buf,const char *salt);\r#else\rchar *crypt();\r#endif\r#endif\rvoid des_ofb_encrypt(unsigned char *in,unsigned char *out,\r int numbits,long length,des_key_schedule schedule,des_cblock *ivec);\rvoid des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,\r   des_key_schedule schedule,des_cblock *ivec,int enc);\rDES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,\r     long length,int out_count,des_cblock *seed);\rvoid des_random_seed(des_cblock key);\rvoid des_random_key(des_cblock ret);\rint des_read_password(des_cblock *key,char *prompt,int verify);\rint des_read_2passwords(des_cblock *key1,des_cblock *key2,\r     char *prompt,int verify);\rint des_read_pw_string(char *buf,int length,char *prompt,int verify);\rvoid des_set_odd_parity(des_cblock *key);\rint des_is_weak_key(des_cblock *key);\rint des_set_key(des_cblock *key,des_key_schedule schedule);\rint des_key_sched(des_cblock *key,des_key_schedule schedule);\rvoid des_string_to_key(char *str,des_cblock *key);\rvoid des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);\rvoid des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,\r des_key_schedule schedule, des_cblock *ivec, int *num, int enc);\rvoid des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,\r    des_key_schedule schedule, des_cblock *ivec, int *num);\r\r/* Extra functions from Mark Murray <mark@grondar.za> */\rvoid des_cblock_print_file(des_cblock *cb, FILE *fp);\r/* The following functions are not in the normal unix build or the\r * SSLeay build.  When using the SSLeay build, use RAND_seed()\r * and RAND_bytes() instead. */\rint des_new_random_key(des_cblock *key);\rvoid des_init_random_number_generator(des_cblock *key);\rvoid des_set_random_generator_seed(des_cblock *key);\rvoid des_set_sequence_number(des_cblock new_sequence_number);\rvoid des_generate_random_block(des_cblock *block);\r\r#else\r\rchar *des_options();\rvoid des_ecb3_encrypt();\rDES_LONG des_cbc_cksum();\rvoid des_cbc_encrypt();\rvoid des_ncbc_encrypt();\rvoid des_xcbc_encrypt();\rvoid des_3cbc_encrypt();\rvoid des_cfb_encrypt();\rvoid des_ede3_cfb64_encrypt();\rvoid des_ede3_ofb64_encrypt();\rvoid des_ecb_encrypt();\rvoid des_encrypt();\rvoid des_encrypt2();\rvoid des_encrypt3();\rvoid des_decrypt3();\rvoid des_ede3_cbc_encrypt();\rint des_enc_read();\rint des_enc_write();\rchar *des_fcrypt();\r#ifdef PERL5\rchar *des_crypt();\r#else\rchar *crypt();\r#endif\rvoid des_ofb_encrypt();\rvoid des_pcbc_encrypt();\rDES_LONG des_quad_cksum();\rvoid des_random_seed();\rvoid des_random_key();\rint des_read_password();\rint des_read_2passwords();\rint des_read_pw_string();\rvoid des_set_odd_parity();\rint des_is_weak_key();\rint des_set_key();\rint des_key_sched();\rvoid des_string_to_key();\rvoid des_string_to_2keys();\rvoid des_cfb64_encrypt();\rvoid des_ofb64_encrypt();\r\r/* Extra functions from Mark Murray <mark@grondar.za> */\rvoid des_cblock_print_file();\r/* The following functions are not in the normal unix build or the\r * SSLeay build.  When using the SSLeay build, use RAND_seed()\r * and RAND_bytes() instead. */\r#ifdef FreeBSD\rint des_new_random_key();\rvoid des_init_random_number_generator();\rvoid des_set_random_generator_seed();\rvoid des_set_sequence_number();\rvoid des_generate_random_block();\r#endif\r\r#endif\r\r#ifdef  __cplusplus\r}\r#endif\r\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/des.pl b/mac/libdes/src/des.pl
new file mode 100755 (executable)
index 0000000..fbc808a
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r# des.pl - eric young 22/11/1991 eay@mincom.oz.au or eay@psych.psy.uq.oz.au\r#\r# Copyright (C) 1993 Eric Young\r#\r# 11 April 1996 - patched to circumvent Perl 5 (through 5.002) problem\r#                 with sign-extension on right shift operations.\r#                 Ed Kubaitis - ejk@uiuc.edu\r#\r# eay - 92/08/31 - I think I have fixed all problems for 64bit\r# versions of perl but I could be wrong since I have not tested it yet :-).\r#\r# This is an implementation of DES in perl.\r# The two routines (des_set_key and des_ecb_encrypt)\r# take 8 byte objects as arguments.\r#\r# des_set_key takes an 8 byte string as a key and returns a key schedule\r# for use in calls to des_ecb_encrypt.\r# des_ecb_encrypt takes three arguments, the first is a key schedule\r# (make sure to pass it by reference with the *), the second is 1\r# to encrypt, 0 to decrypt.  The third argument is an 8 byte object\r# to encrypt.  The function returns an 8 byte object that has been\r# DES encrypted.\r#\r# example:\r# require 'des.pl'\r#\r# $key =pack("C8",0x12,0x23,0x45,0x67,0x89,0xab,0xcd,0xef);\r# @ks=  &des_set_key($key);\r#\r# $outbytes= &des_ecb_encrypt(*ks,1,$data);\r# @enc =unpack("C8",$outbytes);\r#\r                 \rpackage des;\r\reval("usr integer;") if (int($]) > 4);\r\r# The following 8 arrays are used in des_set_key\r@skb0=(\r# for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 \r0x00000000,0x00000010,0x20000000,0x20000010,\r0x00010000,0x00010010,0x20010000,0x20010010,\r0x00000800,0x00000810,0x20000800,0x20000810,\r0x00010800,0x00010810,0x20010800,0x20010810,\r0x00000020,0x00000030,0x20000020,0x20000030,\r0x00010020,0x00010030,0x20010020,0x20010030,\r0x00000820,0x00000830,0x20000820,0x20000830,\r0x00010820,0x00010830,0x20010820,0x20010830,\r0x00080000,0x00080010,0x20080000,0x20080010,\r0x00090000,0x00090010,0x20090000,0x20090010,\r0x00080800,0x00080810,0x20080800,0x20080810,\r0x00090800,0x00090810,0x20090800,0x20090810,\r0x00080020,0x00080030,0x20080020,0x20080030,\r0x00090020,0x00090030,0x20090020,0x20090030,\r0x00080820,0x00080830,0x20080820,0x20080830,\r0x00090820,0x00090830,0x20090820,0x20090830,\r);\r@skb1=(\r# for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 \r0x00000000,0x02000000,0x00002000,0x02002000,\r0x00200000,0x02200000,0x00202000,0x02202000,\r0x00000004,0x02000004,0x00002004,0x02002004,\r0x00200004,0x02200004,0x00202004,0x02202004,\r0x00000400,0x02000400,0x00002400,0x02002400,\r0x00200400,0x02200400,0x00202400,0x02202400,\r0x00000404,0x02000404,0x00002404,0x02002404,\r0x00200404,0x02200404,0x00202404,0x02202404,\r0x10000000,0x12000000,0x10002000,0x12002000,\r0x10200000,0x12200000,0x10202000,0x12202000,\r0x10000004,0x12000004,0x10002004,0x12002004,\r0x10200004,0x12200004,0x10202004,0x12202004,\r0x10000400,0x12000400,0x10002400,0x12002400,\r0x10200400,0x12200400,0x10202400,0x12202400,\r0x10000404,0x12000404,0x10002404,0x12002404,\r0x10200404,0x12200404,0x10202404,0x12202404,\r);\r@skb2=(\r# for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 \r0x00000000,0x00000001,0x00040000,0x00040001,\r0x01000000,0x01000001,0x01040000,0x01040001,\r0x00000002,0x00000003,0x00040002,0x00040003,\r0x01000002,0x01000003,0x01040002,0x01040003,\r0x00000200,0x00000201,0x00040200,0x00040201,\r0x01000200,0x01000201,0x01040200,0x01040201,\r0x00000202,0x00000203,0x00040202,0x00040203,\r0x01000202,0x01000203,0x01040202,0x01040203,\r0x08000000,0x08000001,0x08040000,0x08040001,\r0x09000000,0x09000001,0x09040000,0x09040001,\r0x08000002,0x08000003,0x08040002,0x08040003,\r0x09000002,0x09000003,0x09040002,0x09040003,\r0x08000200,0x08000201,0x08040200,0x08040201,\r0x09000200,0x09000201,0x09040200,0x09040201,\r0x08000202,0x08000203,0x08040202,0x08040203,\r0x09000202,0x09000203,0x09040202,0x09040203,\r);\r@skb3=(\r# for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 \r0x00000000,0x00100000,0x00000100,0x00100100,\r0x00000008,0x00100008,0x00000108,0x00100108,\r0x00001000,0x00101000,0x00001100,0x00101100,\r0x00001008,0x00101008,0x00001108,0x00101108,\r0x04000000,0x04100000,0x04000100,0x04100100,\r0x04000008,0x04100008,0x04000108,0x04100108,\r0x04001000,0x04101000,0x04001100,0x04101100,\r0x04001008,0x04101008,0x04001108,0x04101108,\r0x00020000,0x00120000,0x00020100,0x00120100,\r0x00020008,0x00120008,0x00020108,0x00120108,\r0x00021000,0x00121000,0x00021100,0x00121100,\r0x00021008,0x00121008,0x00021108,0x00121108,\r0x04020000,0x04120000,0x04020100,0x04120100,\r0x04020008,0x04120008,0x04020108,0x04120108,\r0x04021000,0x04121000,0x04021100,0x04121100,\r0x04021008,0x04121008,0x04021108,0x04121108,\r);\r@skb4=(\r# for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 \r0x00000000,0x10000000,0x00010000,0x10010000,\r0x00000004,0x10000004,0x00010004,0x10010004,\r0x20000000,0x30000000,0x20010000,0x30010000,\r0x20000004,0x30000004,0x20010004,0x30010004,\r0x00100000,0x10100000,0x00110000,0x10110000,\r0x00100004,0x10100004,0x00110004,0x10110004,\r0x20100000,0x30100000,0x20110000,0x30110000,\r0x20100004,0x30100004,0x20110004,0x30110004,\r0x00001000,0x10001000,0x00011000,0x10011000,\r0x00001004,0x10001004,0x00011004,0x10011004,\r0x20001000,0x30001000,0x20011000,0x30011000,\r0x20001004,0x30001004,0x20011004,0x30011004,\r0x00101000,0x10101000,0x00111000,0x10111000,\r0x00101004,0x10101004,0x00111004,0x10111004,\r0x20101000,0x30101000,0x20111000,0x30111000,\r0x20101004,0x30101004,0x20111004,0x30111004,\r);\r@skb5=(\r# for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 \r0x00000000,0x08000000,0x00000008,0x08000008,\r0x00000400,0x08000400,0x00000408,0x08000408,\r0x00020000,0x08020000,0x00020008,0x08020008,\r0x00020400,0x08020400,0x00020408,0x08020408,\r0x00000001,0x08000001,0x00000009,0x08000009,\r0x00000401,0x08000401,0x00000409,0x08000409,\r0x00020001,0x08020001,0x00020009,0x08020009,\r0x00020401,0x08020401,0x00020409,0x08020409,\r0x02000000,0x0A000000,0x02000008,0x0A000008,\r0x02000400,0x0A000400,0x02000408,0x0A000408,\r0x02020000,0x0A020000,0x02020008,0x0A020008,\r0x02020400,0x0A020400,0x02020408,0x0A020408,\r0x02000001,0x0A000001,0x02000009,0x0A000009,\r0x02000401,0x0A000401,0x02000409,0x0A000409,\r0x02020001,0x0A020001,0x02020009,0x0A020009,\r0x02020401,0x0A020401,0x02020409,0x0A020409,\r);\r@skb6=(\r# for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 \r0x00000000,0x00000100,0x00080000,0x00080100,\r0x01000000,0x01000100,0x01080000,0x01080100,\r0x00000010,0x00000110,0x00080010,0x00080110,\r0x01000010,0x01000110,0x01080010,0x01080110,\r0x00200000,0x00200100,0x00280000,0x00280100,\r0x01200000,0x01200100,0x01280000,0x01280100,\r0x00200010,0x00200110,0x00280010,0x00280110,\r0x01200010,0x01200110,0x01280010,0x01280110,\r0x00000200,0x00000300,0x00080200,0x00080300,\r0x01000200,0x01000300,0x01080200,0x01080300,\r0x00000210,0x00000310,0x00080210,0x00080310,\r0x01000210,0x01000310,0x01080210,0x01080310,\r0x00200200,0x00200300,0x00280200,0x00280300,\r0x01200200,0x01200300,0x01280200,0x01280300,\r0x00200210,0x00200310,0x00280210,0x00280310,\r0x01200210,0x01200310,0x01280210,0x01280310,\r);\r@skb7=(\r# for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 \r0x00000000,0x04000000,0x00040000,0x04040000,\r0x00000002,0x04000002,0x00040002,0x04040002,\r0x00002000,0x04002000,0x00042000,0x04042000,\r0x00002002,0x04002002,0x00042002,0x04042002,\r0x00000020,0x04000020,0x00040020,0x04040020,\r0x00000022,0x04000022,0x00040022,0x04040022,\r0x00002020,0x04002020,0x00042020,0x04042020,\r0x00002022,0x04002022,0x00042022,0x04042022,\r0x00000800,0x04000800,0x00040800,0x04040800,\r0x00000802,0x04000802,0x00040802,0x04040802,\r0x00002800,0x04002800,0x00042800,0x04042800,\r0x00002802,0x04002802,0x00042802,0x04042802,\r0x00000820,0x04000820,0x00040820,0x04040820,\r0x00000822,0x04000822,0x00040822,0x04040822,\r0x00002820,0x04002820,0x00042820,0x04042820,\r0x00002822,0x04002822,0x00042822,0x04042822,\r);\r\r@shifts2=(0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0);\r\r# used in ecb_encrypt\r@SP0=(\r0x00410100, 0x00010000, 0x40400000, 0x40410100,\r0x00400000, 0x40010100, 0x40010000, 0x40400000,\r0x40010100, 0x00410100, 0x00410000, 0x40000100,\r0x40400100, 0x00400000, 0x00000000, 0x40010000,\r0x00010000, 0x40000000, 0x00400100, 0x00010100,\r0x40410100, 0x00410000, 0x40000100, 0x00400100,\r0x40000000, 0x00000100, 0x00010100, 0x40410000,\r0x00000100, 0x40400100, 0x40410000, 0x00000000,\r0x00000000, 0x40410100, 0x00400100, 0x40010000,\r0x00410100, 0x00010000, 0x40000100, 0x00400100,\r0x40410000, 0x00000100, 0x00010100, 0x40400000,\r0x40010100, 0x40000000, 0x40400000, 0x00410000,\r0x40410100, 0x00010100, 0x00410000, 0x40400100,\r0x00400000, 0x40000100, 0x40010000, 0x00000000,\r0x00010000, 0x00400000, 0x40400100, 0x00410100,\r0x40000000, 0x40410000, 0x00000100, 0x40010100,\r);\r@SP1=(\r0x08021002, 0x00000000, 0x00021000, 0x08020000,\r0x08000002, 0x00001002, 0x08001000, 0x00021000,\r0x00001000, 0x08020002, 0x00000002, 0x08001000,\r0x00020002, 0x08021000, 0x08020000, 0x00000002,\r0x00020000, 0x08001002, 0x08020002, 0x00001000,\r0x00021002, 0x08000000, 0x00000000, 0x00020002,\r0x08001002, 0x00021002, 0x08021000, 0x08000002,\r0x08000000, 0x00020000, 0x00001002, 0x08021002,\r0x00020002, 0x08021000, 0x08001000, 0x00021002,\r0x08021002, 0x00020002, 0x08000002, 0x00000000,\r0x08000000, 0x00001002, 0x00020000, 0x08020002,\r0x00001000, 0x08000000, 0x00021002, 0x08001002,\r0x08021000, 0x00001000, 0x00000000, 0x08000002,\r0x00000002, 0x08021002, 0x00021000, 0x08020000,\r0x08020002, 0x00020000, 0x00001002, 0x08001000,\r0x08001002, 0x00000002, 0x08020000, 0x00021000,\r);\r@SP2=(\r0x20800000, 0x00808020, 0x00000020, 0x20800020,\r0x20008000, 0x00800000, 0x20800020, 0x00008020,\r0x00800020, 0x00008000, 0x00808000, 0x20000000,\r0x20808020, 0x20000020, 0x20000000, 0x20808000,\r0x00000000, 0x20008000, 0x00808020, 0x00000020,\r0x20000020, 0x20808020, 0x00008000, 0x20800000,\r0x20808000, 0x00800020, 0x20008020, 0x00808000,\r0x00008020, 0x00000000, 0x00800000, 0x20008020,\r0x00808020, 0x00000020, 0x20000000, 0x00008000,\r0x20000020, 0x20008000, 0x00808000, 0x20800020,\r0x00000000, 0x00808020, 0x00008020, 0x20808000,\r0x20008000, 0x00800000, 0x20808020, 0x20000000,\r0x20008020, 0x20800000, 0x00800000, 0x20808020,\r0x00008000, 0x00800020, 0x20800020, 0x00008020,\r0x00800020, 0x00000000, 0x20808000, 0x20000020,\r0x20800000, 0x20008020, 0x00000020, 0x00808000,\r);\r@SP3=(\r0x00080201, 0x02000200, 0x00000001, 0x02080201,\r0x00000000, 0x02080000, 0x02000201, 0x00080001,\r0x02080200, 0x02000001, 0x02000000, 0x00000201,\r0x02000001, 0x00080201, 0x00080000, 0x02000000,\r0x02080001, 0x00080200, 0x00000200, 0x00000001,\r0x00080200, 0x02000201, 0x02080000, 0x00000200,\r0x00000201, 0x00000000, 0x00080001, 0x02080200,\r0x02000200, 0x02080001, 0x02080201, 0x00080000,\r0x02080001, 0x00000201, 0x00080000, 0x02000001,\r0x00080200, 0x02000200, 0x00000001, 0x02080000,\r0x02000201, 0x00000000, 0x00000200, 0x00080001,\r0x00000000, 0x02080001, 0x02080200, 0x00000200,\r0x02000000, 0x02080201, 0x00080201, 0x00080000,\r0x02080201, 0x00000001, 0x02000200, 0x00080201,\r0x00080001, 0x00080200, 0x02080000, 0x02000201,\r0x00000201, 0x02000000, 0x02000001, 0x02080200,\r);\r@SP4=(\r0x01000000, 0x00002000, 0x00000080, 0x01002084,\r0x01002004, 0x01000080, 0x00002084, 0x01002000,\r0x00002000, 0x00000004, 0x01000004, 0x00002080,\r0x01000084, 0x01002004, 0x01002080, 0x00000000,\r0x00002080, 0x01000000, 0x00002004, 0x00000084,\r0x01000080, 0x00002084, 0x00000000, 0x01000004,\r0x00000004, 0x01000084, 0x01002084, 0x00002004,\r0x01002000, 0x00000080, 0x00000084, 0x01002080,\r0x01002080, 0x01000084, 0x00002004, 0x01002000,\r0x00002000, 0x00000004, 0x01000004, 0x01000080,\r0x01000000, 0x00002080, 0x01002084, 0x00000000,\r0x00002084, 0x01000000, 0x00000080, 0x00002004,\r0x01000084, 0x00000080, 0x00000000, 0x01002084,\r0x01002004, 0x01002080, 0x00000084, 0x00002000,\r0x00002080, 0x01002004, 0x01000080, 0x00000084,\r0x00000004, 0x00002084, 0x01002000, 0x01000004,\r);\r@SP5=(\r0x10000008, 0x00040008, 0x00000000, 0x10040400,\r0x00040008, 0x00000400, 0x10000408, 0x00040000,\r0x00000408, 0x10040408, 0x00040400, 0x10000000,\r0x10000400, 0x10000008, 0x10040000, 0x00040408,\r0x00040000, 0x10000408, 0x10040008, 0x00000000,\r0x00000400, 0x00000008, 0x10040400, 0x10040008,\r0x10040408, 0x10040000, 0x10000000, 0x00000408,\r0x00000008, 0x00040400, 0x00040408, 0x10000400,\r0x00000408, 0x10000000, 0x10000400, 0x00040408,\r0x10040400, 0x00040008, 0x00000000, 0x10000400,\r0x10000000, 0x00000400, 0x10040008, 0x00040000,\r0x00040008, 0x10040408, 0x00040400, 0x00000008,\r0x10040408, 0x00040400, 0x00040000, 0x10000408,\r0x10000008, 0x10040000, 0x00040408, 0x00000000,\r0x00000400, 0x10000008, 0x10000408, 0x10040400,\r0x10040000, 0x00000408, 0x00000008, 0x10040008,\r);\r@SP6=(\r0x00000800, 0x00000040, 0x00200040, 0x80200000,\r0x80200840, 0x80000800, 0x00000840, 0x00000000,\r0x00200000, 0x80200040, 0x80000040, 0x00200800,\r0x80000000, 0x00200840, 0x00200800, 0x80000040,\r0x80200040, 0x00000800, 0x80000800, 0x80200840,\r0x00000000, 0x00200040, 0x80200000, 0x00000840,\r0x80200800, 0x80000840, 0x00200840, 0x80000000,\r0x80000840, 0x80200800, 0x00000040, 0x00200000,\r0x80000840, 0x00200800, 0x80200800, 0x80000040,\r0x00000800, 0x00000040, 0x00200000, 0x80200800,\r0x80200040, 0x80000840, 0x00000840, 0x00000000,\r0x00000040, 0x80200000, 0x80000000, 0x00200040,\r0x00000000, 0x80200040, 0x00200040, 0x00000840,\r0x80000040, 0x00000800, 0x80200840, 0x00200000,\r0x00200840, 0x80000000, 0x80000800, 0x80200840,\r0x80200000, 0x00200840, 0x00200800, 0x80000800,\r);\r@SP7=(\r0x04100010, 0x04104000, 0x00004010, 0x00000000,\r0x04004000, 0x00100010, 0x04100000, 0x04104010,\r0x00000010, 0x04000000, 0x00104000, 0x00004010,\r0x00104010, 0x04004010, 0x04000010, 0x04100000,\r0x00004000, 0x00104010, 0x00100010, 0x04004000,\r0x04104010, 0x04000010, 0x00000000, 0x00104000,\r0x04000000, 0x00100000, 0x04004010, 0x04100010,\r0x00100000, 0x00004000, 0x04104000, 0x00000010,\r0x00100000, 0x00004000, 0x04000010, 0x04104010,\r0x00004010, 0x04000000, 0x00000000, 0x00104000,\r0x04100010, 0x04004010, 0x04004000, 0x00100010,\r0x04104000, 0x00000010, 0x00100010, 0x04004000,\r0x04104010, 0x00100000, 0x04100000, 0x04000010,\r0x00104000, 0x00004010, 0x04004010, 0x04100000,\r0x00000010, 0x04104000, 0x00104010, 0x00000000,\r0x04000000, 0x04100010, 0x00004000, 0x00104010,\r);\r\rsub main'des_set_key\r  {\r      local($param)=@_;\r      local(@key);\r   local($c,$d,$i,$s,$t);\r local(@ks)=();\r\r        # Get the bytes in the order we want.\r  @key=unpack("C8",$param);\r\r     $c=     ($key[0]    )|\r         ($key[1]<< 8)|\r         ($key[2]<<16)|\r         ($key[3]<<24);\r $d=     ($key[4]    )|\r         ($key[5]<< 8)|\r         ($key[6]<<16)|\r         ($key[7]<<24);\r\r        &doPC1(*c,*d);\r\r        for $i (@shifts2)\r              {\r              if ($i)\r                        {\r                      $c=($c>>2)|($c<<26);\r                   $d=($d>>2)|($d<<26);\r                   }\r              else\r                   {\r                      $c=($c>>1)|($c<<27);\r                   $d=($d>>1)|($d<<27);\r                   }\r              $c&=0x0fffffff;\r                $d&=0x0fffffff;\r                $s=     $skb0[ ($c    )&0x3f                 ]|\r                        $skb1[(($c>> 6)&0x03)|(($c>> 7)&0x3c)]|\r                        $skb2[(($c>>13)&0x0f)|(($c>>14)&0x30)]|\r                        $skb3[(($c>>20)&0x01)|(($c>>21)&0x06) |\r                                             (($c>>22)&0x38)];\r         $t=     $skb4[ ($d    )&0x3f                ]|\r                 $skb5[(($d>> 7)&0x03)|(($d>> 8)&0x3c)]|\r                        $skb6[ ($d>>15)&0x3f                 ]|\r                        $skb7[(($d>>21)&0x0f)|(($d>>22)&0x30)];\r                push(@ks,(($t<<16)|($s&0x0000ffff))&0xffffffff);\r               $s=      (($s>>16)&0x0000ffff)|($t&0xffff0000) ;\r               push(@ks,(($s<<4)|(($s>>28)&0xf))&0xffffffff);\r         }\r      @ks;\r   }\r\rsub doPC1\r   {\r      local(*a,*b)=@_;\r       local($t);\r\r    $t=(($b>>4)^$a)&0x0f0f0f0f;\r    $b^=($t<<4); $a^=$t;\r   # do $a first \r $t=(($a<<18)^$a)&0xcccc0000;\r   $a=$a^$t^(($t>>18)&0x00003fff);\r        $t=(($a<<17)^$a)&0xaaaa0000;\r   $a=$a^$t^(($t>>17)&0x00007fff);\r        $t=(($a<< 8)^$a)&0x00ff0000;\r   $a=$a^$t^(($t>> 8)&0x00ffffff);\r        $t=(($a<<17)^$a)&0xaaaa0000;\r   $a=$a^$t^(($t>>17)&0x00007fff);\r\r       # now do $b\r    $t=(($b<<24)^$b)&0xff000000;\r   $b=$b^$t^(($t>>24)&0x000000ff);\r        $t=(($b<< 8)^$b)&0x00ff0000;\r   $b=$b^$t^(($t>> 8)&0x00ffffff);\r        $t=(($b<<14)^$b)&0x33330000;\r   $b=$b^$t^(($t>>14)&0x0003ffff);\r        $b=(($b&0x00aa00aa)<<7)|(($b&0x55005500)>>7)|($b&0xaa55aa55);\r  $b=(($b>>8)&0x00ffffff)|((($a&0xf0000000)>>4)&0x0fffffff);\r     $a&=0x0fffffff;\r        }\r\rsub doIP\r    {\r      local(*a,*b)=@_;\r       local($t);\r\r    $t=(($b>> 4)^$a)&0x0f0f0f0f;\r   $b^=($t<< 4); $a^=$t;\r  $t=(($a>>16)^$b)&0x0000ffff;\r   $a^=($t<<16); $b^=$t;\r  $t=(($b>> 2)^$a)&0x33333333;\r   $b^=($t<< 2); $a^=$t;\r  $t=(($a>> 8)^$b)&0x00ff00ff;\r   $a^=($t<< 8); $b^=$t;\r  $t=(($b>> 1)^$a)&0x55555555;\r   $b^=($t<< 1); $a^=$t;\r  $t=$a;\r $a=$b&0xffffffff;\r      $b=$t&0xffffffff;\r      }\r\rsub doFP\r    {\r      local(*a,*b)=@_;\r       local($t);\r\r    $t=(($b>> 1)^$a)&0x55555555;\r   $b^=($t<< 1); $a^=$t;\r  $t=(($a>> 8)^$b)&0x00ff00ff;\r   $a^=($t<< 8); $b^=$t;\r  $t=(($b>> 2)^$a)&0x33333333;\r   $b^=($t<< 2); $a^=$t;\r  $t=(($a>>16)^$b)&0x0000ffff;\r   $a^=($t<<16); $b^=$t;\r  $t=(($b>> 4)^$a)&0x0f0f0f0f;\r   $b^=($t<< 4); $a^=$t;\r  $a&=0xffffffff;\r        $b&=0xffffffff;\r        }\r\rsub main'des_ecb_encrypt\r    {\r      local(*ks,$encrypt,$in)=@_;\r    local($l,$r,$i,$t,$u,@input);\r  \r       @input=unpack("C8",$in);\r       # Get the bytes in the order we want.\r  $l=     ($input[0]    )|\r               ($input[1]<< 8)|\r               ($input[2]<<16)|\r               ($input[3]<<24);\r       $r=     ($input[4]    )|\r               ($input[5]<< 8)|\r               ($input[6]<<16)|\r               ($input[7]<<24);\r\r      $l&=0xffffffff;\r        $r&=0xffffffff;\r        &doIP(*l,*r);\r  if ($encrypt)\r          {\r              for ($i=0; $i<32; $i+=4)\r                       {\r                      $t=((($r&0x7fffffff)<<1)|(($r>>31)&0x00000001));\r                       $u=$t^$ks[$i  ];\r                       $t=$t^$ks[$i+1];\r                       $t2=(($t&0x0000000f)<<28);\r\r                    $t=((($t>>4)&0x0fffffff)|(($t&0x0000000f)<<28));\r                       $l^=    $SP1[ $t     &0x3f]|\r                           $SP3[($t>> 8)&0x3f]|\r                           $SP5[($t>>16)&0x3f]|\r                           $SP7[($t>>24)&0x3f]|\r                           $SP0[ $u     &0x3f]|\r                           $SP2[($u>> 8)&0x3f]|\r                           $SP4[($u>>16)&0x3f]|\r                           $SP6[($u>>24)&0x3f];\r\r                  $t=(($l<<1)|(($l>>31)&0x1))&0xffffffff;\r                        $u=$t^$ks[$i+2];\r                       $t=$t^$ks[$i+3];\r                       $t=((($t>>4)&0x0fffffff)|($t<<28))&0xffffffff;\r                 $r^=    $SP1[ $t     &0x3f]|\r                           $SP3[($t>> 8)&0x3f]|\r                           $SP5[($t>>16)&0x3f]|\r                           $SP7[($t>>24)&0x3f]|\r                           $SP0[ $u     &0x3f]|\r                           $SP2[($u>> 8)&0x3f]|\r                           $SP4[($u>>16)&0x3f]|\r                           $SP6[($u>>24)&0x3f];\r                   }\r              }\r      else    \r               {\r              for ($i=30; $i>0; $i-=4)\r                       {\r                      $t=(($r<<1)|(($r>>31)&0x1))&0xffffffff;\r                        $u=$t^$ks[$i  ];\r                       $t=$t^$ks[$i+1];\r                       $t=((($t>>4)&0x0fffffff)|($t<<28))&0xffffffff;\r                 $l^=    $SP1[ $t     &0x3f]|\r                           $SP3[($t>> 8)&0x3f]|\r                           $SP5[($t>>16)&0x3f]|\r                           $SP7[($t>>24)&0x3f]|\r                           $SP0[ $u     &0x3f]|\r                           $SP2[($u>> 8)&0x3f]|\r                           $SP4[($u>>16)&0x3f]|\r                           $SP6[($u>>24)&0x3f];\r\r                  $t=(($l<<1)|(($l>>31)&0x1))&0xffffffff;\r                        $u=$t^$ks[$i-2];\r                       $t=$t^$ks[$i-1];\r                       $t=((($t>>4)&0x0fffffff)|($t<<28))&0xffffffff;\r                 $r^=    $SP1[ $t     &0x3f]|\r                           $SP3[($t>> 8)&0x3f]|\r                           $SP5[($t>>16)&0x3f]|\r                           $SP7[($t>>24)&0x3f]|\r                           $SP0[ $u     &0x3f]|\r                           $SP2[($u>> 8)&0x3f]|\r                           $SP4[($u>>16)&0x3f]|\r                           $SP6[($u>>24)&0x3f];\r                   }\r              }\r      &doFP(*l,*r);\r  pack("C8",$l&0xff, \r              ($l>> 8)&0x00ffffff,\r           ($l>>16)&0x0000ffff,\r           ($l>>24)&0x000000ff,\r           $r&0xff,\r               ($r>> 8)&0x00ffffff,\r           ($r>>16)&0x0000ffff,\r           ($r>>24)&0x000000ff);\r        }\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_crypt.man b/mac/libdes/src/des_crypt.man
new file mode 100755 (executable)
index 0000000..8c33e5f
--- /dev/null
@@ -0,0 +1 @@
+.TH DES_CRYPT 3 \r.SH NAME\rdes_read_password, des_read_2password,\rdes_string_to_key, des_string_to_2key, des_read_pw_string,\rdes_random_key, des_set_key,\rdes_key_sched, des_ecb_encrypt, des_3ecb_encrypt, des_cbc_encrypt,\rdes_3cbc_encrypt,\rdes_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,\rdes_cbc_cksum, des_quad_cksum,\rdes_enc_read, des_enc_write, des_set_odd_parity,\rdes_is_weak_key, crypt \- (non USA) DES encryption\r.SH SYNOPSIS\r.nf\r.nj\r.ft B\r#include <des.h>\r.PP\r.B int des_read_password(key,prompt,verify)\rdes_cblock *key;\rchar *prompt;\rint verify;\r.PP\r.B int des_read_2password(key1,key2,prompt,verify)\rdes_cblock *key1,*key2;\rchar *prompt;\rint verify;\r.PP\r.B int des_string_to_key(str,key)\rchar *str;\rdes_cblock *key;\r.PP\r.B int des_string_to_2keys(str,key1,key2)\rchar *str;\rdes_cblock *key1,*key2;\r.PP\r.B int des_read_pw_string(buf,length,prompt,verify)\rchar *buf;\rint length;\rchar *prompt;\rint verify;\r.PP\r.B int des_random_key(key)\rdes_cblock *key;\r.PP\r.B int des_set_key(key,schedule)\rdes_cblock *key;\rdes_key_schedule schedule;\r.PP\r.B int des_key_sched(key,schedule)\rdes_cblock *key;\rdes_key_schedule schedule;\r.PP\r.B int des_ecb_encrypt(input,output,schedule,encrypt)\rdes_cblock *input;\rdes_cblock *output;\rdes_key_schedule schedule;\rint encrypt;\r.PP\r.B int des_3ecb_encrypt(input,output,ks1,ks2,encrypt)\rdes_cblock *input;\rdes_cblock *output;\rdes_key_schedule ks1,ks2;\rint encrypt;\r.PP\r.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)\rdes_cblock *input;\rdes_cblock *output;\rlong length;\rdes_key_schedule schedule;\rdes_cblock *ivec;\rint encrypt;\r.PP\r.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)\rdes_cblock *input;\rdes_cblock *output;\rlong length;\rdes_key_schedule sk1;\rdes_key_schedule sk2;\rdes_cblock *ivec1;\rdes_cblock *ivec2;\rint encrypt;\r.PP\r.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)\rdes_cblock *input;\rdes_cblock *output;\rlong length;\rdes_key_schedule schedule;\rdes_cblock *ivec;\rint encrypt;\r.PP\r.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)\runsigned char *input;\runsigned char *output;\rint numbits;\rlong length;\rdes_key_schedule schedule;\rdes_cblock *ivec;\rint encrypt;\r.PP\r.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)\runsigned char *input,*output;\rint numbits;\rlong length;\rdes_key_schedule schedule;\rdes_cblock *ivec;\r.PP\r.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)\rdes_cblock *input;\rdes_cblock *output;\rlong length;\rdes_key_schedule schedule;\rdes_cblock *ivec;\r.PP\r.B unsigned long des_quad_cksum(input,output,length,out_count,seed)\rdes_cblock *input;\rdes_cblock *output;\rlong length;\rint out_count;\rdes_cblock *seed;\r.PP\r.B int des_check_key;\r.PP\r.B int des_enc_read(fd,buf,len,sched,iv)\rint fd;\rchar *buf;\rint len;\rdes_key_schedule sched;\rdes_cblock *iv;\r.PP\r.B int des_enc_write(fd,buf,len,sched,iv)\rint fd;\rchar *buf;\rint len;\rdes_key_schedule sched;\rdes_cblock *iv;\r.PP\r.B extern int des_rw_mode;\r.PP\r.B void des_set_odd_parity(key)\rdes_cblock *key;\r.PP\r.B int des_is_weak_key(key)\rdes_cblock *key;\r.PP\r.B char *crypt(passwd,salt)\rchar *passwd;\rchar *salt;\r.PP\r.fi\r.SH DESCRIPTION\rThis library contains a fast implementation of the DES encryption\ralgorithm.\r.PP\rThere are two phases to the use of DES encryption.\rThe first is the generation of a\r.I des_key_schedule\rfrom a key,\rthe second is the actual encryption.\rA des key is of type\r.I des_cblock.\rThis type is made from 8 characters with odd parity.\rThe least significant bit in the character is the parity bit.\rThe key schedule is an expanded form of the key; it is used to speed the\rencryption process.\r.PP\r.I des_read_password\rwrites the string specified by prompt to the standard output,\rturns off echo and reads an input string from standard input\runtil terminated with a newline.\rIf verify is non-zero, it prompts and reads the input again and verifies\rthat both entered passwords are the same.\rThe entered string is converted into a des key by using the\r.I des_string_to_key\rroutine.\rThe new key is placed in the\r.I des_cblock\rthat was passed (by reference) to the routine.\rIf there were no errors,\r.I des_read_password\rreturns 0,\r-1 is returned if there was a terminal error and 1 is returned for\rany other error.\r.PP\r.I des_read_2password\roperates in the same way as\r.I des_read_password\rexcept that it generates 2 keys by using the\r.I des_string_to_2key\rfunction.\r.PP\r.I des_read_pw_string\ris called by\r.I des_read_password\rto read and verify a string from a terminal device.\rThe string is returned in\r.I buf.\rThe size of\r.I buf\ris passed to the routine via the\r.I length\rparameter.\r.PP\r.I des_string_to_key\rconverts a string into a valid des key.\r.PP\r.I des_string_to_2key\rconverts a string into 2 valid des keys.\rThis routine is best suited for used to generate keys for use with\r.I des_3ecb_encrypt.\r.PP\r.I des_random_key\rreturns a random key that is made of a combination of process id,\rtime and an increasing counter.\r.PP\rBefore a des key can be used it is converted into a\r.I des_key_schedule\rvia the\r.I des_set_key\rroutine.\rIf the\r.I des_check_key\rflag is non-zero,\r.I des_set_key\rwill check that the key passed is of odd parity and is not a week or\rsemi-weak key.\rIf the parity is wrong,\rthen -1 is returned.\rIf the key is a weak key,\rthen -2 is returned.\rIf an error is returned,\rthe key schedule is not generated.\r.PP\r.I des_key_sched\ris another name for the\r.I des_set_key\rfunction.\r.PP\rThe following routines mostly operate on an input and output stream of\r.I des_cblock's.\r.PP\r.I des_ecb_encrypt\ris the basic DES encryption routine that encrypts or decrypts a single 8-byte\r.I des_cblock\rin\r.I electronic code book\rmode.\rIt always transforms the input data, pointed to by\r.I input,\rinto the output data,\rpointed to by the\r.I output\rargument.\rIf the\r.I encrypt\rargument is non-zero (DES_ENCRYPT),\rthe\r.I input\r(cleartext) is encrypted in to the\r.I output\r(ciphertext) using the key_schedule specified by the\r.I schedule\rargument,\rpreviously set via\r.I des_set_key.\rIf\r.I encrypt\ris zero (DES_DECRYPT),\rthe\r.I input\r(now ciphertext)\ris decrypted into the\r.I output\r(now cleartext).\rInput and output may overlap.\rNo meaningful value is returned.\r.PP\r.I des_3ecb_encrypt\rencrypts/decrypts the\r.I input\rblock by using triple ecb DES encryption.\rThis involves encrypting the input with \r.I ks1,\rdecryption with the key schedule\r.I ks2,\rand then encryption with the first again.\rThis routine greatly reduces the chances of brute force breaking of\rDES and has the advantage of if\r.I ks1\rand\r.I ks2\rare the same, it is equivalent to just encryption using ecb mode and\r.I ks1\ras the key.\r.PP\r.I des_cbc_encrypt\rencrypts/decrypts using the\r.I cipher-block-chaining\rmode of DES.\rIf the\r.I encrypt\rargument is non-zero,\rthe routine cipher-block-chain encrypts the cleartext data pointed to by the\r.I input\rargument into the ciphertext pointed to by the\r.I output\rargument,\rusing the key schedule provided by the\r.I schedule\rargument,\rand initialisation vector provided by the\r.I ivec\rargument.\rIf the\r.I length\rargument is not an integral multiple of eight bytes, \rthe last block is copied to a temporary area and zero filled.\rThe output is always\ran integral multiple of eight bytes.\rTo make multiple cbc encrypt calls on a large amount of data appear to\rbe one \r.I des_cbc_encrypt\rcall, the\r.I ivec\rof subsequent calls should be the last 8 bytes of the output.\r.PP\r.I des_3cbc_encrypt\rencrypts/decrypts the\r.I input\rblock by using triple cbc DES encryption.\rThis involves encrypting the input with key schedule\r.I ks1,\rdecryption with the key schedule\r.I ks2,\rand then encryption with the first again.\r2 initialisation vectors are required,\r.I ivec1\rand\r.I ivec2.\rUnlike\r.I des_cbc_encrypt,\rthese initialisation vectors are modified by the subroutine.\rThis routine greatly reduces the chances of brute force breaking of\rDES and has the advantage of if\r.I ks1\rand\r.I ks2\rare the same, it is equivalent to just encryption using cbc mode and\r.I ks1\ras the key.\r.PP\r.I des_pcbc_encrypt\rencrypt/decrypts using a modified block chaining mode.\rIt provides better error propagation characteristics than cbc\rencryption.\r.PP\r.I des_cfb_encrypt\rencrypt/decrypts using cipher feedback mode.  This method takes an\rarray of characters as input and outputs and array of characters.  It\rdoes not require any padding to 8 character groups.  Note: the ivec\rvariable is changed and the new changed value needs to be passed to\rthe next call to this function.  Since this function runs a complete\rDES ecb encryption per numbits, this function is only suggested for\ruse when sending small numbers of characters.\r.PP\r.I des_ofb_encrypt\rencrypt using output feedback mode.  This method takes an\rarray of characters as input and outputs and array of characters.  It\rdoes not require any padding to 8 character groups.  Note: the ivec\rvariable is changed and the new changed value needs to be passed to\rthe next call to this function.  Since this function runs a complete\rDES ecb encryption per numbits, this function is only suggested for\ruse when sending small numbers of characters.\r.PP\r.I des_cbc_cksum\rproduces an 8 byte checksum based on the input stream (via cbc encryption).\rThe last 4 bytes of the checksum is returned and the complete 8 bytes is\rplaced in\r.I output.\r.PP\r.I des_quad_cksum\rreturns a 4 byte checksum from the input bytes.\rThe algorithm can be iterated over the input,\rdepending on\r.I out_count,\r1, 2, 3 or 4 times.\rIf\r.I output\ris non-NULL,\rthe 8 bytes generated by each pass are written into\r.I output.\r.PP\r.I des_enc_write\ris used to write\r.I len\rbytes\rto file descriptor\r.I fd\rfrom buffer\r.I buf.\rThe data is encrypted via\r.I pcbc_encrypt\r(default) using\r.I sched\rfor the key and\r.I iv\ras a starting vector.\rThe actual data send down\r.I fd\rconsists of 4 bytes (in network byte order) containing the length of the\rfollowing encrypted data.  The encrypted data then follows, padded with random\rdata out to a multiple of 8 bytes.\r.PP\r.I des_enc_read\ris used to read\r.I len\rbytes\rfrom file descriptor\r.I fd\rinto buffer\r.I buf.\rThe data being read from\r.I fd\ris assumed to have come from\r.I des_enc_write\rand is decrypted using\r.I sched\rfor the key schedule and\r.I iv\rfor the initial vector.\rThe\r.I des_enc_read/des_enc_write\rpair can be used to read/write to files, pipes and sockets.\rI have used them in implementing a version of rlogin in which all\rdata is encrypted.\r.PP\r.I des_rw_mode\ris used to specify the encryption mode to use with \r.I des_enc_read\rand \r.I des_end_write.\rIf set to\r.I DES_PCBC_MODE\r(the default), des_pcbc_encrypt is used.\rIf set to\r.I DES_CBC_MODE\rdes_cbc_encrypt is used.\rThese two routines and the variable are not part of the normal MIT library.\r.PP\r.I des_set_odd_parity\rsets the parity of the passed\r.I key\rto odd.  This routine is not part of the standard MIT library.\r.PP\r.I des_is_weak_key\rreturns 1 is the passed key is a weak key (pick again :-),\r0 if it is ok.\rThis routine is not part of the standard MIT library.\r.PP\r.I crypt\ris a replacement for the normal system crypt.\rIt is much faster than the system crypt.\r.PP\r.SH FILES\r/usr/include/des.h\r.br\r/usr/lib/libdes.a\r.PP\rThe encryption routines have been tested on 16bit, 32bit and 64bit\rmachines of various endian and even works under VMS.\r.PP\r.SH BUGS\r.PP\rIf you think this manual is sparse,\rread the des_crypt(3) manual from the MIT kerberos (or bones outside\rof the USA) distribution.\r.PP\r.I des_cfb_encrypt\rand\r.I des_ofb_encrypt\roperates on input of 8 bits.  What this means is that if you set\rnumbits to 12, and length to 2, the first 12 bits will come from the 1st\rinput byte and the low half of the second input byte.  The second 12\rbits will have the low 8 bits taken from the 3rd input byte and the\rtop 4 bits taken from the 4th input byte.  The same holds for output.\rThis function has been implemented this way because most people will\rbe using a multiple of 8 and because once you get into pulling bytes input\rbytes apart things get ugly!\r.PP\r.I des_read_pw_string\ris the most machine/OS dependent function and normally generates the\rmost problems when porting this code.\r.PP\r.I des_string_to_key\ris probably different from the MIT version since there are lots\rof fun ways to implement one-way encryption of a text string.\r.PP\rThe routines are optimised for 32 bit machines and so are not efficient\ron IBM PCs.\r.PP\rNOTE: extensive work has been done on this library since this document\rwas origionally written.  Please try to read des.doc from the libdes\rdistribution since it is far more upto date and documents more of the\rfunctions.  Libdes is now also being shipped as part of SSLeay, a\rgeneral cryptographic library that amonst other things implements\rnetscapes SSL protocoll.  The most recent version can be found in\rSSLeay distributions.\r.SH AUTHOR\rEric Young (eay@mincom.oz.au or eay@psych.psy.uq.oz.au)\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_enc.c b/mac/libdes/src/des_enc.c
new file mode 100755 (executable)
index 0000000..2a839a6
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_encrypt(data, ks, encrypt)\rDES_LONG *data;\rdes_key_schedule ks;\rint encrypt;\r  {\r      register DES_LONG l,r,t,u;\r#ifdef DES_PTR\r      register unsigned char *des_SP=(unsigned char *)des_SPtrans;\r#endif\r#ifndef DES_UNROLL\r register int i;\r#endif\r register DES_LONG *s;\r\r r=data[0];\r     l=data[1];\r\r    IP(r,l);\r       /* Things have been modified so that the initial rotate is\r      * done outside the loop.  This required the\r    * des_SPtrans values in sp.h to be rotated 1 bit to the right.\r         * One perl script later and things have a 5% speed up on a sparc2.\r     * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>\r     * for pointing this out. */\r   /* clear the top bits on machines with 8byte longs */\r  /* shift left by 2 */\r  r=ROTATE(r,29)&0xffffffffL;\r    l=ROTATE(l,29)&0xffffffffL;\r\r   s=(DES_LONG *)ks;\r      /* I don't know if it is worth the effort of loop unrolling the\r         * inner loop */\r       if (encrypt)\r           {\r#ifdef DES_UNROLL\r            D_ENCRYPT(l,r, 0); /*  1 */\r            D_ENCRYPT(r,l, 2); /*  2 */\r            D_ENCRYPT(l,r, 4); /*  3 */\r            D_ENCRYPT(r,l, 6); /*  4 */\r            D_ENCRYPT(l,r, 8); /*  5 */\r            D_ENCRYPT(r,l,10); /*  6 */\r            D_ENCRYPT(l,r,12); /*  7 */\r            D_ENCRYPT(r,l,14); /*  8 */\r            D_ENCRYPT(l,r,16); /*  9 */\r            D_ENCRYPT(r,l,18); /*  10 */\r           D_ENCRYPT(l,r,20); /*  11 */\r           D_ENCRYPT(r,l,22); /*  12 */\r           D_ENCRYPT(l,r,24); /*  13 */\r           D_ENCRYPT(r,l,26); /*  14 */\r           D_ENCRYPT(l,r,28); /*  15 */\r           D_ENCRYPT(r,l,30); /*  16 */\r#else\r             for (i=0; i<32; i+=8)\r                  {\r                      D_ENCRYPT(l,r,i+0); /*  1 */\r                   D_ENCRYPT(r,l,i+2); /*  2 */\r                   D_ENCRYPT(l,r,i+4); /*  3 */\r                   D_ENCRYPT(r,l,i+6); /*  4 */\r                   }\r#endif\r               }\r      else\r           {\r#ifdef DES_UNROLL\r            D_ENCRYPT(l,r,30); /* 16 */\r            D_ENCRYPT(r,l,28); /* 15 */\r            D_ENCRYPT(l,r,26); /* 14 */\r            D_ENCRYPT(r,l,24); /* 13 */\r            D_ENCRYPT(l,r,22); /* 12 */\r            D_ENCRYPT(r,l,20); /* 11 */\r            D_ENCRYPT(l,r,18); /* 10 */\r            D_ENCRYPT(r,l,16); /*  9 */\r            D_ENCRYPT(l,r,14); /*  8 */\r            D_ENCRYPT(r,l,12); /*  7 */\r            D_ENCRYPT(l,r,10); /*  6 */\r            D_ENCRYPT(r,l, 8); /*  5 */\r            D_ENCRYPT(l,r, 6); /*  4 */\r            D_ENCRYPT(r,l, 4); /*  3 */\r            D_ENCRYPT(l,r, 2); /*  2 */\r            D_ENCRYPT(r,l, 0); /*  1 */\r#else\r              for (i=30; i>0; i-=8)\r                  {\r                      D_ENCRYPT(l,r,i-0); /* 16 */\r                   D_ENCRYPT(r,l,i-2); /* 15 */\r                   D_ENCRYPT(l,r,i-4); /* 14 */\r                   D_ENCRYPT(r,l,i-6); /* 13 */\r                   }\r#endif\r               }\r\r     /* rotate and clear the top bits on machines with 8byte longs */\r       l=ROTATE(l,3)&0xffffffffL;\r     r=ROTATE(r,3)&0xffffffffL;\r\r    FP(r,l);\r       data[0]=l;\r     data[1]=r;\r     l=r=t=u=0;\r     }\r\rvoid des_encrypt2(data, ks, encrypt)\rDES_LONG *data;\rdes_key_schedule ks;\rint encrypt;\r      {\r      register DES_LONG l,r,t,u;\r#ifdef DES_PTR\r      register unsigned char *des_SP=(unsigned char *)des_SPtrans;\r#endif\r#ifndef DES_UNROLL\r register int i;\r#endif\r register DES_LONG *s;\r\r r=data[0];\r     l=data[1];\r\r    /* Things have been modified so that the initial rotate is\r      * done outside the loop.  This required the\r    * des_SPtrans values in sp.h to be rotated 1 bit to the right.\r         * One perl script later and things have a 5% speed up on a sparc2.\r     * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>\r     * for pointing this out. */\r   /* clear the top bits on machines with 8byte longs */\r  r=ROTATE(r,29)&0xffffffff;\r     l=ROTATE(l,29)&0xffffffff;\r\r    s=(DES_LONG *)ks;\r      /* I don't know if it is worth the effort of loop unrolling the\r         * inner loop */\r       if (encrypt)\r           {\r#ifdef DES_UNROLL\r            D_ENCRYPT(l,r, 0); /*  1 */\r            D_ENCRYPT(r,l, 2); /*  2 */\r            D_ENCRYPT(l,r, 4); /*  3 */\r            D_ENCRYPT(r,l, 6); /*  4 */\r            D_ENCRYPT(l,r, 8); /*  5 */\r            D_ENCRYPT(r,l,10); /*  6 */\r            D_ENCRYPT(l,r,12); /*  7 */\r            D_ENCRYPT(r,l,14); /*  8 */\r            D_ENCRYPT(l,r,16); /*  9 */\r            D_ENCRYPT(r,l,18); /*  10 */\r           D_ENCRYPT(l,r,20); /*  11 */\r           D_ENCRYPT(r,l,22); /*  12 */\r           D_ENCRYPT(l,r,24); /*  13 */\r           D_ENCRYPT(r,l,26); /*  14 */\r           D_ENCRYPT(l,r,28); /*  15 */\r           D_ENCRYPT(r,l,30); /*  16 */\r#else\r             for (i=0; i<32; i+=8)\r                  {\r                      D_ENCRYPT(l,r,i+0); /*  1 */\r                   D_ENCRYPT(r,l,i+2); /*  2 */\r                   D_ENCRYPT(l,r,i+4); /*  3 */\r                   D_ENCRYPT(r,l,i+6); /*  4 */\r                   }\r#endif\r               }\r      else\r           {\r#ifdef DES_UNROLL\r            D_ENCRYPT(l,r,30); /* 16 */\r            D_ENCRYPT(r,l,28); /* 15 */\r            D_ENCRYPT(l,r,26); /* 14 */\r            D_ENCRYPT(r,l,24); /* 13 */\r            D_ENCRYPT(l,r,22); /* 12 */\r            D_ENCRYPT(r,l,20); /* 11 */\r            D_ENCRYPT(l,r,18); /* 10 */\r            D_ENCRYPT(r,l,16); /*  9 */\r            D_ENCRYPT(l,r,14); /*  8 */\r            D_ENCRYPT(r,l,12); /*  7 */\r            D_ENCRYPT(l,r,10); /*  6 */\r            D_ENCRYPT(r,l, 8); /*  5 */\r            D_ENCRYPT(l,r, 6); /*  4 */\r            D_ENCRYPT(r,l, 4); /*  3 */\r            D_ENCRYPT(l,r, 2); /*  2 */\r            D_ENCRYPT(r,l, 0); /*  1 */\r#else\r              for (i=30; i>0; i-=8)\r                  {\r                      D_ENCRYPT(l,r,i-0); /* 16 */\r                   D_ENCRYPT(r,l,i-2); /* 15 */\r                   D_ENCRYPT(l,r,i-4); /* 14 */\r                   D_ENCRYPT(r,l,i-6); /* 13 */\r                   }\r#endif\r               }\r      /* rotate and clear the top bits on machines with 8byte longs */\r       data[0]=ROTATE(l,3)&0xffffffff;\r        data[1]=ROTATE(r,3)&0xffffffff;\r        l=r=t=u=0;\r     }\r\rvoid des_encrypt3(data,ks1,ks2,ks3)\rDES_LONG *data;\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_key_schedule ks3;\r       {\r      register DES_LONG l,r;\r\r        l=data[0];\r     r=data[1];\r     IP(l,r);\r       data[0]=l;\r     data[1]=r;\r     des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);\r        des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);\r        des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);\r        l=data[0];\r     r=data[1];\r     FP(r,l);\r       data[0]=l;\r     data[1]=r;\r     }\r\rvoid des_decrypt3(data,ks1,ks2,ks3)\rDES_LONG *data;\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_key_schedule ks3;\r       {\r      register DES_LONG l,r;\r\r        l=data[0];\r     r=data[1];\r     IP(l,r);\r       data[0]=l;\r     data[1]=r;\r     des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);\r        des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);\r        des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);\r        l=data[0];\r     r=data[1];\r     FP(r,l);\r       data[0]=l;\r     data[1]=r;\r     }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_locl.h b/mac/libdes/src/des_locl.h
new file mode 100755 (executable)
index 0000000..24bf6ae
--- /dev/null
@@ -0,0 +1 @@
+#ifdef HAVE_CONFIG_H\r#include "config.h"\r\r/*\r  if (we have termios.h)\r    define TERMIOS\r  else if (we have termio.h)\r    define TERMIO\r*/\r#ifdef HAVE_TERMIOS_H\r\r#define TERMIOS\r\r#else /* !HAVE_TERMIOS_H */\r\r#ifdef HAVE_TERMIO_H\r#define TERMIO\r#endif\r\r#endif /* !HAVE_TERMIOS_H */\r\r#endif /* HAVE_CONFIG_H */\r\r/* crypto/des/des_locl.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\r *\r * Always modify des_locl.org since des_locl.h is automatically generated from\r * it during SSLeay configuration.\r *\r * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\r */\r\r#ifndef HEADER_DES_LOCL_H\r#define HEADER_DES_LOCL_H\r\r#if defined(WIN32) || defined(WIN16)\r#ifndef MSDOS\r#define MSDOS\r#endif\r#endif\r\r#include <stdio.h>\r#include <stdlib.h>\r#ifdef HAVE_UNISTD_H\r#include <unistd.h>\r#endif\r#ifdef HAVE_IO_H\r#include <io.h>\r#endif\r#include "des.h"\r\r#ifndef DES_DEFAULT_OPTIONS\r/* the following is tweaked from a config script, that is why it is a\r * protected undef/define */\r#ifndef DES_PTR\r#undef DES_PTR\r#endif\r\r/* This helps C compiler generate the correct code for multiple functional\r * units.  It reduces register dependancies at the expense of 2 more\r * registers */\r#ifndef DES_RISC1\r#undef DES_RISC1\r#endif\r\r#ifndef DES_RISC2\r#undef DES_RISC2\r#endif\r\r#if defined(DES_RISC1) && defined(DES_RISC2)\rYOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!\r#endif\r\r/* Unroll the inner loop, this sometimes helps, sometimes hinders.\r * Very mucy CPU dependant */\r#ifndef DES_UNROLL\r#undef DES_UNROLL\r#endif\r\r/* These default values were supplied by\r * Peter Gutman <pgut001@cs.auckland.ac.nz>\r * They are only used if nothing else has been defined */\r#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)\r/* Special defines which change the way the code is built depending on the\r   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find\r   even newer MIPS CPU's, but at the moment one size fits all for\r   optimization options.  Older Sparc's work better with only UNROLL, but\r   there's no way to tell at compile time what it is you're running on */\r \r#if defined( sun )             /* Newer Sparc's */\r  #define DES_PTR\r  #define DES_RISC1\r  #define DES_UNROLL\r#elif defined( __ultrix )        /* Older MIPS */\r  #define DES_PTR\r  #define DES_RISC2\r  #define DES_UNROLL\r#elif defined( __osf1__ )   /* Alpha */\r  #define DES_PTR\r  #define DES_RISC2\r#elif defined ( _AIX )                /* RS6000 */\r  /* Unknown */\r#elif defined( __hpux )            /* HP-PA */\r  #define DES_UNROLL\r#elif defined( __aux )         /* 68K */\r  /* Unknown */\r#elif defined( __dgux )               /* 88K (but P6 in latest boxes) */\r  #define DES_UNROLL\r#elif defined( __sgi )          /* Newer MIPS */\r  #define DES_PTR\r  #define DES_RISC2\r  #define DES_UNROLL\r#elif defined( i386 )               /* x86 boxes, should be gcc */\r  #define DES_PTR\r  #define DES_RISC1\r  #define DES_UNROLL\r#endif /* Systems-specific speed defines */\r#endif\r\r#endif /* DES_DEFAULT_OPTIONS */\r\r#ifdef MSDOS            /* Visual C++ 2.1 (Windows NT/95) */\r#include <stdlib.h>\r#include <errno.h>\r#include <time.h>\r#include <io.h>\r#ifndef RAND\r#define RAND\r#endif\r#undef NOPROTO\r#endif\r\r#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) || defined(WIN32)\r#include <string.h>\r#endif\r\r#ifndef RAND\r#define RAND\r#endif\r\r#ifdef linux\r#undef RAND\r#endif\r\r#ifdef MSDOS\r#define getpid() 2\r#define RAND\r#undef NOPROTO\r#endif\r\r#if defined(NOCONST)\r#define const\r#endif\r\r#ifdef __STDC__\r#undef NOPROTO\r#endif\r\r#ifdef RAND\r#define srandom(s) srand(s)\r#define random rand\r#endif\r\r#define ITERATIONS 16\r#define HALF_ITERATIONS 8\r\r/* used in des_read and des_write */\r#define MAXWRITE     (1024*16)\r#define BSIZE         (MAXWRITE+4)\r\r#define c2l(c,l)  (l =((DES_LONG)(*((c)++)))    , \\r                       l|=((DES_LONG)(*((c)++)))<< 8L, \\r                      l|=((DES_LONG)(*((c)++)))<<16L, \\r                      l|=((DES_LONG)(*((c)++)))<<24L)\r\r/* NOTE - c is not incremented as per c2l */\r#define c2ln(c,l1,l2,n)  { \\r                    c+=n; \\r                        l1=l2=0; \\r                     switch (n) { \\r                 case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \\r                     case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \\r                     case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \\r                     case 5: l2|=((DES_LONG)(*(--(c))));     \\r                      case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \\r                     case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \\r                     case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \\r                     case 1: l1|=((DES_LONG)(*(--(c))));     \\r                              } \\r                    }\r\r#define l2c(l,c)     (*((c)++)=(unsigned char)(((l)     )&0xff), \\r                   *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>16L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>24L)&0xff))\r\r/* replacements for htonl and ntohl since I have no idea what to do\r * when faced with machines with 8 byte longs. */\r#define HDRSIZE 4\r\r#define n2l(c,l)  (l =((DES_LONG)(*((c)++)))<<24L, \\r                      l|=((DES_LONG)(*((c)++)))<<16L, \\r                      l|=((DES_LONG)(*((c)++)))<< 8L, \\r                      l|=((DES_LONG)(*((c)++))))\r\r#define l2n(l,c)   (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>16L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)     )&0xff))\r\r/* NOTE - c is not incremented as per l2c */\r#define l2cn(l1,l2,c,n)       { \\r                    c+=n; \\r                        switch (n) { \\r                 case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \\r                  case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \\r                  case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \\r                  case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \\r                  case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \\r                  case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \\r                  case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \\r                  case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \\r                          } \\r                    }\r\r#if defined(WIN32)\r#define   ROTATE(a,n)     (_lrotr(a,n))\r#else\r#define     ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))\r#endif\r\r/* Don't worry about the LOAD_DATA() stuff, that is used by\r * fcrypt() to add it's little bit to the front */\r\r#ifdef DES_FCRYPT\r\r#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \\r { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }\r\r#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \\r        t=R^(R>>16L); \\r        u=t&E0; t&=E1; \\r       tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \\r    tmp=(t<<16); t^=R^s[S+1]; t^=tmp\r#else\r#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)\r#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \\r      u=R^s[S  ]; \\r  t=R^s[S+1]\r#endif\r\r/* The changes to this macro may help or hinder, depending on the\r * compiler and the achitecture.  gcc2 always seems to do well :-).\r * Inspired by Dana How <how@isl.stanford.edu>\r * DO NOT use the alternative version on machines with 8 byte longs.\r * It does not seem to work on the Alpha, even when DES_LONG is 4\r * bytes, probably an issue of accessing non-word aligned objects :-( */\r#ifdef DES_PTR\r\r/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there\r * is no reason to not xor all the sub items together.  This potentially\r * saves a register since things can be xored directly into L */\r\r#if defined(DES_RISC1) || defined(DES_RISC2)\r#ifdef DES_RISC1\r#define D_ENCRYPT(LL,R,S) { \\r  unsigned int u1,u2,u3; \\r       LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u2=(int)u>>8L; \\r       u1=(int)u&0xfc; \\r      u2&=0xfc; \\r    t=ROTATE(t,4); \\r       u>>=16L; \\r     LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \\r        u3=(int)(u>>8L); \\r     u1=(int)u&0xfc; \\r      u3&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \\r        u2=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u2&=0xfc; \\r    t>>=16L; \\r     LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \\r        u3=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u3&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }\r#endif\r#ifdef DES_RISC2\r#define D_ENCRYPT(LL,R,S) { \\r  unsigned int u1,u2,s1,s2; \\r    LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u2=(int)u>>8L; \\r       u1=(int)u&0xfc; \\r      u2&=0xfc; \\r    t=ROTATE(t,4); \\r       LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \\r        s1=(int)(u>>16L); \\r    s2=(int)(u>>24L); \\r    s1&=0xfc; \\r    s2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \\r        u2=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \\r        s1=(int)(t>>16L); \\r    s2=(int)(t>>24L); \\r    s1&=0xfc; \\r    s2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }\r#endif\r#else\r#define D_ENCRYPT(LL,R,S) { \\r     LOAD_DATA_tmp(R,S,u,t,E0,E1); \\r        t=ROTATE(t,4); \\r       LL^= \\r *(DES_LONG *)((unsigned char *)des_SP      +((u     )&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x100+((t     )&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }\r#endif\r\r#else /* original version */\r\r#if defined(DES_RISC1) || defined(DES_RISC2)\r#ifdef DES_RISC1\r#define D_ENCRYPT(LL,R,S) {\\r       unsigned int u1,u2,u3; \\r       LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u>>=2L; \\r      t=ROTATE(t,6); \\r       u2=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u2&=0x3f; \\r    u>>=16L; \\r     LL^=des_SPtrans[0][u1]; \\r      LL^=des_SPtrans[2][u2]; \\r      u3=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u3&=0x3f; \\r    LL^=des_SPtrans[4][u1]; \\r      LL^=des_SPtrans[6][u3]; \\r      u2=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u2&=0x3f; \\r    t>>=16L; \\r     LL^=des_SPtrans[1][u1]; \\r      LL^=des_SPtrans[3][u2]; \\r      u3=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u3&=0x3f; \\r    LL^=des_SPtrans[5][u1]; \\r      LL^=des_SPtrans[7][u3]; }\r#endif\r#ifdef DES_RISC2\r#define D_ENCRYPT(LL,R,S) {\\r unsigned int u1,u2,s1,s2; \\r    LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u>>=2L; \\r      t=ROTATE(t,6); \\r       u2=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u2&=0x3f; \\r    LL^=des_SPtrans[0][u1]; \\r      LL^=des_SPtrans[2][u2]; \\r      s1=(int)u>>16L; \\r      s2=(int)u>>24L; \\r      s1&=0x3f; \\r    s2&=0x3f; \\r    LL^=des_SPtrans[4][s1]; \\r      LL^=des_SPtrans[6][s2]; \\r      u2=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u2&=0x3f; \\r    LL^=des_SPtrans[1][u1]; \\r      LL^=des_SPtrans[3][u2]; \\r      s1=(int)t>>16; \\r       s2=(int)t>>24L; \\r      s1&=0x3f; \\r    s2&=0x3f; \\r    LL^=des_SPtrans[5][s1]; \\r      LL^=des_SPtrans[7][s2]; }\r#endif\r\r#else\r\r#define D_ENCRYPT(LL,R,S) {\\r  LOAD_DATA_tmp(R,S,u,t,E0,E1); \\r        t=ROTATE(t,4); \\r       LL^=\\r          des_SPtrans[0][(u>> 2L)&0x3f]^ \\r               des_SPtrans[2][(u>>10L)&0x3f]^ \\r               des_SPtrans[4][(u>>18L)&0x3f]^ \\r               des_SPtrans[6][(u>>26L)&0x3f]^ \\r               des_SPtrans[1][(t>> 2L)&0x3f]^ \\r               des_SPtrans[3][(t>>10L)&0x3f]^ \\r               des_SPtrans[5][(t>>18L)&0x3f]^ \\r               des_SPtrans[7][(t>>26L)&0x3f]; }\r#endif\r#endif\r\r        /* IP and FP\r    * The problem is more of a geometric problem that random bit fiddling.\r         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6\r    8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4\r   16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2\r   24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0\r\r  32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7\r   40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5\r   48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3\r   56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1\r\r  The output has been subject to swaps of the form\r       0 1 -> 3 1 but the odd and even bits have been put into\r        2 3    2 0\r     different words.  The main trick is to remember that\r   t=((l>>size)^r)&(mask);\r        r^=t;\r  l^=(t<<size);\r  can be used to swap and move bits between words.\r\r      So l =  0  1  2  3  r = 16 17 18 19\r            4  5  6  7      20 21 22 23\r            8  9 10 11      24 25 26 27\r           12 13 14 15      28 29 30 31\r    becomes (for size == 2 and mask == 0x3333)\r        t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19\r            6^20  7^21 -- --        4  5 20 21       6  7 22 23\r           10^24 11^25 -- --        8  9 24 25      10 11 24 25\r           14^28 15^29 -- --       12 13 28 29      14 15 28 29\r\r  Thanks for hints from Richard Outerbridge - he told me IP&FP\r   could be done in 15 xor, 10 shifts and 5 ands.\r When I finally started to think of the problem in 2D\r   I first got ~42 operations without xors.  When I remembered\r    how to use xors :-) I got it to its final state.\r       */\r#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\\r    (b)^=(t),\\r     (a)^=((t)<<(n)))\r\r#define IP(l,r) \\r    { \\r    register DES_LONG tt; \\r        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \\r      PERM_OP(l,r,tt,16,0x0000ffffL); \\r      PERM_OP(r,l,tt, 2,0x33333333L); \\r      PERM_OP(l,r,tt, 8,0x00ff00ffL); \\r      PERM_OP(r,l,tt, 1,0x55555555L); \\r      }\r\r#define FP(l,r) \\r   { \\r    register DES_LONG tt; \\r        PERM_OP(l,r,tt, 1,0x55555555L); \\r      PERM_OP(r,l,tt, 8,0x00ff00ffL); \\r      PERM_OP(l,r,tt, 2,0x33333333L); \\r      PERM_OP(r,l,tt,16,0x0000ffffL); \\r      PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \\r      }\r\rextern const DES_LONG des_SPtrans[8][64];\r\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_locl.org b/mac/libdes/src/des_locl.org
new file mode 100755 (executable)
index 0000000..d7af95b
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des_locl.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\r *\r * Always modify des_locl.org since des_locl.h is automatically generated from\r * it during SSLeay configuration.\r *\r * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING\r */\r\r#ifndef HEADER_DES_LOCL_H\r#define HEADER_DES_LOCL_H\r\r#if defined(WIN32) || defined(WIN16)\r#ifndef MSDOS\r#define MSDOS\r#endif\r#endif\r\r#include <stdio.h>\r#include <stdlib.h>\r#ifndef MSDOS\r#include <unistd.h>\r#endif\r#include "des.h"\r\r#ifndef DES_DEFAULT_OPTIONS\r/* the following is tweaked from a config script, that is why it is a\r * protected undef/define */\r#ifndef DES_PTR\r#undef DES_PTR\r#endif\r\r/* This helps C compiler generate the correct code for multiple functional\r * units.  It reduces register dependancies at the expense of 2 more\r * registers */\r#ifndef DES_RISC1\r#undef DES_RISC1\r#endif\r\r#ifndef DES_RISC2\r#undef DES_RISC2\r#endif\r\r#if defined(DES_RISC1) && defined(DES_RISC2)\rYOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!\r#endif\r\r/* Unroll the inner loop, this sometimes helps, sometimes hinders.\r * Very mucy CPU dependant */\r#ifndef DES_UNROLL\r#undef DES_UNROLL\r#endif\r\r/* These default values were supplied by\r * Peter Gutman <pgut001@cs.auckland.ac.nz>\r * They are only used if nothing else has been defined */\r#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)\r/* Special defines which change the way the code is built depending on the\r   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find\r   even newer MIPS CPU's, but at the moment one size fits all for\r   optimization options.  Older Sparc's work better with only UNROLL, but\r   there's no way to tell at compile time what it is you're running on */\r \r#if defined( sun )          /* Newer Sparc's */\r  #define DES_PTR\r  #define DES_RISC1\r  #define DES_UNROLL\r#elif defined( __ultrix )        /* Older MIPS */\r  #define DES_PTR\r  #define DES_RISC2\r  #define DES_UNROLL\r#elif defined( __osf1__ )   /* Alpha */\r  #define DES_PTR\r  #define DES_RISC2\r#elif defined ( _AIX )                /* RS6000 */\r  /* Unknown */\r#elif defined( __hpux )            /* HP-PA */\r  /* Unknown */\r#elif defined( __aux )              /* 68K */\r  /* Unknown */\r#elif defined( __dgux )               /* 88K (but P6 in latest boxes) */\r  #define DES_UNROLL\r#elif defined( __sgi )          /* Newer MIPS */\r  #define DES_PTR\r  #define DES_RISC2\r  #define DES_UNROLL\r#elif defined( i386 )               /* x86 boxes, should be gcc */\r  #define DES_PTR\r  #define DES_RISC1\r  #define DES_UNROLL\r#endif /* Systems-specific speed defines */\r#endif\r\r#endif /* DES_DEFAULT_OPTIONS */\r\r#ifdef MSDOS            /* Visual C++ 2.1 (Windows NT/95) */\r#include <stdlib.h>\r#include <errno.h>\r#include <time.h>\r#include <io.h>\r#ifndef RAND\r#define RAND\r#endif\r#undef NOPROTO\r#endif\r\r#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)\r#include <string.h>\r#endif\r\r#ifndef RAND\r#define RAND\r#endif\r\r#ifdef linux\r#undef RAND\r#endif\r\r#ifdef MSDOS\r#define getpid() 2\r#define RAND\r#undef NOPROTO\r#endif\r\r#if defined(NOCONST)\r#define const\r#endif\r\r#ifdef __STDC__\r#undef NOPROTO\r#endif\r\r#ifdef RAND\r#define srandom(s) srand(s)\r#define random rand\r#endif\r\r#define ITERATIONS 16\r#define HALF_ITERATIONS 8\r\r/* used in des_read and des_write */\r#define MAXWRITE       (1024*16)\r#define BSIZE         (MAXWRITE+4)\r\r#define c2l(c,l)  (l =((DES_LONG)(*((c)++)))    , \\r                       l|=((DES_LONG)(*((c)++)))<< 8L, \\r                      l|=((DES_LONG)(*((c)++)))<<16L, \\r                      l|=((DES_LONG)(*((c)++)))<<24L)\r\r/* NOTE - c is not incremented as per c2l */\r#define c2ln(c,l1,l2,n)  { \\r                    c+=n; \\r                        l1=l2=0; \\r                     switch (n) { \\r                 case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \\r                     case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \\r                     case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \\r                     case 5: l2|=((DES_LONG)(*(--(c))));     \\r                      case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \\r                     case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \\r                     case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \\r                     case 1: l1|=((DES_LONG)(*(--(c))));     \\r                              } \\r                    }\r\r#define l2c(l,c)     (*((c)++)=(unsigned char)(((l)     )&0xff), \\r                   *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>16L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>24L)&0xff))\r\r/* replacements for htonl and ntohl since I have no idea what to do\r * when faced with machines with 8 byte longs. */\r#define HDRSIZE 4\r\r#define n2l(c,l)  (l =((DES_LONG)(*((c)++)))<<24L, \\r                      l|=((DES_LONG)(*((c)++)))<<16L, \\r                      l|=((DES_LONG)(*((c)++)))<< 8L, \\r                      l|=((DES_LONG)(*((c)++))))\r\r#define l2n(l,c)   (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>>16L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \\r                   *((c)++)=(unsigned char)(((l)     )&0xff))\r\r/* NOTE - c is not incremented as per l2c */\r#define l2cn(l1,l2,c,n)       { \\r                    c+=n; \\r                        switch (n) { \\r                 case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \\r                  case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \\r                  case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \\r                  case 5: *(--(c))=(unsigned char)(((l2)     )&0xff); \\r                  case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \\r                  case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \\r                  case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \\r                  case 1: *(--(c))=(unsigned char)(((l1)     )&0xff); \\r                          } \\r                    }\r\r#if defined(WIN32)\r#define   ROTATE(a,n)     (_lrotr(a,n))\r#else\r#define     ROTATE(a,n)     (((a)>>(n))+((a)<<(32-(n))))\r#endif\r\r/* Don't worry about the LOAD_DATA() stuff, that is used by\r * fcrypt() to add it's little bit to the front */\r\r#ifdef DES_FCRYPT\r\r#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \\r { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }\r\r#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \\r        t=R^(R>>16L); \\r        u=t&E0; t&=E1; \\r       tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \\r    tmp=(t<<16); t^=R^s[S+1]; t^=tmp\r#else\r#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)\r#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \\r      u=R^s[S  ]; \\r  t=R^s[S+1]\r#endif\r\r/* The changes to this macro may help or hinder, depending on the\r * compiler and the achitecture.  gcc2 always seems to do well :-).\r * Inspired by Dana How <how@isl.stanford.edu>\r * DO NOT use the alternative version on machines with 8 byte longs.\r * It does not seem to work on the Alpha, even when DES_LONG is 4\r * bytes, probably an issue of accessing non-word aligned objects :-( */\r#ifdef DES_PTR\r\r/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there\r * is no reason to not xor all the sub items together.  This potentially\r * saves a register since things can be xored directly into L */\r\r#if defined(DES_RISC1) || defined(DES_RISC2)\r#ifdef DES_RISC1\r#define D_ENCRYPT(LL,R,S) { \\r  unsigned int u1,u2,u3; \\r       LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u2=(int)u>>8L; \\r       u1=(int)u&0xfc; \\r      u2&=0xfc; \\r    t=ROTATE(t,4); \\r       u>>=16L; \\r     LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \\r        u3=(int)(u>>8L); \\r     u1=(int)u&0xfc; \\r      u3&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \\r        u2=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u2&=0xfc; \\r    t>>=16L; \\r     LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \\r        u3=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u3&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }\r#endif\r#ifdef DES_RISC2\r#define D_ENCRYPT(LL,R,S) { \\r  unsigned int u1,u2,s1,s2; \\r    LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u2=(int)u>>8L; \\r       u1=(int)u&0xfc; \\r      u2&=0xfc; \\r    t=ROTATE(t,4); \\r       LL^= *(DES_LONG *)((unsigned char *)des_SP      +u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \\r        s1=(int)(u>>16L); \\r    s2=(int)(u>>24L); \\r    s1&=0xfc; \\r    s2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \\r        u2=(int)t>>8L; \\r       u1=(int)t&0xfc; \\r      u2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \\r        s1=(int)(t>>16L); \\r    s2=(int)(t>>24L); \\r    s1&=0xfc; \\r    s2&=0xfc; \\r    LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \\r        LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }\r#endif\r#else\r#define D_ENCRYPT(LL,R,S) { \\r     LOAD_DATA_tmp(R,S,u,t,E0,E1); \\r        t=ROTATE(t,4); \\r       LL^= \\r *(DES_LONG *)((unsigned char *)des_SP      +((u     )&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x100+((t     )&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \\r        *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }\r#endif\r\r#else /* original version */\r\r#if defined(DES_RISC1) || defined(DES_RISC2)\r#ifdef DES_RISC1\r#define D_ENCRYPT(LL,R,S) {\\r       unsigned int u1,u2,u3; \\r       LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u>>=2L; \\r      t=ROTATE(t,6); \\r       u2=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u2&=0x3f; \\r    u>>=16L; \\r     LL^=des_SPtrans[0][u1]; \\r      LL^=des_SPtrans[2][u2]; \\r      u3=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u3&=0x3f; \\r    LL^=des_SPtrans[4][u1]; \\r      LL^=des_SPtrans[6][u3]; \\r      u2=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u2&=0x3f; \\r    t>>=16L; \\r     LL^=des_SPtrans[1][u1]; \\r      LL^=des_SPtrans[3][u2]; \\r      u3=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u3&=0x3f; \\r    LL^=des_SPtrans[5][u1]; \\r      LL^=des_SPtrans[7][u3]; }\r#endif\r#ifdef DES_RISC2\r#define D_ENCRYPT(LL,R,S) {\\r unsigned int u1,u2,s1,s2; \\r    LOAD_DATA(R,S,u,t,E0,E1,u1); \\r u>>=2L; \\r      t=ROTATE(t,6); \\r       u2=(int)u>>8L; \\r       u1=(int)u&0x3f; \\r      u2&=0x3f; \\r    LL^=des_SPtrans[0][u1]; \\r      LL^=des_SPtrans[2][u2]; \\r      s1=(int)u>>16L; \\r      s2=(int)u>>24L; \\r      s1&=0x3f; \\r    s2&=0x3f; \\r    LL^=des_SPtrans[4][s1]; \\r      LL^=des_SPtrans[6][s2]; \\r      u2=(int)t>>8L; \\r       u1=(int)t&0x3f; \\r      u2&=0x3f; \\r    LL^=des_SPtrans[1][u1]; \\r      LL^=des_SPtrans[3][u2]; \\r      s1=(int)t>>16; \\r       s2=(int)t>>24L; \\r      s1&=0x3f; \\r    s2&=0x3f; \\r    LL^=des_SPtrans[5][s1]; \\r      LL^=des_SPtrans[7][s2]; }\r#endif\r\r#else\r\r#define D_ENCRYPT(LL,R,S) {\\r  LOAD_DATA_tmp(R,S,u,t,E0,E1); \\r        t=ROTATE(t,4); \\r       LL^=\\r          des_SPtrans[0][(u>> 2L)&0x3f]^ \\r               des_SPtrans[2][(u>>10L)&0x3f]^ \\r               des_SPtrans[4][(u>>18L)&0x3f]^ \\r               des_SPtrans[6][(u>>26L)&0x3f]^ \\r               des_SPtrans[1][(t>> 2L)&0x3f]^ \\r               des_SPtrans[3][(t>>10L)&0x3f]^ \\r               des_SPtrans[5][(t>>18L)&0x3f]^ \\r               des_SPtrans[7][(t>>26L)&0x3f]; }\r#endif\r#endif\r\r        /* IP and FP\r    * The problem is more of a geometric problem that random bit fiddling.\r         0  1  2  3  4  5  6  7      62 54 46 38 30 22 14  6\r    8  9 10 11 12 13 14 15      60 52 44 36 28 20 12  4\r   16 17 18 19 20 21 22 23      58 50 42 34 26 18 10  2\r   24 25 26 27 28 29 30 31  to  56 48 40 32 24 16  8  0\r\r  32 33 34 35 36 37 38 39      63 55 47 39 31 23 15  7\r   40 41 42 43 44 45 46 47      61 53 45 37 29 21 13  5\r   48 49 50 51 52 53 54 55      59 51 43 35 27 19 11  3\r   56 57 58 59 60 61 62 63      57 49 41 33 25 17  9  1\r\r  The output has been subject to swaps of the form\r       0 1 -> 3 1 but the odd and even bits have been put into\r        2 3    2 0\r     different words.  The main trick is to remember that\r   t=((l>>size)^r)&(mask);\r        r^=t;\r  l^=(t<<size);\r  can be used to swap and move bits between words.\r\r      So l =  0  1  2  3  r = 16 17 18 19\r            4  5  6  7      20 21 22 23\r            8  9 10 11      24 25 26 27\r           12 13 14 15      28 29 30 31\r    becomes (for size == 2 and mask == 0x3333)\r        t =   2^16  3^17 -- --   l =  0  1 16 17  r =  2  3 18 19\r            6^20  7^21 -- --        4  5 20 21       6  7 22 23\r           10^24 11^25 -- --        8  9 24 25      10 11 24 25\r           14^28 15^29 -- --       12 13 28 29      14 15 28 29\r\r  Thanks for hints from Richard Outerbridge - he told me IP&FP\r   could be done in 15 xor, 10 shifts and 5 ands.\r When I finally started to think of the problem in 2D\r   I first got ~42 operations without xors.  When I remembered\r    how to use xors :-) I got it to its final state.\r       */\r#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\\r    (b)^=(t),\\r     (a)^=((t)<<(n)))\r\r#define IP(l,r) \\r    { \\r    register DES_LONG tt; \\r        PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \\r      PERM_OP(l,r,tt,16,0x0000ffffL); \\r      PERM_OP(r,l,tt, 2,0x33333333L); \\r      PERM_OP(l,r,tt, 8,0x00ff00ffL); \\r      PERM_OP(r,l,tt, 1,0x55555555L); \\r      }\r\r#define FP(l,r) \\r   { \\r    register DES_LONG tt; \\r        PERM_OP(l,r,tt, 1,0x55555555L); \\r      PERM_OP(r,l,tt, 8,0x00ff00ffL); \\r      PERM_OP(l,r,tt, 2,0x33333333L); \\r      PERM_OP(r,l,tt,16,0x0000ffffL); \\r      PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \\r      }\r\rextern const DES_LONG des_SPtrans[8][64];\r\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_opts.c b/mac/libdes/src/des_opts.c
new file mode 100755 (executable)
index 0000000..6a71981
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des_opts.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.\r * This is for machines with 64k code segment size restrictions. */\r\r#ifndef MSDOS\r#define TIMES\r#endif\r\r#include <stdio.h>\r#ifndef MSDOS\r#include <unistd.h>\r#else\r#include <io.h>\rextern void exit();\r#endif\r#include <signal.h>\r#ifndef VMS\r#ifndef _IRIX\r#include <time.h>\r#endif\r#ifdef TIMES\r#include <sys/types.h>\r#include <sys/times.h>\r#endif\r#else /* VMS */\r#include <types.h>\rstruct tms {\r      time_t tms_utime;\r      time_t tms_stime;\r      time_t tms_uchild;      /* I dunno...  */\r      time_t tms_uchildsys;   /* so these names are a guess :-) */\r   }\r#endif\r#ifndef TIMES\r#include <sys/timeb.h>\r#endif\r\r#ifdef sun\r#include <limits.h>\r#include <sys/param.h>\r#endif\r\r#include "des.h"\r#include "spr.h"\r\r#define DES_DEFAULT_OPTIONS\r\r#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)\r#define PART1\r#define PART2\r#define PART3\r#define PART4\r#endif\r\r#ifdef PART1\r\r#undef DES_UNROLL\r#undef DES_RISC1\r#undef DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#define des_encrypt  des_encrypt_u4_cisc_idx\r#define des_encrypt2 des_encrypt2_u4_cisc_idx\r#define des_encrypt3 des_encrypt3_u4_cisc_idx\r#define des_decrypt3 des_decrypt3_u4_cisc_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#undef DES_RISC1\r#undef DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_cisc_idx\r#define des_encrypt2 des_encrypt2_u16_cisc_idx\r#define des_encrypt3 des_encrypt3_u16_cisc_idx\r#define des_decrypt3 des_decrypt3_u16_cisc_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#undef DES_UNROLL\r#define DES_RISC1\r#undef DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u4_risc1_idx\r#define des_encrypt2 des_encrypt2_u4_risc1_idx\r#define des_encrypt3 des_encrypt3_u4_risc1_idx\r#define des_decrypt3 des_decrypt3_u4_risc1_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#endif\r\r#ifdef PART2\r\r#undef DES_UNROLL\r#undef DES_RISC1\r#define DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u4_risc2_idx\r#define des_encrypt2 des_encrypt2_u4_risc2_idx\r#define des_encrypt3 des_encrypt3_u4_risc2_idx\r#define des_decrypt3 des_decrypt3_u4_risc2_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#define DES_RISC1\r#undef DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_risc1_idx\r#define des_encrypt2 des_encrypt2_u16_risc1_idx\r#define des_encrypt3 des_encrypt3_u16_risc1_idx\r#define des_decrypt3 des_decrypt3_u16_risc1_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#undef DES_RISC1\r#define DES_RISC2\r#undef DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_risc2_idx\r#define des_encrypt2 des_encrypt2_u16_risc2_idx\r#define des_encrypt3 des_encrypt3_u16_risc2_idx\r#define des_decrypt3 des_decrypt3_u16_risc2_idx\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#endif\r\r#ifdef PART3\r\r#undef DES_UNROLL\r#undef DES_RISC1\r#undef DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u4_cisc_ptr\r#define des_encrypt2 des_encrypt2_u4_cisc_ptr\r#define des_encrypt3 des_encrypt3_u4_cisc_ptr\r#define des_decrypt3 des_decrypt3_u4_cisc_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#undef DES_RISC1\r#undef DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_cisc_ptr\r#define des_encrypt2 des_encrypt2_u16_cisc_ptr\r#define des_encrypt3 des_encrypt3_u16_cisc_ptr\r#define des_decrypt3 des_decrypt3_u16_cisc_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#undef DES_UNROLL\r#define DES_RISC1\r#undef DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u4_risc1_ptr\r#define des_encrypt2 des_encrypt2_u4_risc1_ptr\r#define des_encrypt3 des_encrypt3_u4_risc1_ptr\r#define des_decrypt3 des_decrypt3_u4_risc1_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#endif\r\r#ifdef PART4\r\r#undef DES_UNROLL\r#undef DES_RISC1\r#define DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u4_risc2_ptr\r#define des_encrypt2 des_encrypt2_u4_risc2_ptr\r#define des_encrypt3 des_encrypt3_u4_risc2_ptr\r#define des_decrypt3 des_decrypt3_u4_risc2_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#define DES_RISC1\r#undef DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_risc1_ptr\r#define des_encrypt2 des_encrypt2_u16_risc1_ptr\r#define des_encrypt3 des_encrypt3_u16_risc1_ptr\r#define des_decrypt3 des_decrypt3_u16_risc1_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#define DES_UNROLL\r#undef DES_RISC1\r#define DES_RISC2\r#define DES_PTR\r#undef D_ENCRYPT\r#undef des_encrypt\r#undef des_encrypt2\r#undef des_encrypt3\r#undef des_decrypt3\r#define des_encrypt  des_encrypt_u16_risc2_ptr\r#define des_encrypt2 des_encrypt2_u16_risc2_ptr\r#define des_encrypt3 des_encrypt3_u16_risc2_ptr\r#define des_decrypt3 des_decrypt3_u16_risc2_ptr\r#undef HEADER_DES_LOCL_H\r#include "des_enc.c"\r\r#endif\r\r/* The following if from times(3) man page.  It may need to be changed */\r#ifndef HZ\r#ifndef CLK_TCK\r#ifndef VMS\r#define HZ   100.0\r#else /* VMS */\r#define HZ        100.0\r#endif\r#else /* CLK_TCK */\r#define HZ ((double)CLK_TCK)\r#endif\r#endif\r\r#define BUFSIZE    ((long)1024)\rlong run=0;\r\r#ifndef NOPROTO\rdouble Time_F(int s);\r#else\rdouble Time_F();\r#endif\r\r#ifdef SIGALRM\r#if defined(__STDC__) || defined(sgi)\r#define SIGRETTYPE void\r#else\r#define SIGRETTYPE int\r#endif\r\r#ifndef NOPROTO\rSIGRETTYPE sig_done(int sig);\r#else\rSIGRETTYPE sig_done();\r#endif\r\rSIGRETTYPE sig_done(sig)\rint sig;\r  {\r      signal(SIGALRM,sig_done);\r      run=0;\r#ifdef LINT\r     sig=sig;\r#endif\r        }\r#endif\r\r#define START 0\r#define STOP  1\r\rdouble Time_F(s)\rint s;\r     {\r      double ret;\r#ifdef TIMES\r       static struct tms tstart,tend;\r\r        if (s == START)\r                {\r              times(&tstart);\r                return(0);\r             }\r      else\r           {\r              times(&tend);\r          ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;\r            return((ret == 0.0)?1e-6:ret);\r         }\r#else /* !times() */\r static struct timeb tstart,tend;\r       long i;\r\r       if (s == START)\r                {\r              ftime(&tstart);\r                return(0);\r             }\r      else\r           {\r              ftime(&tend);\r          i=(long)tend.millitm-(long)tstart.millitm;\r             ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;\r              return((ret == 0.0)?1e-6:ret);\r         }\r#endif\r       }\r\r#ifdef SIGALRM\r#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);\r#else\r#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);\r#endif\r        \r#define time_it(func,name,index) \\r    print_name(name); \\r    Time_F(START); \\r       for (count=0,run=1; COND(cb); count++) \\r               { \\r            unsigned long d[2]; \\r          func(d,&(sch[0]),DES_ENCRYPT); \\r               } \\r    tm[index]=Time_F(STOP); \\r      fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \\r    tm[index]=((double)COUNT(cb))/tm[index];\r\r#define print_it(name,index) \\r       fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \\r         tm[index]*8,1.0e6/tm[index]);\r\rint main(argc,argv)\rint argc;\rchar **argv;\r      {\r      long count;\r    static unsigned char buf[BUFSIZE];\r     static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};\r      static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};\r      static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};\r      des_key_schedule sch,sch2,sch3;\r        double d,tm[16],max=0;\r int rank[16];\r  char *str[16];\r int max_idx=0,i,num=0,j;\r#ifndef SIGALARM\r      long ca,cb,cc,cd,ce;\r#endif\r\r   for (i=0; i<12; i++)\r           {\r              tm[i]=0.0;\r             rank[i]=0;\r             }\r\r#ifndef TIMES\r       fprintf(stderr,"To get the most acurate results, try to run this\n");\r  fprintf(stderr,"program when this computer is idle.\n");\r#endif\r\r       des_set_key((C_Block *)key,sch);\r       des_set_key((C_Block *)key2,sch2);\r     des_set_key((C_Block *)key3,sch3);\r\r#ifndef SIGALRM\r    fprintf(stderr,"First we calculate the approximate speed ...\n");\r      des_set_key((C_Block *)key,sch);\r       count=10;\r      do      {\r              long i;\r                unsigned long data[2];\r\r                count*=2;\r              Time_F(START);\r         for (i=count; i; i--)\r                  des_encrypt(data,&(sch[0]),DES_ENCRYPT);\r               d=Time_F(STOP);\r                } while (d < 3.0);\r     ca=count;\r      cb=count*3;\r    cc=count*3*8/BUFSIZE+1;\r        cd=count*8/BUFSIZE+1;\r\r ce=count/20+1;\r#define COND(d) (count != (d))\r#define COUNT(d) (d)\r#else\r#define COND(c) (run)\r#define COUNT(d) (count)\r        signal(SIGALRM,sig_done);\r        alarm(10);\r#endif\r\r#ifdef PART1\r      time_it(des_encrypt_u4_cisc_idx,  "des_encrypt_u4_cisc_idx  ", 0);\r     time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);\r     time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);\r     num+=3;\r#endif\r#ifdef PART2\r    time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);\r     time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);\r     time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);\r     num+=3;\r#endif\r#ifdef PART3\r    time_it(des_encrypt_u4_cisc_ptr,  "des_encrypt_u4_cisc_ptr  ", 6);\r     time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);\r     time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);\r     num+=3;\r#endif\r#ifdef PART4\r    time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);\r     time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);\r     time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);\r     num+=3;\r#endif\r\r#ifdef PART1\r   str[0]=" 4  c i";\r      print_it("des_encrypt_u4_cisc_idx  ",0);\r       max=tm[0];\r     max_idx=0;\r     str[1]="16  c i";\r      print_it("des_encrypt_u16_cisc_idx ",1);\r       if (max < tm[1]) { max=tm[1]; max_idx=1; }\r     str[2]=" 4 r1 i";\r      print_it("des_encrypt_u4_risc1_idx ",2);\r       if (max < tm[2]) { max=tm[2]; max_idx=2; }\r#endif\r#ifdef PART2\r str[3]="16 r1 i";\r      print_it("des_encrypt_u16_risc1_idx",3);\r       if (max < tm[3]) { max=tm[3]; max_idx=3; }\r     str[4]=" 4 r2 i";\r      print_it("des_encrypt_u4_risc2_idx ",4);\r       if (max < tm[4]) { max=tm[4]; max_idx=4; }\r     str[5]="16 r2 i";\r      print_it("des_encrypt_u16_risc2_idx",5);\r       if (max < tm[5]) { max=tm[5]; max_idx=5; }\r#endif\r#ifdef PART3\r str[6]=" 4  c p";\r      print_it("des_encrypt_u4_cisc_ptr  ",6);\r       if (max < tm[6]) { max=tm[6]; max_idx=6; }\r     str[7]="16  c p";\r      print_it("des_encrypt_u16_cisc_ptr ",7);\r       if (max < tm[7]) { max=tm[7]; max_idx=7; }\r     str[8]=" 4 r1 p";\r      print_it("des_encrypt_u4_risc1_ptr ",8);\r       if (max < tm[8]) { max=tm[8]; max_idx=8; }\r#endif\r#ifdef PART4\r str[9]="16 r1 p";\r      print_it("des_encrypt_u16_risc1_ptr",9);\r       if (max < tm[9]) { max=tm[9]; max_idx=9; }\r     str[10]=" 4 r2 p";\r     print_it("des_encrypt_u4_risc2_ptr ",10);\r      if (max < tm[10]) { max=tm[10]; max_idx=10; }\r  str[11]="16 r2 p";\r     print_it("des_encrypt_u16_risc2_ptr",11);\r      if (max < tm[11]) { max=tm[11]; max_idx=11; }\r#endif\r   printf("options    des ecb/s\n");\r      printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);\r        d=tm[max_idx];\r tm[max_idx]= -2.0;\r     max= -1.0;\r     for (;;)\r               {\r              for (i=0; i<12; i++)\r                   {\r                      if (max < tm[i]) { max=tm[i]; j=i; }\r                   }\r              if (max < 0.0) break;\r          printf("%s %12.2f  %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);\r             tm[j]= -2.0;\r           max= -1.0;\r             }\r\r     switch (max_idx)\r               {\r      case 0:\r                printf("-DDES_DEFAULT_OPTIONS\n");\r             break;\r case 1:\r                printf("-DDES_UNROLL\n");\r              break;\r case 2:\r                printf("-DDES_RISC1\n");\r               break;\r case 3:\r                printf("-DDES_UNROLL -DDES_RISC1\n");\r          break;\r case 4:\r                printf("-DDES_RISC2\n");\r               break;\r case 5:\r                printf("-DDES_UNROLL -DDES_RISC2\n");\r          break;\r case 6:\r                printf("-DDES_PTR\n");\r         break;\r case 7:\r                printf("-DDES_UNROLL -DDES_PTR\n");\r            break;\r case 8:\r                printf("-DDES_RISC1 -DDES_PTR\n");\r             break;\r case 9:\r                printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");\r                break;\r case 10:\r               printf("-DDES_RISC2 -DDES_PTR\n");\r             break;\r case 11:\r               printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");\r                break;\r         }\r      exit(0);\r#if defined(LINT) || defined(MSDOS)\r   return(0);\r#endif\r      }\r
\ No newline at end of file
diff --git a/mac/libdes/src/des_ver.h b/mac/libdes/src/des_ver.h
new file mode 100755 (executable)
index 0000000..746c01d
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/des_ver.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\rextern char *DES_version;      /* SSLeay version string */\rextern char *libdes_version;        /* old libdes version string */\r
\ No newline at end of file
diff --git a/mac/libdes/src/dllmain.c b/mac/libdes/src/dllmain.c
new file mode 100755 (executable)
index 0000000..a898636
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\rRCSID("$Id: dllmain.c,v 1.2 2001/12/04 02:06:29 rjs3 Exp $");\r#endif\r\r#include <Windows.h>\r\rBOOL WINAPI\rDllMain (HANDLE hInst, \r    ULONG reason,\r  LPVOID lpReserved)\r{\r    switch(reason) {\r    case DLL_PROCESS_ATTACH:\r    case DLL_PROCESS_DETACH:\r    default:\r      return TRUE;\r    }\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/doIP b/mac/libdes/src/doIP
new file mode 100755 (executable)
index 0000000..b0a4dbe
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r@l=(\r    0, 1, 2, 3, 4, 5, 6, 7,\r        8, 9,10,11,12,13,14,15,\r       16,17,18,19,20,21,22,23,\r       24,25,26,27,28,29,30,31\r        );\r@r=(\r        32,33,34,35,36,37,38,39,\r       40,41,42,43,44,45,46,47,\r       48,49,50,51,52,53,54,55,\r       56,57,58,59,60,61,62,63\r        );\r\rrequire 'shifts.pl';\r\rsub PERM_OP\r  {\r      local(*a,*b,*t,$n,$m)=@_;\r\r     @z=&shift(*a,-$n);\r     @z=&xor(*b,*z);\r        @z=&and(*z,$m);\r        @b=&xor(*b,*z);\r        @z=&shift(*z,$n);\r      @a=&xor(*a,*z);\r        }\r\r\r@L=@l;\r@R=@r;\r&PERM_OP(*R,*L,*T,4,0x0f0f0f0f);\r&PERM_OP(*L,*R,*T,16,0x0000ffff);\r&PERM_OP(*R,*L,*T,2,0x33333333);\r&PERM_OP(*L,*R,*T,8,0x00ff00ff);\r&PERM_OP(*R,*L,*T,1,0x55555555);\r        &printit(@L);\r  &printit(@R);\r&PERM_OP(*R,*L,*T,1,0x55555555);\r&PERM_OP(*L,*R,*T,8,0x00ff00ff);\r&PERM_OP(*R,*L,*T,2,0x33333333);\r&PERM_OP(*L,*R,*T,16,0x0000ffff);\r&PERM_OP(*R,*L,*T,4,0x0f0f0f0f);\r    &printit(@L);\r  &printit(@R);\r
\ No newline at end of file
diff --git a/mac/libdes/src/doPC1 b/mac/libdes/src/doPC1
new file mode 100755 (executable)
index 0000000..f4827e6
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r@l=(\r    0, 1, 2, 3, 4, 5, 6, 7,\r        8, 9,10,11,12,13,14,15,\r       16,17,18,19,20,21,22,23,\r       24,25,26,27,28,29,30,31\r        );\r@r=(\r        32,33,34,35,36,37,38,39,\r       40,41,42,43,44,45,46,47,\r       48,49,50,51,52,53,54,55,\r       56,57,58,59,60,61,62,63\r        );\r\rrequire 'shifts.pl';\r\rsub PERM_OP\r  {\r      local(*a,*b,*t,$n,$m)=@_;\r\r     @z=&shift(*a,-$n);\r     @z=&xor(*b,*z);\r        @z=&and(*z,$m);\r        @b=&xor(*b,*z);\r        @z=&shift(*z,$n);\r      @a=&xor(*a,*z);\r        }\r\rsub HPERM_OP2\r       {\r      local(*a,*t,$n,$m)=@_;\r local(@x,@y,$i);\r\r      @z=&shift(*a,16-$n);\r   @z=&xor(*a,*z);\r        @z=&and(*z,$m);\r        @a=&xor(*a,*z);\r        @z=&shift(*z,$n-16);\r   @a=&xor(*a,*z);\r        }\r\rsub HPERM_OP\r        {\r        local(*a,*t,$n,$m)=@_;\r        local(@x,@y,$i);\r\r        for ($i=0; $i<16; $i++)\r                {\r                $x[$i]=$a[$i];\r                $y[$i]=$a[16+$i];\r                }\r        @z=&shift(*x,-$n);\r        @z=&xor(*y,*z);\r        @z=&and(*z,$m);\r        @y=&xor(*y,*z);\r        @z=&shift(*z,$n);\r        @x=&xor(*x,*z);\r        for ($i=0; $i<16; $i++)\r                {\r                $a[$i]=$x[$i];\r                $a[16+$i]=$y[$i];\r                }\r        }\r\r@L=@l;\r@R=@r;\r\r    print "---\n"; &printit(@R);\r&PERM_OP(*R,*L,*T,4,0x0f0f0f0f);\r  print "---\n"; &printit(@R);\r&HPERM_OP2(*L,*T,-2,0xcccc0000);\r&HPERM_OP2(*R,*T,-2,0xcccc0000);\r print "---\n"; &printit(@R);\r&PERM_OP(*R,*L,*T,1,0x55555555);\r  print "---\n"; &printit(@R);\r&PERM_OP(*L,*R,*T,8,0x00ff00ff);\r  print "---\n"; &printit(@R);\r&PERM_OP(*R,*L,*T,1,0x55555555);\r  print "---\n"; &printit(@R);\r#  &printit(@L);\r  &printit(@R);\rprint <<"EOF";\r==============================\r63  55  47  39  31  23  15   7  \r62  54  46  38  30  22  14   6  \r61  53  45  37  29  21  13   5  \r60  52  44  36  --  --  --  --  \r\r57  49  41  33  25  17   9   1  \r58  50  42  34  26  18  10   2  \r59  51  43  35  27  19  11   3  \r28  20  12   4  --  --  --  --  \rEOF\rexit(1);\r@A=&and(*R,0x000000ff);\r@A=&shift(*A,16);\r@B=&and(*R,0x0000ff00);\r@C=&and(*R,0x00ff0000);\r@C=&shift(*C,-16);\r@D=&and(*L,0xf0000000);\r@D=&shift(*D,-4);\r@A=&or(*A,*B);\r@B=&or(*D,*C);\r@R=&or(*A,*B);\r@L=&and(*L,0x0fffffff);\r\r &printit(@L);\r  &printit(@R);\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/doPC2 b/mac/libdes/src/doPC2
new file mode 100755 (executable)
index 0000000..d2c111f
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r@PC2_C=(14,17,11,24, 1, 5,\r      3,28,15, 6,21,10,\r     23,19,12, 4,26, 8,\r     16, 7,27,20,13, 2,\r     );\r\r@PC2_D=(41,52,31,37,47,55,\r 30,40,51,45,33,48,\r     44,49,39,56,34,53,\r     46,42,50,36,29,32,\r     );\r\r$i=0;\rforeach (@PC2_C) {\r   $_--;\r# printf "%2d,",$_;\r      $C{$_}=$i;\r     ++$i;\r# print "\n" if ((($i) % 8) == 0);\r       }\r$i=0;\r#print "\n";\rforeach (@PC2_D) {\r        $_-=28;\r        $_--;\r# printf "%2d,",$_;\r      $D{$_}=$i;\r     $i++;\r# print "\n" if ((($i) % 8) == 0);\r       }\r\r#print "\n";\rforeach $i (0 .. 27)\r   {\r      $_=$C{$i};\r#    printf "%2d,",$_;\r      $i++;\r# print "\n" if ((($i) % 8) == 0);\r       }\r#print "\n";\r\r#print "\n";\rforeach $i (0 .. 27)\r      {\r      $_=$D{$i};\r#    printf "%2d,",$_;\r      $i++;\r# print "\n" if ((($i) % 8) == 0);\r       }\r#print "\n";\r\rprint "static ulong skb[8][64]={\n";\r&doit("C",*C, 0, 1, 2, 3, 4, 5);\r&doit("C",*C, 6, 7, 9,10,11,12);\r&doit("C",*C,13,14,15,16,18,19);\r&doit("C",*C,20,22,23,25,26,27);\r\r&doit("D",*D, 0, 1, 2, 3, 4, 5);\r&doit("D",*D, 7, 8,10,11,12,13);\r&doit("D",*D,15,16,17,18,19,20);\r&doit("D",*D,21,22,23,24,26,27);\rprint "};\n";\r\rsub doit\r  {\r      local($l,*A,@b)=@_;\r    local(@out);\r\r  printf("/* for $l bits (numbered as per FIPS 46) %d %d %d %d %d %d */\n",\r              $b[0]+1, $b[1]+1, $b[2]+1, $b[3]+1, $b[4]+1, $b[5]+1);\r for ($i=0; $i<64; $i++)\r                {\r              $out[$i]=0;\r            $j=1;\r#print "\n";\r             for ($k=0; $k<6; $k++)\r                 {\r                      $l=$A{$b[$k]};\r#print"$l - ";\r                  if ((1<<$k) & $i)\r                              {\r                              $ll=int($l/6)*8+($l%6);\r                                $out[$i]|=1<<($ll);\r                            }\r                      }\r              $pp=$out[$i];\r          $pp=($pp&0xff0000ff)|   (($pp&0x00ff0000)>>8)|\r                                 (($pp&0x0000ff00)<<8);\r         printf("0x%08X,",$pp);\r         print "\n" if (($i+1) % 4 == 0);\r               }\r      }\r
\ No newline at end of file
diff --git a/mac/libdes/src/ecb3_enc.c b/mac/libdes/src/ecb3_enc.c
new file mode 100755 (executable)
index 0000000..eeb0e62
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ecb3_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_ecb3_encrypt(input, output, ks1, ks2, ks3, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_key_schedule ks3;\rint encrypt;\r        {\r      register DES_LONG l0,l1;\r       register unsigned char *in,*out;\r       DES_LONG ll[2];\r\r       in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   c2l(in,l0);\r    c2l(in,l1);\r    ll[0]=l0;\r      ll[1]=l1;\r      if (encrypt)\r           des_encrypt3(ll,ks1,ks2,ks3);\r  else\r           des_decrypt3(ll,ks1,ks2,ks3);\r  l0=ll[0];\r      l1=ll[1];\r      l2c(l0,out);\r   l2c(l1,out);\r   }\r
\ No newline at end of file
diff --git a/mac/libdes/src/ecb_enc.c b/mac/libdes/src/ecb_enc.c
new file mode 100755 (executable)
index 0000000..d2a5e89
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ecb_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r#include "spr.h"\r\rchar *libdes_version="libdes v 4.01 - 13-Jan-1997 - eay";\rchar *DES_version="DES part of SSLeay 0.6.6 14-Jan-1997";\r\rchar *des_options()\r      {\r      static int init=1;\r     static char buf[32];\r\r  if (init)\r              {\r              char *ptr,*unroll,*risc,*size;\r\r                init=0;\r#ifdef DES_PTR\r         ptr="ptr";\r#else\r               ptr="idx";\r#endif\r#if defined(DES_RISC1) || defined(DES_RISC2)\r#ifdef DES_RISC1\r                risc="risc1";\r#endif\r#ifdef DES_RISC2\r          risc="risc2";\r#endif\r#else\r             risc="cisc";\r#endif\r#ifdef DES_UNROLL\r          unroll="16";\r#else\r             unroll="4";\r#endif\r             if (sizeof(DES_LONG) != sizeof(long))\r                  size="int";\r            else\r                   size="long";\r           sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);\r          }\r      return(buf);\r   }\r              \r\rvoid des_ecb_encrypt(input, output, ks, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rdes_key_schedule ks;\rint encrypt;\r        {\r      register DES_LONG l;\r   register unsigned char *in,*out;\r       DES_LONG ll[2];\r\r       in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   c2l(in,l); ll[0]=l;\r    c2l(in,l); ll[1]=l;\r    des_encrypt(ll,ks,encrypt);\r    l=ll[0]; l2c(l,out);\r   l=ll[1]; l2c(l,out);\r   l=ll[0]=ll[1]=0;\r       }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/ede_enc.c b/mac/libdes/src/ede_enc.c
new file mode 100755 (executable)
index 0000000..dae701b
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ede_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_key_schedule ks3;\rdes_cblock (*ivec);\rint encrypt;\r      {\r      register DES_LONG tin0,tin1;\r   register DES_LONG tout0,tout1,xor0,xor1;\r       register unsigned char *in,*out;\r       register long l=length;\r        DES_LONG tin[2];\r       unsigned char *iv;\r\r    in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     if (encrypt)\r           {\r              c2l(iv,tout0);\r         c2l(iv,tout1);\r         for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r                  tin0^=tout0;\r                   tin1^=tout1;\r\r                  tin[0]=tin0;\r                   tin[1]=tin1;\r                   des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);\r                     tout0=tin[0];\r                  tout1=tin[1];\r\r                 l2c(tout0,out);\r                        l2c(tout1,out);\r                        }\r              if (l != -8)\r                   {\r                      c2ln(in,tin0,tin1,l+8);\r                        tin0^=tout0;\r                   tin1^=tout1;\r\r                  tin[0]=tin0;\r                   tin[1]=tin1;\r                   des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);\r                     tout0=tin[0];\r                  tout1=tin[1];\r\r                 l2c(tout0,out);\r                        l2c(tout1,out);\r                        }\r              iv=(unsigned char *)ivec;\r              l2c(tout0,iv);\r         l2c(tout1,iv);\r         }\r      else\r           {\r              register DES_LONG t0,t1;\r\r              c2l(iv,xor0);\r          c2l(iv,xor1);\r          for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r\r                 t0=tin0;\r                       t1=tin1;\r\r                      tin[0]=tin0;\r                   tin[1]=tin1;\r                   des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);\r                     tout0=tin[0];\r                  tout1=tin[1];\r\r                 tout0^=xor0;\r                   tout1^=xor1;\r                   l2c(tout0,out);\r                        l2c(tout1,out);\r                        xor0=t0;\r                       xor1=t1;\r                       }\r              if (l != -8)\r                   {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r\r                 t0=tin0;\r                       t1=tin1;\r\r                      tin[0]=tin0;\r                   tin[1]=tin1;\r                   des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);\r                     tout0=tin[0];\r                  tout1=tin[1];\r\r                 tout0^=xor0;\r                   tout1^=xor1;\r                   l2cn(tout0,tout1,out,l+8);\r                     xor0=t0;\r                       xor1=t1;\r                       }\r              iv=(unsigned char *)ivec;\r              l2c(xor0,iv);\r          l2c(xor1,iv);\r          }\r      tin0=tin1=tout0=tout1=xor0=xor1=0;\r     tin[0]=tin[1]=0;\r       }\r\r#ifdef undef /* MACRO */\rvoid des_ede2_cbc_encrypt(input, output, length, ks1, ks2, ivec, enc)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule ks1;\rdes_key_schedule ks2;\rdes_cblock (*ivec);\rint enc;\r     {\r      des_ede3_cbc_encrypt(input,output,length,ks1,ks2,ks1,ivec,enc);\r        }\r#endif\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/enc_read.c b/mac/libdes/src/enc_read.c
new file mode 100755 (executable)
index 0000000..80268d2
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/enc_read.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include <stdio.h>\r#include <errno.h>\r#include "des_locl.h"\r\r/* This has some uglies in it but it works - even over sockets. */\r/*extern int errno;*/\rint des_rw_mode=DES_PCBC_MODE;\r\rint des_enc_read(fd, buf, len, sched, iv)\rint fd;\rchar *buf;\rint len;\rdes_key_schedule sched;\rdes_cblock (*iv);\r        {\r      /* data to be unencrypted */\r   int net_num=0;\r static unsigned char *net=NULL;\r        /* extra unencrypted data \r      * for when a block of 100 comes in but is des_read one byte at\r         * a time. */\r  static char *unnet=NULL;\r       static int unnet_start=0;\r      static int unnet_left=0;\r       static char *tmpbuf=NULL;\r      int i;\r long num=0,rnum;\r       unsigned char *p;\r\r     if (tmpbuf == NULL)\r            {\r              tmpbuf=(char *)malloc(BSIZE);\r          if (tmpbuf == NULL) return(-1);\r                }\r      if (net == NULL)\r               {\r              net=(unsigned char *)malloc(BSIZE);\r            if (net == NULL) return(-1);\r           }\r      if (unnet == NULL)\r             {\r              unnet=(char *)malloc(BSIZE);\r           if (unnet == NULL) return(-1);\r         }\r      /* left over data from last decrypt */\r if (unnet_left != 0)\r           {\r              if (unnet_left < len)\r                  {\r                      /* we still still need more data but will return\r                        * with the number of bytes we have - should always\r                     * check the return value */\r                   memcpy(buf,&(unnet[unnet_start]),\r                              (unsigned int)unnet_left);\r                     /* eay 26/08/92 I had the next 2 lines\r                  * reversed :-( */\r                     i=unnet_left;\r                  unnet_start=unnet_left=0;\r                      }\r              else\r                   {\r                      memcpy(buf,&(unnet[unnet_start]),(unsigned int)len);\r                   unnet_start+=len;\r                      unnet_left-=len;\r                       i=len;\r                 }\r              return(i);\r             }\r\r     /* We need to get more data. */\r        if (len > MAXWRITE) len=MAXWRITE;\r\r     /* first - get the length */\r   while (net_num < HDRSIZE) \r             {\r              i=read(fd,&(net[net_num]),(unsigned int)HDRSIZE-net_num);\r              if ((i == -1) && (errno == EINTR)) continue;\r           if (i <= 0) return(0);\r         net_num+=i;\r            }\r\r     /* we now have at net_num bytes in net */\r      p=net;\r /* num=0;  */\r  n2l(p,num);\r    /* num should be rounded up to the next group of eight\r  * we make sure that we have read a multiple of 8 bytes from the net.\r   */\r    if ((num > MAXWRITE) || (num < 0)) /* error */\r         return(-1);\r    rnum=(num < 8)?8:((num+7)/8*8);\r\r       net_num=0;\r     while (net_num < rnum)\r         {\r              i=read(fd,&(net[net_num]),(unsigned int)rnum-net_num);\r         if ((i == -1) && (errno == EINTR)) continue;\r           if (i <= 0) return(0);\r         net_num+=i;\r            }\r\r     /* Check if there will be data left over. */\r   if (len < num)\r         {\r              if (des_rw_mode & DES_PCBC_MODE)\r                       des_pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,\r                                num,sched,iv,DES_DECRYPT);\r             else\r                   des_cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,\r                         num,sched,iv,DES_DECRYPT);\r             memcpy(buf,unnet,(unsigned int)len);\r           unnet_start=len;\r               unnet_left=(int)num-len;\r\r              /* The following line is done because we return num\r             * as the number of bytes read. */\r             num=len;\r               }\r      else\r           {\r              /* >output is a multiple of 8 byes, if len < rnum\r               * >we must be careful.  The user must be aware that this\r               * >routine will write more bytes than he asked for.\r            * >The length of the buffer must be correct.\r           * FIXED - Should be ok now 18-9-90 - eay */\r           if (len < rnum)\r                        {\r\r                     if (des_rw_mode & DES_PCBC_MODE)\r                               des_pcbc_encrypt((des_cblock *)net,\r                                    (des_cblock *)tmpbuf,\r                                  num,sched,iv,DES_DECRYPT);\r                     else\r                           des_cbc_encrypt((des_cblock *)net,\r                                     (des_cblock *)tmpbuf,\r                                  num,sched,iv,DES_DECRYPT);\r\r                    /* eay 26/08/92 fix a bug that returned more\r                    * bytes than you asked for (returned len bytes :-( */\r                 memcpy(buf,tmpbuf,(unsigned int)num);\r                  }\r              else\r                   {\r                      if (des_rw_mode & DES_PCBC_MODE)\r                               des_pcbc_encrypt((des_cblock *)net,\r                                    (des_cblock *)buf,num,sched,iv,\r                                        DES_DECRYPT);\r                  else\r                           des_cbc_encrypt((des_cblock *)net,\r                                     (des_cblock *)buf,num,sched,iv,\r                                        DES_DECRYPT);\r                  }\r              }\r      return((int)num);\r      }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/enc_writ.c b/mac/libdes/src/enc_writ.c
new file mode 100755 (executable)
index 0000000..98e97d3
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/enc_writ.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include <errno.h>\r#include <time.h>\r#include "des_locl.h"\r\rint des_enc_write(fd, buf, len, sched, iv)\rint fd;\rchar *buf;\rint len;\rdes_key_schedule sched;\rdes_cblock (*iv);\r {\r#ifdef _LIBC\r extern int srandom();\r  extern unsigned long time();\r   extern int random();\r   extern int write();\r#endif\r\r    long rnum;\r     int i,j,k,outnum;\r      char *outbuf=NULL;\r     char shortbuf[8];\r      char *p;\r       static int start=1;\r\r   if (outbuf == NULL)\r            {\r              outbuf=(char *)malloc(BSIZE+HDRSIZE);\r          if (outbuf == NULL) return(-1);\r                }\r      /* If we are sending less than 8 bytes, the same char will look\r         * the same if we don't pad it out with random bytes */\r        if (start)\r             {\r              start=0;\r               srandom((unsigned int)time(NULL));\r             }\r\r     /* lets recurse if we want to send the data in small chunks */\r if (len > MAXWRITE)\r            {\r              j=0;\r           for (i=0; i<len; i+=k)\r                 {\r                      k=des_enc_write(fd,&(buf[i]),\r                          ((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);\r                       if (k < 0)\r                             return(k);\r                     else\r                           j+=k;\r                  }\r              return(j);\r             }\r\r     /* write length first */\r       p=outbuf;\r      l2n(len,p);\r\r   /* pad short strings */\r        if (len < 8)\r           {\r              p=shortbuf;\r            memcpy(shortbuf,buf,(unsigned int)len);\r                for (i=len; i<8; i++)\r                  shortbuf[i]=random();\r          rnum=8;\r                }\r      else\r           {\r              p=buf;\r         rnum=((len+7)/8*8); /* round up to nearest eight */\r            }\r\r     if (des_rw_mode & DES_PCBC_MODE)\r               des_pcbc_encrypt((des_cblock *)p,\r                      (des_cblock *)&(outbuf[HDRSIZE]),\r                      (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); \r  else\r           des_cbc_encrypt((des_cblock *)p,\r                       (des_cblock *)&(outbuf[HDRSIZE]),\r                      (long)((len<8)?8:len),sched,iv,DES_ENCRYPT); \r\r /* output */\r   outnum=(int)rnum+HDRSIZE;\r\r     for (j=0; j<outnum; j+=i)\r              {\r              /* eay 26/08/92 I was not doing writing from where we\r           * got upto. */\r                i=write(fd,&(outbuf[j]),(unsigned int)(outnum-j));\r             if (i == -1)\r                   {\r                      if (errno == EINTR)\r                            i=0;\r                   else    /* This is really a bad error - very bad\r                                * It will stuff-up both ends. */\r                              return(-1);\r                    }\r              }\r\r     return(len);\r   }\r
\ No newline at end of file
diff --git a/mac/libdes/src/fcrypt.c b/mac/libdes/src/fcrypt.c
new file mode 100755 (executable)
index 0000000..e1b3719
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/fcrypt.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include <stdio.h>\r\r/* Eric Young.\r * This version of crypt has been developed from my MIT compatable\r * DES library.\r * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au\r * eay@mincom.oz.au or eay@psych.psy.uq.oz.au\r */\r\r/* Modification by Jens Kupferschmidt (Cu)\r * I have included directive PARA for shared memory computers.\r * I have included a directive LONGCRYPT to using this routine to cipher\r * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN\r * definition is the maximum of lenght of password and can changed. I have\r * defined 24.\r */\r\r#define FCRYPT_MOD(R,u,t,E0,E1,tmp) \\r    u=R>>16; \\r     t=R^u; \\r       u=t&E0; t=t&E1; \\r      tmp=(u<<16); u^=R^s[S  ]; u^=tmp; \\r    tmp=(t<<16); t^=R^s[S+1]; t^=tmp\r\r#define DES_FCRYPT\r#include "des_locl.h"\r#undef DES_FCRYPT\r\r#undef PERM_OP\r#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\\r  (b)^=(t),\\r     (a)^=((t)<<(n)))\r\r#undef HPERM_OP\r#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\\r (a)=(a)^(t)^(t>>(16-(n))))\\r\r#ifdef PARA\r#define STATIC\r#else\r#define STATIC    static\r#endif\r\r/* It is really only FreeBSD that still suffers from MD5 based crypts */\r#ifdef __FreeBSD__\r#define MD5_CRYPT_SUPPORT 1\r#endif\r#if     MD5_CRYPT_SUPPORT\r/*\r * ----------------------------------------------------------------------------\r * "THE BEER-WARE LICENSE" (Revision 42):\r * <phk@login.dknet.dk> wrote this file.  As long as you retain this notice you\r * can do whatever you want with this stuff. If we meet some day, and you think\r * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp\r * ----------------------------------------------------------------------------\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\r#endif\r#include <md5.h>\r\rstatic unsigned char itoa64[] =             /* 0 ... 63 => ascii - 64 */\r   "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";\r\rstatic void\rto64(s, v, n)\r char *s;\r       unsigned long v;\r       int n;\r{\r       while (--n >= 0) {\r             *s++ = itoa64[v&0x3f];\r         v >>= 6;\r       }\r}\r\r/*\r * UNIX password\r *\r * Use MD5 for what it is best at...\r */\r\rstatic\rchar *\rcrypt_md5(pw, salt)\r        register const char *pw;\r       register const char *salt;\r{\r   static char     *magic = "$1$"; /*\r                                              * This string is magic for\r                                             * this algorithm.  Having\r                                              * it this way, we can get\r                                              * get better later on\r                                          */\r    static char     passwd[120], *p;\r       static const char *sp,*ep;\r     unsigned char   final[16];\r     int sl,pl,i,j;\r MD5_CTX ctx,ctx1;\r      unsigned long l;\r\r      /* Refine the Salt first */\r    sp = salt;\r\r    /* If it starts with the magic string, then skip that */\r       if(!strncmp(sp,magic,strlen(magic)))\r           sp += strlen(magic);\r\r  /* It stops at the first '$', max 8 chars */\r   for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)\r               continue;\r\r     /* get the length of the true salt */\r  sl = ep - sp;\r\r MD5Init(&ctx);\r\r        /* The password first, since that is what is most unknown */\r   MD5Update(&ctx,pw,strlen(pw));\r\r        /* Then our magic string */\r    MD5Update(&ctx,magic,strlen(magic));\r\r  /* Then the raw salt */\r        MD5Update(&ctx,sp,sl);\r\r        /* Then just as many characters of the MD5(pw,salt,pw) */\r      MD5Init(&ctx1);\r        MD5Update(&ctx1,pw,strlen(pw));\r        MD5Update(&ctx1,sp,sl);\r        MD5Update(&ctx1,pw,strlen(pw));\r        MD5Final(final,&ctx1);\r for(pl = strlen(pw); pl > 0; pl -= 16)\r         MD5Update(&ctx,final,pl>16 ? 16 : pl);\r\r        /* Don't leave anything around in vm they could use. */\r        memset(final,0,sizeof final);\r\r /* Then something really weird... */\r   for (j=0,i = strlen(pw); i ; i >>= 1)\r          if(i&1)\r                    MD5Update(&ctx, final+j, 1);\r               else\r               MD5Update(&ctx, pw+j, 1);\r\r /* Now make the output string */\r       snprintf (passwd, sizeof(passwd),\r                "%s%.*s$", magic, sl, sp);\r\r  MD5Final(final,&ctx);\r\r /*\r      * and now, just to make sure things don't run too fast\r         * On a 60 Mhz Pentium this takes 34 msec, so you would\r         * need 30 seconds to build a 1000 entry dictionary...\r  */\r    for(i=0;i<1000;i++) {\r          MD5Init(&ctx1);\r                if(i & 1)\r                      MD5Update(&ctx1,pw,strlen(pw));\r                else\r                   MD5Update(&ctx1,final,16);\r\r            if(i % 3)\r                      MD5Update(&ctx1,sp,sl);\r\r               if(i % 7)\r                      MD5Update(&ctx1,pw,strlen(pw));\r\r               if(i & 1)\r                      MD5Update(&ctx1,final,16);\r             else\r                   MD5Update(&ctx1,pw,strlen(pw));\r                MD5Final(final,&ctx1);\r }\r\r     p = passwd + strlen(passwd);\r\r  l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;\r l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;\r l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;\r l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;\r l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;\r l =                    final[11]                ; to64(p,l,2); p += 2;\r *p = '\0';\r\r    /* Don't leave anything around in vm they could use. */\r        memset(final,0,sizeof final);\r\r return passwd;\r}\r#endif /* MD5_CRYPT_SUPPORT */\r\r#ifndef NOPROTO\r\rSTATIC int fcrypt_body(DES_LONG *out0, DES_LONG *out1,\r       des_key_schedule ks, DES_LONG Eswap0, DES_LONG Eswap1);\r\r#else\r\rSTATIC int fcrypt_body();\r\r#endif\r\r/* Added more values to handle illegal salt values the way normal\r * crypt() implementations do.  The patch was sent by \r * Bjorn Gronvall <bg@sics.se>\r */\rstatic unsigned const char con_salt[128]={\r0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,\r0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,\r0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,\r0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,\r0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,\r0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,\r0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,\r0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,\r0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,\r0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,\r0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,\r0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,\r0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,\r0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,\r0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,\r0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,\r};\r\rstatic unsigned const char cov_2char[64]={\r0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,\r0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,\r0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,\r0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,\r0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,\r0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,\r0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,\r0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A\r};\r\r#ifndef NOPROTO\r#ifdef PERL5\rchar *des_crypt(const char *buf,const char *salt);\r#else\rchar *crypt(const char *buf,const char *salt);\r#endif\r#else\r#ifdef PERL5\rchar *des_crypt();\r#else\rchar *crypt();\r#endif\r#endif\r\r#ifdef PERL5\rchar *des_crypt(buf,salt)\r#else\rchar *crypt(buf,salt)\r#endif\rconst char *buf;\rconst char *salt;\r {\r      static char buff[14];\r\r#if     MD5_CRYPT_SUPPORT\r       if (!strncmp(salt, "$1$", 3))\r          return crypt_md5(buf, salt);\r#endif\r\r   return(des_fcrypt(buf,salt,buff));\r     }\r\r\rchar *des_fcrypt(buf,salt,ret)\rconst char *buf;\rconst char *salt;\rchar *ret;\r       {\r      unsigned int i,j,x,y;\r  DES_LONG Eswap0,Eswap1;\r        DES_LONG out[2],ll;\r    des_cblock key;\r        des_key_schedule ks;\r   unsigned char bb[9];\r   unsigned char *b=bb;\r   unsigned char c,u;\r\r    /* eay 25/08/92\r         * If you call crypt("pwd","*") as often happens when you\r       * have * as the pwd field in /etc/passwd, the function\r         * returns *\0XXXXXXXXX\r         * The \0 makes the string look like * so the pwd "*" would\r     * crypt to "*".  This was found when replacing the crypt in\r    * our shared libraries.  People found that the disbled\r         * accounts effectivly had no passwd :-(. */\r   x=ret[0]=((salt[0] == '\0')?'A':salt[0]);\r      Eswap0=con_salt[x]<<2;\r x=ret[1]=((salt[1] == '\0')?'A':salt[1]);\r      Eswap1=con_salt[x]<<6;\r\r/* EAY\rr=strlen(buf);\rr=(r+7)/8;\r*/\r    for (i=0; i<8; i++)\r            {\r              c= *(buf++);\r           if (!c) break;\r         key[i]=(c<<1);\r         }\r      for (; i<8; i++)\r               key[i]=0;\r\r     des_set_key((des_cblock *)(key),ks);\r   fcrypt_body(&(out[0]),&(out[1]),ks,Eswap0,Eswap1);\r\r    ll=out[0]; l2c(ll,b);\r  ll=out[1]; l2c(ll,b);\r  y=0;\r   u=0x80;\r        bb[8]=0;\r       for (i=2; i<13; i++)\r           {\r              c=0;\r           for (j=0; j<6; j++)\r                    {\r                      c<<=1;\r                 if (bb[y] & u) c|=1;\r                   u>>=1;\r                 if (!u)\r                                {\r                              y++;\r                           u=0x80;\r                                }\r                      }\r              ret[i]=cov_2char[c];\r           }\r      ret[13]='\0';\r  return(ret);\r   }\r\rSTATIC int fcrypt_body(out0, out1, ks, Eswap0, Eswap1)\rDES_LONG *out0;\rDES_LONG *out1;\rdes_key_schedule ks;\rDES_LONG Eswap0;\rDES_LONG Eswap1;\r       {\r      register DES_LONG l,r,t,u;\r#ifdef DES_PTR\r      register unsigned char *des_SP=(unsigned char *)des_SPtrans;\r#endif\r    register DES_LONG *s;\r  register int j;\r        register DES_LONG E0,E1;\r\r      l=0;\r   r=0;\r\r  s=(DES_LONG *)ks;\r      E0=Eswap0;\r     E1=Eswap1;\r\r    for (j=0; j<25; j++)\r           {\r#ifdef DES_UNROLL\r            register int i;\r\r               for (i=0; i<32; i+=8)\r                  {\r                      D_ENCRYPT(l,r,i+0); /*  1 */\r                   D_ENCRYPT(r,l,i+2); /*  2 */\r                   D_ENCRYPT(l,r,i+4); /*  3 */\r                   D_ENCRYPT(r,l,i+6); /*  4 */\r                   }\r#else\r                D_ENCRYPT(l,r, 0); /*  1 */\r            D_ENCRYPT(r,l, 2); /*  2 */\r            D_ENCRYPT(l,r, 4); /*  3 */\r            D_ENCRYPT(r,l, 6); /*  4 */\r            D_ENCRYPT(l,r, 8); /*  5 */\r            D_ENCRYPT(r,l,10); /*  6 */\r            D_ENCRYPT(l,r,12); /*  7 */\r            D_ENCRYPT(r,l,14); /*  8 */\r            D_ENCRYPT(l,r,16); /*  9 */\r            D_ENCRYPT(r,l,18); /*  10 */\r           D_ENCRYPT(l,r,20); /*  11 */\r           D_ENCRYPT(r,l,22); /*  12 */\r           D_ENCRYPT(l,r,24); /*  13 */\r           D_ENCRYPT(r,l,26); /*  14 */\r           D_ENCRYPT(l,r,28); /*  15 */\r           D_ENCRYPT(r,l,30); /*  16 */\r#endif\r            t=l;\r           l=r;\r           r=t;\r           }\r      l=ROTATE(l,3)&0xffffffffL;\r     r=ROTATE(r,3)&0xffffffffL;\r\r    PERM_OP(l,r,t, 1,0x55555555L);\r PERM_OP(r,l,t, 8,0x00ff00ffL);\r PERM_OP(l,r,t, 2,0x33333333L);\r PERM_OP(r,l,t,16,0x0000ffffL);\r PERM_OP(l,r,t, 4,0x0f0f0f0fL);\r\r        *out0=r;\r       *out1=l;\r       return(0);\r     }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/key_par.c b/mac/libdes/src/key_par.c
new file mode 100755 (executable)
index 0000000..284f2d2
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#include "des_locl.h"\r\r/* MIT Link and source compatibility */\r\r#ifdef des_fixup_key_parity\r#undef des_fixup_key_parity\r#endif /* des_fixup_key_parity */\r\rvoid des_fixup_key_parity(des_cblock *key);\r\rvoid\rdes_fixup_key_parity(des_cblock *key)\r{\r  des_set_odd_parity(key);\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/makefile.bc b/mac/libdes/src/makefile.bc
new file mode 100755 (executable)
index 0000000..c1e78b3
--- /dev/null
@@ -0,0 +1 @@
+#\r# Origional BC Makefile from Teun <Teun.Nijssen@kub.nl>\r#\r#\rCC      = bcc\rTLIB    = tlib /0 /C\r# note: the -3 flag produces code for 386, 486, Pentium etc; omit it for 286s\rOPTIMIZE= -3 -O2\r#WINDOWS= -W\rCFLAGS  = -c -ml -d $(OPTIMIZE) $(WINDOWS) -DMSDOS\rLFLAGS  = -ml $(WINDOWS)\r\r.c.obj:\r     $(CC) $(CFLAGS) $*.c\r\r.obj.exe:\r        $(CC) $(LFLAGS) -e$*.exe $*.obj libdes.lib  \r\rall: $(LIB) destest.exe rpw.exe des.exe speed.exe\r\r# "make clean": use a directory containing only libdes .exe and .obj files...\rclean:\r  del *.exe\r      del *.obj\r      del libdes.lib\r del libdes.rsp\r\rOBJS=   cbc_cksm.obj cbc_enc.obj  ecb_enc.obj  pcbc_enc.obj \\r  qud_cksm.obj rand_key.obj set_key.obj  str2key.obj \\r   enc_read.obj enc_writ.obj fcrypt.obj   cfb_enc.obj \\r   ecb3_enc.obj ofb_enc.obj  cbc3_enc.obj read_pwd.obj\\r   cfb64enc.obj ofb64enc.obj ede_enc.obj  cfb64ede.obj\\r   ofb64ede.obj supp.obj\r\rLIB=    libdes.lib\r\r$(LIB): $(OBJS)\r     del $(LIB)\r     makersp "+%s &\n" &&|\r  $(OBJS)\r|       >libdes.rsp\r    $(TLIB) libdes.lib @libdes.rsp,nul\r     del libdes.rsp\r\rdestest.exe: destest.obj libdes.lib\rrpw.exe:     rpw.obj libdes.lib\rspeed.exe:   speed.obj libdes.lib\rdes.exe:     des.obj libdes.lib\r\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/md4.c b/mac/libdes/src/md4.c
new file mode 100755 (executable)
index 0000000..f095449
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include "config.h"\r\rRCSID("$Id: md4.c,v 1.2 2001/12/04 02:06:29 rjs3 Exp $");\r#endif\r\r#include <stdlib.h>\r#include <string.h>\r\r#include "md4.h"\r\r#ifndef min\r#define min(a,b) (((a)>(b))?(b):(a))\r#endif\r\r#define A m->counter[0]\r#define B m->counter[1]\r#define C m->counter[2]\r#define D m->counter[3]\r#define X data\r\rvoid\rmd4_init (struct md4 *m)\r{\r  m->offset = 0;\r  m->sz = 0;\r  D = 0x10325476;\r  C = 0x98badcfe;\r  B = 0xefcdab89;\r  A = 0x67452301;\r}\r\rstatic inline u_int32_t\rcshift (u_int32_t x, unsigned int n)\r{\r  return (x << n) | (x >> (32 - n));\r}\r\r#define F(x,y,z) ((x & y) | (~x & z))\r#define G(x,y,z) ((x & y) | (x & z) | (y & z))\r#define H(x,y,z) (x ^ y ^ z)\r\r#define DOIT(a,b,c,d,k,s,i,OP) \\ra = cshift(a + OP(b,c,d) + X[k] + i, s)\r\r#define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)\r#define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)\r#define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)\r\rstatic inline void\rcalc (struct md4 *m, u_int32_t *data)\r{\r  u_int32_t AA, BB, CC, DD;\r\r  AA = A;\r  BB = B;\r  CC = C;\r  DD = D;\r\r  /* Round 1 */\r\r  DO1(A,B,C,D,0,3,0);\r  DO1(D,A,B,C,1,7,0);\r  DO1(C,D,A,B,2,11,0);\r  DO1(B,C,D,A,3,19,0);\r\r  DO1(A,B,C,D,4,3,0);\r  DO1(D,A,B,C,5,7,0);\r  DO1(C,D,A,B,6,11,0);\r  DO1(B,C,D,A,7,19,0);\r\r  DO1(A,B,C,D,8,3,0);\r  DO1(D,A,B,C,9,7,0);\r  DO1(C,D,A,B,10,11,0);\r  DO1(B,C,D,A,11,19,0);\r\r  DO1(A,B,C,D,12,3,0);\r  DO1(D,A,B,C,13,7,0);\r  DO1(C,D,A,B,14,11,0);\r  DO1(B,C,D,A,15,19,0);\r\r  /* Round 2 */\r\r  DO2(A,B,C,D,0,3,0x5A827999);\r  DO2(D,A,B,C,4,5,0x5A827999);\r  DO2(C,D,A,B,8,9,0x5A827999);\r  DO2(B,C,D,A,12,13,0x5A827999);\r\r  DO2(A,B,C,D,1,3,0x5A827999);\r  DO2(D,A,B,C,5,5,0x5A827999);\r  DO2(C,D,A,B,9,9,0x5A827999);\r  DO2(B,C,D,A,13,13,0x5A827999);\r\r  DO2(A,B,C,D,2,3,0x5A827999);\r  DO2(D,A,B,C,6,5,0x5A827999);\r  DO2(C,D,A,B,10,9,0x5A827999);\r  DO2(B,C,D,A,14,13,0x5A827999);\r\r  DO2(A,B,C,D,3,3,0x5A827999);\r  DO2(D,A,B,C,7,5,0x5A827999);\r  DO2(C,D,A,B,11,9,0x5A827999);\r  DO2(B,C,D,A,15,13,0x5A827999);\r\r  /* Round 3 */\r\r  DO3(A,B,C,D,0,3,0x6ED9EBA1);\r  DO3(D,A,B,C,8,9,0x6ED9EBA1);\r  DO3(C,D,A,B,4,11,0x6ED9EBA1);\r  DO3(B,C,D,A,12,15,0x6ED9EBA1);\r\r  DO3(A,B,C,D,2,3,0x6ED9EBA1);\r  DO3(D,A,B,C,10,9,0x6ED9EBA1);\r  DO3(C,D,A,B,6,11,0x6ED9EBA1);\r  DO3(B,C,D,A,14,15,0x6ED9EBA1);\r\r  DO3(A,B,C,D,1,3,0x6ED9EBA1);\r  DO3(D,A,B,C,9,9,0x6ED9EBA1);\r  DO3(C,D,A,B,5,11,0x6ED9EBA1);\r  DO3(B,C,D,A,13,15,0x6ED9EBA1);\r\r  DO3(A,B,C,D,3,3,0x6ED9EBA1);\r  DO3(D,A,B,C,11,9,0x6ED9EBA1);\r  DO3(C,D,A,B,7,11,0x6ED9EBA1);\r  DO3(B,C,D,A,15,15,0x6ED9EBA1);\r\r  A += AA;\r  B += BB;\r  C += CC;\r  D += DD;\r}\r\r/*\r * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>\r */\r\rstatic inline u_int32_t\rswap_u_int32_t (u_int32_t t)\r{\r#if defined(WORDS_BIGENDIAN)\r#define ROL(x,n) ((x)<<(n))|((x)>>(32-(n)))\r  u_int32_t temp1, temp2;\r\r  temp1   = ROL(t,16);\r  temp2   = temp1 >> 8;\r  temp1  &= 0x00ff00ff;\r  temp2  &= 0x00ff00ff;\r  temp1 <<= 8;\r  return temp1 | temp2;\r#else\r  return t;\r#endif\r}\r\rstruct x32{\r  unsigned int a:32;\r  unsigned int b:32;\r};\r\rvoid\rmd4_update (struct md4 *m, const void *v, size_t len)\r{\r  const unsigned char *p = v;\r  m->sz += len;\r  while(len > 0){\r    size_t l = min(len, 64 - m->offset);\r    memcpy(m->save + m->offset, p, l);\r    m->offset += l;\r    p += l;\r    len -= l;\r    if(m->offset == 64){\r#if defined(WORDS_BIGENDIAN)\r      int i;\r      u_int32_t current[16];\r      struct x32 *u = (struct x32*)m->save;\r      for(i = 0; i < 8; i++){\r   current[2*i+0] = swap_u_int32_t(u[i].a);\r       current[2*i+1] = swap_u_int32_t(u[i].b);\r      }\r      calc(m, current);\r#else\r      calc(m, (u_int32_t*)m->save);\r#endif\r      m->offset = 0;\r    }\r  }\r}\r\rvoid\rmd4_finito (struct md4 *m, void *res)\r{\r  static unsigned char zeros[72];\r  u_int32_t len;\r  unsigned int dstart = (120 - m->offset - 1) % 64 + 1;\r\r  *zeros = 0x80;\r  memset (zeros + 1, 0, sizeof(zeros) - 1);\r  len = 8 * m->sz;\r  zeros[dstart+0] = (len >> 0) & 0xff;\r  zeros[dstart+1] = (len >> 8) & 0xff;\r  zeros[dstart+2] = (len >> 16) & 0xff;\r  zeros[dstart+3] = (len >> 24) & 0xff;\r  md4_update (m, zeros, dstart + 8);\r  {\r      int i;\r      unsigned char *r = (unsigned char *)res;\r\r      for (i = 0; i < 4; ++i) {\r         r[4*i]   = m->counter[i] & 0xFF;\r       r[4*i+1] = (m->counter[i] >> 8) & 0xFF;\r        r[4*i+2] = (m->counter[i] >> 16) & 0xFF;\r       r[4*i+3] = (m->counter[i] >> 24) & 0xFF;\r      }\r  }\r#if 0\r  {\r    int i;\r    u_int32_t *r = (u_int32_t *)res;\r\r    for (i = 0; i < 4; ++i)\r      r[i] = swap_u_int32_t (m->counter[i]);\r  }\r#endif\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/md4.h b/mac/libdes/src/md4.h
new file mode 100755 (executable)
index 0000000..faf6d46
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r/* $Id: md4.h,v 1.2 2001/12/04 02:06:30 rjs3 Exp $ */\r\r#include <stdlib.h>\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r#ifdef HAVE_SYS_BITYPES_H\r#include <sys/bitypes.h>\r#endif\r#ifdef KRB5\r#include <krb5-types.h>\r#elif defined(KRB4)\r#include <ktypes.h>\r#endif\r\rstruct md4 {\r  unsigned int offset;\r  unsigned int sz;\r  u_int32_t counter[4];\r  unsigned char save[64];\r};\r\rvoid md4_init (struct md4 *m);\rvoid md4_update (struct md4 *m, const void *p, size_t len);\rvoid md4_finito (struct md4 *m, void *res);\r
\ No newline at end of file
diff --git a/mac/libdes/src/md5.c b/mac/libdes/src/md5.c
new file mode 100755 (executable)
index 0000000..f8b1c28
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include "config.h"\r\rRCSID("$Id: md5.c,v 1.2 2001/12/04 02:06:30 rjs3 Exp $");\r#endif\r\r#include <stdlib.h>\r#include <string.h>\r\r#include "md5.h"\r\r#ifndef min\r#define min(a,b) (((a)>(b))?(b):(a))\r#endif\r\r#define A m->counter[0]\r#define B m->counter[1]\r#define C m->counter[2]\r#define D m->counter[3]\r#define X data\r\rvoid\rmd5_init (struct md5 *m)\r{\r  m->offset = 0;\r  m->sz = 0;\r  D = 0x10325476;\r  C = 0x98badcfe;\r  B = 0xefcdab89;\r  A = 0x67452301;\r}\r\rstatic inline u_int32_t\rcshift (u_int32_t x, unsigned int n)\r{\r  return (x << n) | (x >> (32 - n));\r}\r\r#define F(x,y,z) ((x & y) | (~x & z))\r#define G(x,y,z) ((x & z) | (y & ~z))\r#define H(x,y,z) (x ^ y ^ z)\r#define I(x,y,z) (y ^ (x | ~z))\r\r#define DOIT(a,b,c,d,k,s,i,OP) \\ra = b + cshift(a + OP(b,c,d) + X[k] + (i), s)\r\r#define DO1(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,F)\r#define DO2(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,G)\r#define DO3(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,H)\r#define DO4(a,b,c,d,k,s,i) DOIT(a,b,c,d,k,s,i,I)\r\rstatic inline void\rcalc (struct md5 *m, u_int32_t *data)\r{\r  u_int32_t AA, BB, CC, DD;\r\r  AA = A;\r  BB = B;\r  CC = C;\r  DD = D;\r\r  /* Round 1 */\r\r  DO1(A,B,C,D,0,7,0xd76aa478);\r  DO1(D,A,B,C,1,12,0xe8c7b756);\r  DO1(C,D,A,B,2,17,0x242070db);\r  DO1(B,C,D,A,3,22,0xc1bdceee);\r\r  DO1(A,B,C,D,4,7,0xf57c0faf);\r  DO1(D,A,B,C,5,12,0x4787c62a);\r  DO1(C,D,A,B,6,17,0xa8304613);\r  DO1(B,C,D,A,7,22,0xfd469501);\r\r  DO1(A,B,C,D,8,7,0x698098d8);\r  DO1(D,A,B,C,9,12,0x8b44f7af);\r  DO1(C,D,A,B,10,17,0xffff5bb1);\r  DO1(B,C,D,A,11,22,0x895cd7be);\r\r  DO1(A,B,C,D,12,7,0x6b901122);\r  DO1(D,A,B,C,13,12,0xfd987193);\r  DO1(C,D,A,B,14,17,0xa679438e);\r  DO1(B,C,D,A,15,22,0x49b40821);\r\r  /* Round 2 */\r\r  DO2(A,B,C,D,1,5,0xf61e2562);\r  DO2(D,A,B,C,6,9,0xc040b340);\r  DO2(C,D,A,B,11,14,0x265e5a51);\r  DO2(B,C,D,A,0,20,0xe9b6c7aa);\r\r  DO2(A,B,C,D,5,5,0xd62f105d);\r  DO2(D,A,B,C,10,9,0x2441453);\r  DO2(C,D,A,B,15,14,0xd8a1e681);\r  DO2(B,C,D,A,4,20,0xe7d3fbc8);\r\r  DO2(A,B,C,D,9,5,0x21e1cde6);\r  DO2(D,A,B,C,14,9,0xc33707d6);\r  DO2(C,D,A,B,3,14,0xf4d50d87);\r  DO2(B,C,D,A,8,20,0x455a14ed);\r\r  DO2(A,B,C,D,13,5,0xa9e3e905);\r  DO2(D,A,B,C,2,9,0xfcefa3f8);\r  DO2(C,D,A,B,7,14,0x676f02d9);\r  DO2(B,C,D,A,12,20,0x8d2a4c8a);\r\r  /* Round 3 */\r\r  DO3(A,B,C,D,5,4,0xfffa3942);\r  DO3(D,A,B,C,8,11,0x8771f681);\r  DO3(C,D,A,B,11,16,0x6d9d6122);\r  DO3(B,C,D,A,14,23,0xfde5380c);\r\r  DO3(A,B,C,D,1,4,0xa4beea44);\r  DO3(D,A,B,C,4,11,0x4bdecfa9);\r  DO3(C,D,A,B,7,16,0xf6bb4b60);\r  DO3(B,C,D,A,10,23,0xbebfbc70);\r\r  DO3(A,B,C,D,13,4,0x289b7ec6);\r  DO3(D,A,B,C,0,11,0xeaa127fa);\r  DO3(C,D,A,B,3,16,0xd4ef3085);\r  DO3(B,C,D,A,6,23,0x4881d05);\r\r  DO3(A,B,C,D,9,4,0xd9d4d039);\r  DO3(D,A,B,C,12,11,0xe6db99e5);\r  DO3(C,D,A,B,15,16,0x1fa27cf8);\r  DO3(B,C,D,A,2,23,0xc4ac5665);\r\r  /* Round 4 */\r\r  DO4(A,B,C,D,0,6,0xf4292244);\r  DO4(D,A,B,C,7,10,0x432aff97);\r  DO4(C,D,A,B,14,15,0xab9423a7);\r  DO4(B,C,D,A,5,21,0xfc93a039);\r\r  DO4(A,B,C,D,12,6,0x655b59c3);\r  DO4(D,A,B,C,3,10,0x8f0ccc92);\r  DO4(C,D,A,B,10,15,0xffeff47d);\r  DO4(B,C,D,A,1,21,0x85845dd1);\r\r  DO4(A,B,C,D,8,6,0x6fa87e4f);\r  DO4(D,A,B,C,15,10,0xfe2ce6e0);\r  DO4(C,D,A,B,6,15,0xa3014314);\r  DO4(B,C,D,A,13,21,0x4e0811a1);\r\r  DO4(A,B,C,D,4,6,0xf7537e82);\r  DO4(D,A,B,C,11,10,0xbd3af235);\r  DO4(C,D,A,B,2,15,0x2ad7d2bb);\r  DO4(B,C,D,A,9,21,0xeb86d391);\r\r  A += AA;\r  B += BB;\r  C += CC;\r  D += DD;\r}\r\r/*\r * From `Performance analysis of MD5' by Joseph D. Touch <touch@isi.edu>\r */\r\rstatic inline u_int32_t\rswap_u_int32_t (u_int32_t t)\r{\r#if defined(WORDS_BIGENDIAN)\r#define ROL(x,n) ((x)<<(n))|((x)>>(32-(n)))\r  u_int32_t temp1, temp2;\r\r  temp1   = ROL(t,16);\r  temp2   = temp1 >> 8;\r  temp1  &= 0x00ff00ff;\r  temp2  &= 0x00ff00ff;\r  temp1 <<= 8;\r  return temp1 | temp2;\r#else\r  return t;\r#endif\r}\r\rstruct x32{\r  unsigned int a:32;\r  unsigned int b:32;\r};\r\rvoid\rmd5_update (struct md5 *m, const void *v, size_t len)\r{\r  const unsigned char *p = v;\r  m->sz += len;\r  while(len > 0){\r    size_t l = min(len, 64 - m->offset);\r    memcpy(m->save + m->offset, p, l);\r    m->offset += l;\r    p += l;\r    len -= l;\r    if(m->offset == 64){\r#if defined(WORDS_BIGENDIAN)\r      int i;\r      u_int32_t current[16];\r      struct x32 *u = (struct x32*)m->save;\r      for(i = 0; i < 8; i++){\r    current[2*i+0] = swap_u_int32_t(u[i].a);\r       current[2*i+1] = swap_u_int32_t(u[i].b);\r      }\r      calc(m, current);\r#else\r      calc(m, (u_int32_t*)m->save);\r#endif\r      m->offset = 0;\r    }\r  }\r}\r\rvoid\rmd5_finito (struct md5 *m, void *res)\r{\r  static unsigned char zeros[72];\r  u_int32_t len;\r  unsigned int dstart = (120 - m->offset - 1) % 64 + 1;\r\r  *zeros = 0x80;\r  memset (zeros + 1, 0, sizeof(zeros) - 1);\r  len = 8 * m->sz;\r  zeros[dstart+0] = (len >> 0) & 0xff;\r  zeros[dstart+1] = (len >> 8) & 0xff;\r  zeros[dstart+2] = (len >> 16) & 0xff;\r  zeros[dstart+3] = (len >> 24) & 0xff;\r  md5_update (m, zeros, dstart + 8);\r  {\r      int i;\r      unsigned char *r = (unsigned char *)res;\r\r      for (i = 0; i < 4; ++i) {\r         r[4*i]   = m->counter[i] & 0xFF;\r       r[4*i+1] = (m->counter[i] >> 8) & 0xFF;\r        r[4*i+2] = (m->counter[i] >> 16) & 0xFF;\r       r[4*i+3] = (m->counter[i] >> 24) & 0xFF;\r      }\r  }\r#if 0\r  {\r    int i;\r    u_int32_t *r = (u_int32_t *)res;\r\r    for (i = 0; i < 4; ++i)\r      r[i] = swap_u_int32_t (m->counter[i]);\r  }\r#endif\r}\r\r/*\r * This is only for linkage compatibility!\r */\r#undef MD5Init\r#undef MD5Update\r#undef MD5Final\r\rvoid\rMD5Init (MD5_CTX *mdContext)\r{\r  md5_init(&mdContext->m.d5);\r}\r\rvoid\rMD5Update (MD5_CTX *mdContext, const unsigned char *inBuf, unsigned int inLen)\r{\r  md5_update(&mdContext->m.d5, (unsigned char *)inBuf, inLen);\r}\r\rvoid\rMD5Final (unsigned char digest[16], MD5_CTX *mdContext)\r{\r  md5_finito(&mdContext->m.d5, digest);\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/md5.h b/mac/libdes/src/md5.h
new file mode 100755 (executable)
index 0000000..e38a842
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r/* $Id: md5.h,v 1.2 2001/12/04 02:06:30 rjs3 Exp $ */\r\r#include <stdlib.h>\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r#ifdef HAVE_SYS_BITYPES_H\r#include <sys/bitypes.h>\r#endif\r#ifdef KRB5\r#include <krb5-types.h>\r#elif defined(KRB4)\r#include <ktypes.h>\r#endif\r\rstruct md5 {\r  unsigned int offset;\r  unsigned int sz;\r  u_int32_t counter[4];\r  unsigned char save[64];\r};\r\rvoid md5_init (struct md5 *m);\rvoid md5_update (struct md5 *m, const void *p, size_t len);\rvoid md5_finito (struct md5 *m, void *res); /* u_int32_t res[4] */\r\r/*\r * Functions for compatibility that have never been tested.\r */\rtypedef struct {\r  u_int32_t i[2];            /* number of _bits_ handled mod 2^64 */\r  u_int32_t buf[4];             /* scratch buffer */\r  unsigned char in[64];            /* input buffer */\r} MD5_CTX_PREAMBLE;\r\rtypedef struct {\r  union {\r    MD5_CTX_PREAMBLE preamble_;\r    struct md5 d5;\r  } m;\r} MD5_CTX;\r\rvoid MD5Init (MD5_CTX *mdContext);\rvoid MD5Update (MD5_CTX *mdContext,\r                const unsigned char *inBuf,\r            unsigned int inLen);\rvoid MD5Final (unsigned char digest[16], MD5_CTX *mdContext);\r\r#ifndef NO_MD5_MACROS\r#define MD5Init(mdContext) md5_init(&(mdContext)->m.d5)\r#define MD5Update(mdCtx, inBuf, inLen) md5_update(&(mdCtx)->m.d5, inBuf, inLen)\r#define MD5Final(digest, mdCtx) md5_finito(&(mdCtx)->m.d5, (digest))\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/mdtest.c b/mac/libdes/src/mdtest.c
new file mode 100755 (executable)
index 0000000..babd72d
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\rRCSID("$Id: mdtest.c,v 1.2 2001/12/04 02:06:30 rjs3 Exp $");\r#endif\r\r#include <stdio.h>\r#include <string.h>\r#include <md4.h>\r#include <md5.h>\r#include <sha.h>\r\rstatic\rint\rmd4_tests (void)\r{\r  struct test {\r    char *str;\r    unsigned char hash[16];\r  } tests[] = {\r    {"", \r     {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, \r      0xd7, 0xe0, 0xc0, 0x89, 0xc0}},\r    {"a",\r     {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05,\r      0xfb, 0xdb, 0xd6, 0xfb, 0x24}},\r    {"abc",\r     {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d}},\r    {"message digest",\r     {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b}},\r    {"abcdefghijklmnopqrstuvwxyz", {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9, }},\r    {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",\r     {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4}},\r    {"12345678901234567890123456789012345678901234567890123456789012345678901234567890",\r     {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36, }},\r    {NULL, { 0x0 }}};\r  struct test *t;\r\r  printf ("md4... ");\r  for (t = tests; t->str; ++t) {\r    struct md4 md4;\r    char res[16];\r    int i;\r\r    md4_init (&md4);\r    md4_update (&md4, (unsigned char *)t->str, strlen(t->str));\r    md4_finito (&md4, res);\r    if (memcmp (res, t->hash, 16) != 0) {\r      printf ("MD4(\"%s\") failed\n", t->str);\r      printf("should be: ");\r      for(i = 0; i < 16; ++i)\r       printf("%02x ", t->hash[i]);\r      printf("\nresult was: ");\r      for(i = 0; i < 16; ++i)\r     printf("%02x ", res[i]);\r      printf("\n");\r      return 1;\r    }\r  }\r  printf ("success\n");\r  return 0;\r}\r\rstatic\rint\rmd5_tests (void)\r{\r  struct test {\r    char *str;\r    unsigned char hash[16];\r  } tests[] = {\r    {"", {0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e}}, \r    {"a", {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61}}, \r    {"abc", {0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72}}, \r    {"message digest", {0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0}}, \r    {"abcdefghijklmnopqrstuvwxyz", {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b}}, \r    {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", {0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f}}, \r    {"12345678901234567890123456789012345678901234567890123456789012345678901234567890", {0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a}}, \r    {NULL, { 0x0 }}};\r  struct test *t;\r\r  printf ("md5... ");\r  for (t = tests; t->str; ++t) {\r    struct md5 md5;\r    char res[16];\r\r    md5_init (&md5);\r    md5_update (&md5, (unsigned char *)t->str, strlen(t->str));\r    md5_finito (&md5, res);\r    if (memcmp (res, t->hash, 16) != 0) {\r      int i;\r\r      printf ("MD5(\"%s\") failed\n", t->str);\r      printf("should be: ");\r      for(i = 0; i < 16; ++i)\r          printf("%02x ", t->hash[i]);\r      printf("\nresult was: ");\r      for(i = 0; i < 16; ++i)\r     printf("%02x ", res[i]);\r      printf("\n");\r      return 1;\r    }\r  }\r  printf ("success\n");\r  return 0;\r}\r\rstatic\rint\rsha_tests (void)\r{\r  struct test {\r    char *str;\r    unsigned char hash[20];\r  } tests[] = {\r    {"abc", {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A,\r       0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C,\r        0x9C, 0xD0, 0xD8, 0x9D}},\r    {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r     {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,\r      0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,\r      0xE5, 0x46, 0x70, 0xF1}},\r    {NULL, { 0x0 }}};\r  struct test *t;\r\r  printf ("sha... ");\r  for (t = tests; t->str; ++t) {\r    struct sha sha;\r    char res[20];\r\r    sha_init (&sha);\r    sha_update (&sha, (unsigned char *)t->str, strlen(t->str));\r    sha_finito (&sha, res);\r    if (memcmp (res, t->hash, 20) != 0) {\r      int i;\r\r      printf ("SHA(\"%s\") failed\n", t->str);\r      printf("should be: ");\r      for(i = 0; i < 20; ++i)\r    printf("%02x ", t->hash[i]);\r      printf("\nresult was: ");\r      for(i = 0; i < 20; ++i)\r     printf("%02x ", res[i]);\r      printf("\n");\r      return 1;\r    }\r  }\r  printf ("success\n");\r  return 0;\r}\r\rint\rmain (void)\r{\r  return md4_tests() + md5_tests() + sha_tests();\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/ncbc_enc.c b/mac/libdes/src/ncbc_enc.c
new file mode 100755 (executable)
index 0000000..69cca82
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ncbc_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_ncbc_encrypt(input, output, length, schedule, ivec, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint encrypt;\r     {\r      register DES_LONG tin0,tin1;\r   register DES_LONG tout0,tout1,xor0,xor1;\r       register unsigned char *in,*out;\r       register long l=length;\r        DES_LONG tin[2];\r       unsigned char *iv;\r\r    in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     if (encrypt)\r           {\r              c2l(iv,tout0);\r         c2l(iv,tout1);\r         for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r                  tin0^=tout0; tin[0]=tin0;\r                      tin1^=tout1; tin[1]=tin1;\r                      des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]; l2c(tout0,out);\r                  tout1=tin[1]; l2c(tout1,out);\r                  }\r              if (l != -8)\r                   {\r                      c2ln(in,tin0,tin1,l+8);\r                        tin0^=tout0; tin[0]=tin0;\r                      tin1^=tout1; tin[1]=tin1;\r                      des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]; l2c(tout0,out);\r                  tout1=tin[1]; l2c(tout1,out);\r                  }\r              iv=(unsigned char *)ivec;\r              l2c(tout0,iv);\r         l2c(tout1,iv);\r         }\r      else\r           {\r              c2l(iv,xor0);\r          c2l(iv,xor1);\r          for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0); tin[0]=tin0;\r                     c2l(in,tin1); tin[1]=tin1;\r                     des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0;\r                     tout1=tin[1]^xor1;\r                     l2c(tout0,out);\r                        l2c(tout1,out);\r                        xor0=tin0;\r                     xor1=tin1;\r                     }\r              if (l != -8)\r                   {\r                      c2l(in,tin0); tin[0]=tin0;\r                     c2l(in,tin1); tin[1]=tin1;\r                     des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0;\r                     tout1=tin[1]^xor1;\r                     l2cn(tout0,tout1,out,l+8);\r                     xor0=tin0;\r                     xor1=tin1;\r                     }\r              iv=(unsigned char *)ivec;\r              l2c(xor0,iv);\r          l2c(xor1,iv);\r          }\r      tin0=tin1=tout0=tout1=xor0=xor1=0;\r     tin[0]=tin[1]=0;\r       }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/ofb64ede.c b/mac/libdes/src/ofb64ede.c
new file mode 100755 (executable)
index 0000000..cfd75ef
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ofb64ede.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output encrypted as though 64bit ofb mode is being\r * used.  The extra state information to record how much of the\r * 64bit block we have used is contained in *num;\r */\rvoid des_ede3_ofb64_encrypt(in, out, length, k1,k2,k3, ivec, num)\rregister unsigned char *in;\rregister unsigned char *out;\rlong length;\rdes_key_schedule k1,k2,k3;\rdes_cblock (*ivec);\rint *num;\r    {\r      register DES_LONG v0,v1;\r       register int n= *num;\r  register long l=length;\r        des_cblock d;\r  register char *dp;\r     DES_LONG ti[2];\r        unsigned char *iv;\r     int save=0;\r\r   iv=(unsigned char *)ivec;\r      c2l(iv,v0);\r    c2l(iv,v1);\r    ti[0]=v0;\r      ti[1]=v1;\r      dp=(char *)d;\r  l2c(v0,dp);\r    l2c(v1,dp);\r    while (l--)\r            {\r              if (n == 0)\r                    {\r                      ti[0]=v0;\r                      ti[1]=v1;\r                      des_encrypt3((DES_LONG *)ti,k1,k2,k3);\r                 v0=ti[0];\r                      v1=ti[1];\r\r                     dp=(char *)d;\r                  l2c(v0,dp);\r                    l2c(v1,dp);\r                    save++;\r                        }\r              *(out++)= *(in++)^d[n];\r                n=(n+1)&0x07;\r          }\r      if (save)\r              {\r/*            v0=ti[0];\r              v1=ti[1];*/\r            iv=(unsigned char *)ivec;\r              l2c(v0,iv);\r            l2c(v1,iv);\r            }\r      v0=v1=ti[0]=ti[1]=0;\r   *num=n;\r        }\r\r#ifdef undef /* MACRO */\rvoid des_ede2_ofb64_encrypt(in, out, length, k1,k2, ivec, num)\rregister unsigned char *in;\rregister unsigned char *out;\rlong length;\rdes_key_schedule k1,k2;\rdes_cblock (*ivec);\rint *num;\r {\r      des_ede3_ofb64_encrypt(in, out, length, k1,k2,k1, ivec, num);\r  }\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/ofb64enc.c b/mac/libdes/src/ofb64enc.c
new file mode 100755 (executable)
index 0000000..3ac1220
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ofb64enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output encrypted as though 64bit ofb mode is being\r * used.  The extra state information to record how much of the\r * 64bit block we have used is contained in *num;\r */\rvoid des_ofb64_encrypt(in, out, length, schedule, ivec, num)\rregister unsigned char *in;\rregister unsigned char *out;\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint *num;\r {\r      register DES_LONG v0,v1,t;\r     register int n= *num;\r  register long l=length;\r        des_cblock d;\r  register char *dp;\r     DES_LONG ti[2];\r        unsigned char *iv;\r     int save=0;\r\r   iv=(unsigned char *)ivec;\r      c2l(iv,v0);\r    c2l(iv,v1);\r    ti[0]=v0;\r      ti[1]=v1;\r      dp=(char *)d;\r  l2c(v0,dp);\r    l2c(v1,dp);\r    while (l--)\r            {\r              if (n == 0)\r                    {\r                      des_encrypt((DES_LONG *)ti,schedule,DES_ENCRYPT);\r                      dp=(char *)d;\r                  t=ti[0]; l2c(t,dp);\r                    t=ti[1]; l2c(t,dp);\r                    save++;\r                        }\r              *(out++)= *(in++)^d[n];\r                n=(n+1)&0x07;\r          }\r      if (save)\r              {\r              v0=ti[0];\r              v1=ti[1];\r              iv=(unsigned char *)ivec;\r              l2c(v0,iv);\r            l2c(v1,iv);\r            }\r      t=v0=v1=ti[0]=ti[1]=0;\r *num=n;\r        }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/ofb_enc.c b/mac/libdes/src/ofb_enc.c
new file mode 100755 (executable)
index 0000000..ea71990
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/ofb_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* The input and output are loaded in multiples of 8 bits.\r * What this means is that if you hame numbits=12 and length=2\r * the first 12 bits will be retrieved from the first byte and half\r * the second.  The second 12 bits will come from the 3rd and half the 4th\r * byte.\r */\rvoid des_ofb_encrypt(in, out, numbits, length, schedule, ivec)\runsigned char *in;\runsigned char *out;\rint numbits;\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\r   {\r      register DES_LONG d0,d1,v0,v1,n=(numbits+7)/8;\r register DES_LONG mask0,mask1;\r register long l=length;\r        register int num=numbits;\r      DES_LONG ti[2];\r        unsigned char *iv;\r\r    if (num > 64) return;\r  if (num > 32)\r          {\r              mask0=0xffffffffL;\r             if (num >= 64)\r                 mask1=mask0;\r           else\r                   mask1=(1L<<(num-32))-1;\r                }\r      else\r           {\r              if (num == 32)\r                 mask0=0xffffffffL;\r             else\r                   mask0=(1L<<num)-1;\r             mask1=0x00000000;\r              }\r\r     iv=(unsigned char *)ivec;\r      c2l(iv,v0);\r    c2l(iv,v1);\r    ti[0]=v0;\r      ti[1]=v1;\r      while (l-- > 0)\r                {\r              des_encrypt((DES_LONG *)ti,schedule,DES_ENCRYPT);\r              c2ln(in,d0,d1,n);\r              in+=n;\r         d0=(d0^ti[0])&mask0;\r           d1=(d1^ti[1])&mask1;\r           l2cn(d0,d1,out,n);\r             out+=n;\r                }\r      v0=ti[0];\r      v1=ti[1];\r      iv=(unsigned char *)ivec;\r      l2c(v0,iv);\r    l2c(v1,iv);\r    v0=v1=d0=d1=ti[0]=ti[1]=0;\r     }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/passwd_dialog.aps b/mac/libdes/src/passwd_dialog.aps
new file mode 100755 (executable)
index 0000000..e8cc0a4
Binary files /dev/null and b/mac/libdes/src/passwd_dialog.aps differ
diff --git a/mac/libdes/src/passwd_dialog.clw b/mac/libdes/src/passwd_dialog.clw
new file mode 100755 (executable)
index 0000000..04cc504
--- /dev/null
@@ -0,0 +1 @@
+; CLW file contains information for the MFC ClassWizard\r\r[General Info]\rVersion=1\rLastClass=\rLastTemplate=CDialog\rNewFileInclude1=#include "stdafx.h"\rNewFileInclude2=#include "passwd_dialog.h"\rLastPage=0\r\rClassCount=0\r\rResourceCount=2\rResource1=IDD_DIALOG1\rResource2=IDD_PASSWD_DIALOG\r\r[DLG:IDD_DIALOG1]\rType=1\rControlCount=6\rControl1=IDOK,button,1342242817\rControl2=IDCANCEL,button,1342242816\rControl3=IDC_STATIC,static,1342308352\rControl4=IDC_STATIC,static,1342308352\rControl5=IDC_EDIT1,edit,1350631552\rControl6=IDC_EDIT2,edit,1350631584\r\r[DLG:IDD_PASSWD_DIALOG]\rType=1\rControlCount=4\rControl1=IDC_PASSWD_EDIT,edit,1350631456\rControl2=IDOK,button,1342242817\rControl3=IDCANCEL,button,1342242816\rControl4=IDC_STATIC,static,1342177280\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/passwd_dialog.rc b/mac/libdes/src/passwd_dialog.rc
new file mode 100755 (executable)
index 0000000..555e23d
--- /dev/null
@@ -0,0 +1 @@
+//Microsoft Developer Studio generated resource script.\r//\r#include "resource.h"\r\r#define APSTUDIO_READONLY_SYMBOLS\r/////////////////////////////////////////////////////////////////////////////\r//\r// Generated from the TEXTINCLUDE 2 resource.\r//\r#include "afxres.h"\r\r/////////////////////////////////////////////////////////////////////////////\r#undef APSTUDIO_READONLY_SYMBOLS\r\r/////////////////////////////////////////////////////////////////////////////\r// Swedish resources\r\r#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_SVE)\r#ifdef _WIN32\rLANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT\r#pragma code_page(1252)\r#endif //_WIN32\r\r/////////////////////////////////////////////////////////////////////////////\r//\r// Dialog\r//\r\rIDD_PASSWD_DIALOG DIALOG DISCARDABLE  0, 0, 186, 66\rSTYLE DS_ABSALIGN | DS_MODALFRAME | DS_SETFOREGROUND | DS_CENTER | WS_POPUP | \r    WS_VISIBLE | WS_CAPTION\rCAPTION "Password query"\rFONT 8, "MS Sans Serif"\rBEGIN\r    EDITTEXT        IDC_PASSWD_EDIT,30,22,125,14,ES_PASSWORD\r    DEFPUSHBUTTON   "OK",IDOK,30,45,50,14\r    PUSHBUTTON      "Cancel",IDCANCEL,105,45,50,14\r    LTEXT           "Please insert password:",IDC_STATIC,30,13,87,8,NOT \r                    WS_GROUP\rEND\r\r\r/////////////////////////////////////////////////////////////////////////////\r//\r// DESIGNINFO\r//\r\r#ifdef APSTUDIO_INVOKED\rGUIDELINES DESIGNINFO DISCARDABLE \rBEGIN\r    IDD_PASSWD_DIALOG, DIALOG\r    BEGIN\r        LEFTMARGIN, 7\r        RIGHTMARGIN, 179\r        TOPMARGIN, 7\r        BOTTOMMARGIN, 59\r    END\rEND\r#endif    // APSTUDIO_INVOKED\r\r\r#ifdef APSTUDIO_INVOKED\r/////////////////////////////////////////////////////////////////////////////\r//\r// TEXTINCLUDE\r//\r\r1 TEXTINCLUDE DISCARDABLE \rBEGIN\r    "resource.h\0"\rEND\r\r2 TEXTINCLUDE DISCARDABLE \rBEGIN\r    "#include ""afxres.h""\r\n"\r    "\0"\rEND\r\r3 TEXTINCLUDE DISCARDABLE \rBEGIN\r    "\r\n"\r    "\0"\rEND\r\r#endif    // APSTUDIO_INVOKED\r\r\r#ifndef _MAC\r/////////////////////////////////////////////////////////////////////////////\r//\r// Version\r//\r\rVS_VERSION_INFO VERSIONINFO\r FILEVERSION 1,0,0,1\r PRODUCTVERSION 1,0,0,1\r FILEFLAGSMASK 0x3fL\r#ifdef _DEBUG\r FILEFLAGS 0x1L\r#else\r FILEFLAGS 0x0L\r#endif\r FILEOS 0x40004L\r FILETYPE 0x2L\r FILESUBTYPE 0x0L\rBEGIN\r    BLOCK "StringFileInfo"\r    BEGIN\r        BLOCK "040904b0"\r        BEGIN\r            VALUE "CompanyName", "Royal Institute of Technology (KTH)\0"\r            VALUE "FileDescription", "des\0"\r            VALUE "FileVersion", "4, 0, 9, 9\0"\r            VALUE "InternalName", "des\0"\r            VALUE "LegalCopyright", "Copyright Â© 1996 - 1998  Royal Institute of Technology (KTH)\0"\r            VALUE "OriginalFilename", "des.dll\0"\r            VALUE "ProductName", "KTH Kerberos\0"\r            VALUE "ProductVersion", "4,0,9,9\0"\r        END\r    END\r    BLOCK "VarFileInfo"\r    BEGIN\r        VALUE "Translation", 0x409, 1200\r    END\rEND\r\r#endif    // !_MAC\r\r#endif    // Swedish resources\r/////////////////////////////////////////////////////////////////////////////\r\r\r\r#ifndef APSTUDIO_INVOKED\r/////////////////////////////////////////////////////////////////////////////\r//\r// Generated from the TEXTINCLUDE 3 resource.\r//\r\r\r/////////////////////////////////////////////////////////////////////////////\r#endif    // not APSTUDIO_INVOKED\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/passwd_dialog.res b/mac/libdes/src/passwd_dialog.res
new file mode 100755 (executable)
index 0000000..162f20a
Binary files /dev/null and b/mac/libdes/src/passwd_dialog.res differ
diff --git a/mac/libdes/src/passwd_dlg.c b/mac/libdes/src/passwd_dlg.c
new file mode 100755 (executable)
index 0000000..2b70bca
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r/* passwd_dlg.c - Dialog boxes for Windows95/NT\r * Author:    J\9argen Karlsson - d93-jka@nada.kth.se\r * Date:  June 1996\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\rRCSID("$Id: passwd_dlg.c,v 1.2 2001/12/04 02:06:30 rjs3 Exp $");\r#endif\r\r#ifdef WIN32   /* Visual C++ 4.0 (Windows95/NT) */\r#include <Windows.h>\r#include "passwd_dlg.h"\r#include "Resource.h"\r#define passwdBufSZ 64\r\rchar passwd[passwdBufSZ];\r\rBOOL CALLBACK\rpwd_dialog_proc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r{\r    switch(uMsg)\r    {\r    case WM_COMMAND: \r  switch(wParam)\r {\r      case IDOK:\r         if(!GetDlgItemText(hwndDlg,IDC_PASSWD_EDIT, passwd, passwdBufSZ))\r          EndDialog(hwndDlg, IDCANCEL);\r  case IDCANCEL:\r     EndDialog(hwndDlg, wParam);\r            return TRUE;\r       }\r    }\r    return FALSE;\r}\r\r\r/* return 0 if ok, 1 otherwise */\rint\rpwd_dialog(char *buf, int size)\r{\r    int i;\r    HWND wnd = GetActiveWindow();\r    HANDLE hInst = GetModuleHandle("des");\r    switch(DialogBox(hInst,MAKEINTRESOURCE(IDD_PASSWD_DIALOG),wnd,pwd_dialog_proc))\r    {\r    case IDOK:\r strcpy_truncate(buf, passwd, size);\r    memset (passwd, 0, sizeof(passwd));\r    return 0;\r    case IDCANCEL:\r    default:\r      memset (passwd, 0, sizeof(passwd));\r    return 1;\r    }\r}\r\r#endif /* WIN32 */\r
\ No newline at end of file
diff --git a/mac/libdes/src/passwd_dlg.h b/mac/libdes/src/passwd_dlg.h
new file mode 100755 (executable)
index 0000000..93d4385
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r/* passwd_dlg.h - Dialog boxes for Windows95/NT\r * Author:  J\9argen Karlsson - d93-jka@nada.kth.se\r * Date:  June 1996\r */\r\r/* $Id: passwd_dlg.h,v 1.2 2001/12/04 02:06:30 rjs3 Exp $ */\r\r#ifndef PASSWD_DLG_H\r#define PASSWD_DLG_H\r\rint pwd_dialog(char *buf, int size);\r\r\r#endif /* PASSWD_DLG_H */\r
\ No newline at end of file
diff --git a/mac/libdes/src/pcbc_enc.c b/mac/libdes/src/pcbc_enc.c
new file mode 100755 (executable)
index 0000000..2c1be89
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/pcbc_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rvoid des_pcbc_encrypt(input, output, length, schedule, ivec, encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rint encrypt;\r     {\r      register DES_LONG sin0,sin1,xor0,xor1,tout0,tout1;\r     DES_LONG tin[2];\r       unsigned char *in,*out,*iv;\r\r   in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     if (encrypt)\r           {\r              c2l(iv,xor0);\r          c2l(iv,xor1);\r          for (; length>0; length-=8)\r                    {\r                      if (length >= 8)\r                               {\r                              c2l(in,sin0);\r                          c2l(in,sin1);\r                          }\r                      else\r                           c2ln(in,sin0,sin1,length);\r                     tin[0]=sin0^xor0;\r                      tin[1]=sin1^xor1;\r                      des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0];\r                  tout1=tin[1];\r                  xor0=sin0^tout0;\r                       xor1=sin1^tout1;\r                       l2c(tout0,out);\r                        l2c(tout1,out);\r                        }\r              }\r      else\r           {\r              c2l(iv,xor0); c2l(iv,xor1);\r            for (; length>0; length-=8)\r                    {\r                      c2l(in,sin0);\r                  c2l(in,sin1);\r                  tin[0]=sin0;\r                   tin[1]=sin1;\r                   des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0;\r                     tout1=tin[1]^xor1;\r                     if (length >= 8)\r                               {\r                              l2c(tout0,out);\r                                l2c(tout1,out);\r                                }\r                      else\r                           l2cn(tout0,tout1,out,length);\r                  xor0=tout0^sin0;\r                       xor1=tout1^sin1;\r                       }\r              }\r      tin[0]=tin[1]=0;\r       sin0=sin1=xor0=xor1=tout0=tout1=0;\r     }\r
\ No newline at end of file
diff --git a/mac/libdes/src/podd.h b/mac/libdes/src/podd.h
new file mode 100755 (executable)
index 0000000..18e27ac
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/podd.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\rstatic const unsigned char odd_parity[256]={\r  1,  1,  2,  2,  4,  4,  7,  7,  8,  8, 11, 11, 13, 13, 14, 14,\r 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,\r 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,\r 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,\r 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,\r 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,\r 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,\r112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,\r128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,\r145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,\r161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,\r176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,\r193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,\r208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,\r224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,\r241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};\r
\ No newline at end of file
diff --git a/mac/libdes/src/qud_cksm.c b/mac/libdes/src/qud_cksm.c
new file mode 100755 (executable)
index 0000000..e3b23f2
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/qud_cksm.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* From "Message Authentication"  R.R. Jueneman, S.M. Matyas, C.H. Meyer\r * IEEE Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40\r * This module in only based on the code in this paper and is\r * almost definitely not the same as the MIT implementation.\r */\r#include "des_locl.h"\r\r/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */\r#define Q_B0(a)    (((DES_LONG)(a)))\r#define Q_B1(a)       (((DES_LONG)(a))<<8)\r#define Q_B2(a)    (((DES_LONG)(a))<<16)\r#define Q_B3(a)   (((DES_LONG)(a))<<24)\r\r/* used to scramble things a bit */\r/* Got the value MIT uses via brute force :-) 2/10/90 eay */\r#define NOISE   ((DES_LONG)83653421L)\r\rDES_LONG des_quad_cksum(input, output, length, out_count, seed)\r     des_cblock (*input);\r     des_cblock (*output);\r     long length;\r     int out_count;\r     des_cblock (*seed);\r{\r    DES_LONG z0,z1,t0,t1;\r    int i;\r    long l;\r#ifdef _CRAY\r    typedef struct {\r        unsigned int a:32;\r     unsigned int b:32;\r    } XXX;\r#else\r    typedef DES_LONG XXX;\r#endif\r    unsigned char *cp;\r    XXX *lp;\r\r    if (out_count < 1) out_count=1;\r    lp=(XXX*)output;\r\r    z0=Q_B0((*seed)[0])|Q_B1((*seed)[1])|Q_B2((*seed)[2])|Q_B3((*seed)[3]);\r    z1=Q_B0((*seed)[4])|Q_B1((*seed)[5])|Q_B2((*seed)[6])|Q_B3((*seed)[7]);\r\r    for (i=0; ((i<4)&&(i<out_count)); i++)\r        {\r          cp=(unsigned char *)input;\r     l=length;\r      while (l > 0)\r              {\r                  if (l > 1)\r                 {\r                          t0= (DES_LONG)(*(cp++));\r                       t0|=(DES_LONG)Q_B1(*(cp++));\r                           l--;\r                       }\r                  else\r                       t0= (DES_LONG)(*(cp++));\r                   l--;\r                   /* add */\r              t0+=z0;\r                t0&=0xffffffffL;\r               t1=z1;\r                 /* square, well sort of square */\r              z0=((((t0*t0)&0xffffffffL)+((t1*t1)&0xffffffffL))\r                  &0xffffffffL)%0x7fffffffL; \r                z1=((t0*((t1+NOISE)&0xffffffffL))&0xffffffffL)%0x7fffffffL;\r                }\r          if (lp != NULL) \r           {\r                  /* The MIT library assumes that the checksum is\r                 * composed of 2*out_count 32 bit ints */\r#ifdef _CRAY\r                 lp->a = z0;\r                    lp->b = z1;\r                    lp++;\r#else\r                    *lp++ = (XXX)z0;\r               *lp++ = (XXX)z1;\r#endif\r            }\r      }\r    return(z0);\r}\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/rand_key.c b/mac/libdes/src/rand_key.c
new file mode 100755 (executable)
index 0000000..6b9728d
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/rand_key.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r#include <time.h>\r\rstatic int seed=0;\rstatic des_cblock init;\r\rvoid des_random_seed(key)\rdes_cblock key;\r       {\r      memcpy(init,key,sizeof(des_cblock));\r   seed=1;\r        }\r\r/* Old source */\r/*\rvoid des_random_key(ret)\runsigned char *ret;\r    {\r      des_key_schedule ks;\r   static DES_LONG c=0;\r   static unsigned short pid=0;\r   static des_cblock data={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};\r      des_cblock key;\r        unsigned char *p;\r      DES_LONG t;\r    int i;\r\r#if defined(MSDOS) || defined(WIN32)\r   pid=1;\r#else\r   if (!pid) pid=getpid();\r#endif\r p=key;\r if (seed)\r              {\r              for (i=0; i<8; i++)\r                    {\r                      data[i] ^= init[i];\r                    init[i]=0;\r                     }\r              seed=0;\r                }\r      t=(DES_LONG)time(NULL);\r        l2c(t,p);\r      t=(DES_LONG)((pid)|((c++)<<16));\r       l2c(t,p);\r\r     des_set_odd_parity((des_cblock *)data);\r        des_set_key((des_cblock *)data,ks);\r    des_cbc_cksum((des_cblock *)key,(des_cblock *)key,\r             (long)sizeof(key),ks,(des_cblock *)data);\r\r     des_set_odd_parity((des_cblock *)key);\r des_set_key((des_cblock *)key,ks);\r     des_cbc_cksum((des_cblock *)key,(des_cblock *)data,\r            (long)sizeof(key),ks,(des_cblock *)key);\r\r      memcpy(ret,data,sizeof(key));\r  memset(key,0,sizeof(key));\r     memset(ks,0,sizeof(ks));\r       t=0;\r   }\r*/\r
\ No newline at end of file
diff --git a/mac/libdes/src/read_pwd.c b/mac/libdes/src/read_pwd.c
new file mode 100755 (executable)
index 0000000..d0dbcb2
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/read_pwd.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#ifdef WIN16TTY\r#undef WIN16\r#undef _WINDOWS\r#include <graph.h>\r#endif\r\r/* 06-Apr-92 Luke Brennan    Support for VMS */\r#include "des_locl.h"\r#include <signal.h>\r#include <string.h>\r#include <setjmp.h>\r#include <errno.h>\r\r/* There are 5 types of terminal interface supported,\r * TERMIO, TERMIOS, VMS, MSDOS and SGTTY\r */\r\r#if defined(__sgi) && !defined(TERMIOS)\r#define TERMIOS\r#undef TERMIO\r#undef SGTTY\r#endif\r\r#if defined(linux) && !defined(TERMIO)\r#undef TERMIOS\r#define TERMIO\r#undef SGTTY\r#endif\r\r#ifdef _LIBC\r#define TERMIO\r#endif\r\r#if !defined(TERMIO) && !defined(TERMIOS) && !defined(VMS) && !defined(MSDOS)\r#define SGTTY\r#endif\r\r#ifdef TERMIOS\r#include <termios.h>\r#define TTY_STRUCT         struct termios\r#define TTY_FLAGS                c_lflag\r#define TTY_get(tty,data)       tcgetattr(tty,data)\r#define TTY_set(tty,data)   tcsetattr(tty,TCSANOW,data)\r#endif\r\r#ifdef TERMIO\r#include <termio.h>\r#define TTY_STRUCT                struct termio\r#define TTY_FLAGS         c_lflag\r#define TTY_get(tty,data)       ioctl(tty,TCGETA,data)\r#define TTY_set(tty,data)        ioctl(tty,TCSETA,data)\r#endif\r\r#ifdef SGTTY\r#include <sgtty.h>\r#define TTY_STRUCT               struct sgttyb\r#define TTY_FLAGS         sg_flags\r#define TTY_get(tty,data)      ioctl(tty,TIOCGETP,data)\r#define TTY_set(tty,data)      ioctl(tty,TIOCSETP,data)\r#endif\r\r#if !defined(_LIBC) && !defined(MSDOS) && !defined(VMS)\r#include <sys/ioctl.h>\r#endif\r\r#ifdef MSDOS\r#include <conio.h>\r#define fgets(a,b,c) noecho_fgets(a,b,c)\r#endif\r\r#ifdef VMS\r#include <ssdef.h>\r#include <iodef.h>\r#include <ttdef.h>\r#include <descrip.h>\rstruct IOSB {\r        short iosb$w_value;\r    short iosb$w_count;\r    long  iosb$l_info;\r     };\r#endif\r\r#ifndef NX509_SIG\r#define NX509_SIG 32\r#endif\r\r#ifndef NOPROTO\rstatic void read_till_nl(FILE *);\rstatic int read_pw(char *buf, char *buff, int size, char *prompt, int verify);\rstatic void recsig(int);\rstatic void pushsig(void);\rstatic void popsig(void);\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets(char *buf, int size, FILE *tty);\r#endif\r#else\rstatic void read_till_nl();\rstatic int read_pw();\rstatic void recsig();\rstatic void pushsig();\rstatic void popsig();\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets();\r#endif\r#endif\r\r#ifndef NOPROTO\rstatic void (*savsig[NX509_SIG])(int );\r#else\rstatic void (*savsig[NX509_SIG])();\r#endif\rstatic jmp_buf save;\r\rint des_read_password(key, prompt, verify)\rdes_cblock (*key);\rchar *prompt;\rint verify;\r       {\r      int ok;\r        char buf[BUFSIZ],buff[BUFSIZ];\r\r        if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)\r          des_string_to_key(buf,key);\r    memset(buf,0,BUFSIZ);\r  memset(buff,0,BUFSIZ);\r return(ok);\r    }\r\rint des_read_2passwords(key1, key2, prompt, verify)\rdes_cblock (*key1);\rdes_cblock (*key2);\rchar *prompt;\rint verify;\r       {\r      int ok;\r        char buf[BUFSIZ],buff[BUFSIZ];\r\r        if ((ok=read_pw(buf,buff,BUFSIZ,prompt,verify)) == 0)\r          des_string_to_2keys(buf,key1,key2);\r    memset(buf,0,BUFSIZ);\r  memset(buff,0,BUFSIZ);\r return(ok);\r    }\r\rint des_read_pw_string(buf, length, prompt, verify)\rchar *buf;\rint length;\rchar *prompt;\rint verify;\r        {\r      char buff[BUFSIZ];\r     int ret;\r\r      ret=read_pw(buf,buff,(length>BUFSIZ)?BUFSIZ:length,prompt,verify);\r     memset(buff,0,BUFSIZ);\r return(ret);\r   }\r\r#ifndef WIN16\r\rstatic void read_till_nl(in)\rFILE *in;\r       {\r#define SIZE 4\r       char buf[SIZE+1];\r\r     do      {\r              fgets(buf,SIZE,in);\r            } while (strchr(buf,'\n') == NULL);\r    }\r\r\r/* return 0 if ok, 1 (or -1) otherwise */\rstatic int read_pw(buf, buff, size, prompt, verify)\rchar *buf;\rchar *buff;\rint size;\rchar *prompt;\rint verify;\r   {\r#ifdef VMS\r   struct IOSB iosb;\r      $DESCRIPTOR(terminal,"TT");\r    long tty_orig[3], tty_new[3];\r  long status;\r   unsigned short channel = 0;\r#else\r#ifndef MSDOS\r        TTY_STRUCT tty_orig,tty_new;\r#endif\r#endif\r     int number=5;\r  int ok=0;\r      int ps=0;\r      int is_a_tty=1;\r\r       FILE *tty=NULL;\r        char *p;\r\r#ifdef __CYGWIN32__\r  tty = stdin;\r#elif !defined(MSDOS)\r     if ((tty=fopen("/dev/tty","r")) == NULL)\r               tty=stdin;\r#else /* MSDOS */\r   if ((tty=fopen("con","r")) == NULL)\r            tty=stdin;\r#endif /* MSDOS */\r\r#if defined(TTY_get) && !defined(VMS)\r   if (TTY_get(fileno(tty),&tty_orig) == -1)\r              {\r#ifdef ENOTTY\r                if (errno == ENOTTY)\r                   is_a_tty=0;\r            else\r#endif\r                    return(-1);\r            }\r      memcpy(&(tty_new),&(tty_orig),sizeof(tty_orig));\r#endif\r#ifdef VMS\r     status = SYS$ASSIGN(&terminal,&channel,0,0);\r   if (status != SS$_NORMAL)\r              return(-1);\r    status=SYS$QIOW(0,channel,IO$_SENSEMODE,&iosb,0,0,tty_orig,12,0,0,0,0);\r        if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))\r               return(-1);\r#endif\r\r    if (setjmp(save))\r              {\r              ok=0;\r          goto error;\r            }\r      pushsig();\r     ps=1;\r\r#ifdef TTY_FLAGS\r        tty_new.TTY_FLAGS &= ~ECHO;\r#endif\r\r#if defined(TTY_set) && !defined(VMS)\r      if (is_a_tty && (TTY_set(fileno(tty),&tty_new) == -1))\r         return(-1);\r#endif\r#ifdef VMS\r  tty_new[0] = tty_orig[0];\r      tty_new[1] = tty_orig[1] | TT$M_NOECHO;\r        tty_new[2] = tty_orig[2];\r      status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0,tty_new,12,0,0,0,0);\r if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))\r               return(-1);\r#endif\r     ps=2;\r\r while ((!ok) && (number--))\r            {\r              fputs(prompt,stderr);\r          fflush(stderr);\r\r               buf[0]='\0';\r           fgets(buf,size,tty);\r           if (feof(tty)) goto error;\r             if (ferror(tty)) goto error;\r           if ((p=(char *)strchr(buf,'\n')) != NULL)\r                      *p='\0';\r               else    read_till_nl(tty);\r             if (verify)\r                    {\r                      fprintf(stderr,"\nVerifying password - %s",prompt);\r                    fflush(stderr);\r                        buff[0]='\0';\r                  fgets(buff,size,tty);\r                  if (feof(tty)) goto error;\r                     if ((p=(char *)strchr(buff,'\n')) != NULL)\r                             *p='\0';\r                       else    read_till_nl(tty);\r                             \r                       if (strcmp(buf,buff) != 0)\r                             {\r                              fprintf(stderr,"\nVerify failure");\r                            fflush(stderr);\r                                break;\r                         /* continue; */\r                                }\r                      }\r              ok=1;\r          }\r\rerror:\r      fprintf(stderr,"\n");\r#ifdef DEBUG\r     perror("fgets(tty)");\r#endif\r   /* What can we do if there is an error? */\r#if defined(TTY_set) && !defined(VMS) \r      if (ps >= 2) TTY_set(fileno(tty),&tty_orig);\r#endif\r#ifdef VMS\r if (ps >= 2)\r           status = SYS$QIOW(0,channel,IO$_SETMODE,&iosb,0,0\r                      ,tty_orig,12,0,0,0,0);\r#endif\r  \r       if (ps >= 1) popsig();\r if (stdin != tty) fclose(tty);\r#ifdef VMS\r      status = SYS$DASSGN(channel);\r#endif\r   return(!ok);\r   }\r\r#else /* WIN16 */\r\rstatic int read_pw(buf, buff, size, prompt, verify)\rchar *buf;\rchar *buff;\rint size;\rchar *prompt;\rint verify;\r   { \r     memset(buf,0,size);\r    memset(buff,0,size);\r   return(0);\r     }\r\r#endif\r\rstatic void pushsig()\r       {\r      int i;\r\r        for (i=1; i<NX509_SIG; i++)\r            savsig[i]=signal(i,recsig);\r\r#ifdef SIGWINCH\r   signal(SIGWINCH,SIG_DFL);\r#endif\r       }\r\rstatic void popsig()\r        {\r      int i;\r\r        for (i=1; i<NX509_SIG; i++)\r            signal(i,savsig[i]);\r   }\r\rstatic void recsig(i)\rint i;\r        {\r      longjmp(save,1);\r#ifdef LINT\r   i=i;\r#endif\r    }\r\r#if defined(MSDOS) && !defined(WIN16)\rstatic int noecho_fgets(buf,size,tty)\rchar *buf;\rint size;\rFILE *tty;\r {\r      int i;\r char *p;\r\r      p=buf;\r for (;;)\r               {\r              if (size == 0)\r                 {\r                      *p='\0';\r                       break;\r                 }\r              size--;\r#ifdef WIN16TTY\r                i=_inchar();\r#else\r             i=getch();\r#endif\r              if (i == '\r') i='\n';\r         *(p++)=i;\r              if (i == '\n')\r                 {\r                      *p='\0';\r                       break;\r                 }\r              }\r      return(strlen(buf));\r   }\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/resource.h b/mac/libdes/src/resource.h
new file mode 100755 (executable)
index 0000000..6a9032d
--- /dev/null
@@ -0,0 +1 @@
+//{{NO_DEPENDENCIES}}\r// Microsoft Developer Studio generated include file.\r// Used by passwd_dialog.rc\r//\r#define IDD_PASSWD_DIALOG               101\r#define IDC_EDIT1                       1000\r#define IDC_PASSWD_EDIT                 1001\r\r// Next default values for new objects\r// \r#ifdef APSTUDIO_INVOKED\r#ifndef APSTUDIO_READONLY_SYMBOLS\r#define _APS_NEXT_RESOURCE_VALUE        102\r#define _APS_NEXT_COMMAND_VALUE         40001\r#define _APS_NEXT_CONTROL_VALUE         1002\r#define _APS_NEXT_SYMED_VALUE           101\r#endif\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/rnd_keys.c b/mac/libdes/src/rnd_keys.c
new file mode 100755 (executable)
index 0000000..1559966
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include "config.h"\r\rRCSID("$Id: rnd_keys.c,v 1.2 2001/12/04 02:06:31 rjs3 Exp $");\r#endif\r\r#include <des.h>\r#include <des_locl.h>\r#ifdef KRB5\r#include <krb5-types.h>\r#elif defined(KRB4)\r#include <ktypes.h>\r#endif\r\r#include <string.h>\r\r#ifdef TIME_WITH_SYS_TIME\r#include <sys/time.h>\r#include <time.h>\r#elif defined(HAVE_SYS_TIME_H)\r#include <sys/time.h>\r#else\r#include <time.h>\r#endif\r\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r\r#ifdef HAVE_UNISTD_H\r#include <unistd.h>\r#endif\r#ifdef HAVE_IO_H\r#include <io.h>\r#endif\r\r#ifdef HAVE_SIGNAL_H\r#include <signal.h>\r#endif\r#ifdef HAVE_FCNTL_H\r#include <fcntl.h>\r#endif\r\r#ifdef HAVE_WINSOCK_H\r#include <winsock.h>\r#endif\r\r/*\r * Generate "random" data by checksumming a file.\r *\r * Returns -1 if there were any problems with permissions or I/O\r * errors.\r */\rstatic\rint\rsumFile (const char *name, int len, void *res)\r{\r  u_int32_t sum[2];\r  u_int32_t buf[1024*2];\r  int fd, i;\r\r  fd = open (name, 0);\r  if (fd < 0)\r    return -1;\r\r  while (len > 0)\r    {\r      int n = read(fd, buf, sizeof(buf));\r      if (n < 0)\r   {\r        close(fd);\r     return n;\r    }\r      for (i = 0; i < (n/sizeof(buf[0])); i++)\r       {\r        sum[0] += buf[i];\r      i++;\r   sum[1] += buf[i];\r    }\r      len -= n;\r    }\r  close (fd);\r  memcpy (res, &sum, sizeof(sum));\r  return 0;\r}\r\r#if 0\rstatic\rint\rmd5sumFile (const char *name, int len, int32_t sum[4])\r{\r  int32_t buf[1024*2];\r  int fd, cnt;\r  struct md5 md5;\r\r  fd = open (name, 0);\r  if (fd < 0)\r    return -1;\r\r  md5_init(&md5);\r  while (len > 0)\r    {\r      int n = read(fd, buf, sizeof(buf));\r      if (n < 0)\r   {\r        close(fd);\r     return n;\r    }\r      md5_update(&md5, buf, n);\r      len -= n;\r    }\r  md5_finito(&md5, (unsigned char *)sum);\r  close (fd);\r  return 0;\r}\r#endif\r\r/*\r * Create a sequence of random 64 bit blocks.\r * The sequence is indexed with a long long and \r * based on an initial des key used as a seed.\r */\rstatic des_key_schedule sequence_seed;\rstatic u_int32_t sequence_index[2];\r\r/* \r * Random number generator based on ideas from truerand in cryptolib\r * as described on page 424 in Applied Cryptography 2 ed. by Bruce\r * Schneier.\r */\r\rstatic volatile int counter;\rstatic volatile unsigned char *gdata; /* Global data */\rstatic volatile int igdata;   /* Index into global data */\rstatic int gsize;\r\r#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)\r/* Visual C++ 4.0 (Windows95/NT) */\r\rstatic\rRETSIGTYPE\rsigALRM(int sig)\r{\r    if (igdata < gsize)\r      gdata[igdata++] ^= counter & 0xff;\r\r#ifndef HAVE_SIGACTION\r    signal(SIGALRM, sigALRM); /* Reinstall SysV signal handler */\r#endif\r    SIGRETURN(0);\r}\r\r#endif\r\r#if !defined(HAVE_RANDOM) && defined(HAVE_RAND)\r#ifndef srandom\r#define srandom srand\r#endif\r#ifndef random\r#define random rand\r#endif\r#endif\r\rstatic void\rdes_not_rand_data(unsigned char *data, int size)\r{\r  int i;\r\r  srandom (time (NULL));\r\r  for(i = 0; i < size; ++i)\r    data[i] ^= random() % 0x100;\r}\r\r#if !defined(WIN32) && !defined(__EMX__) && !defined(__OS2__) && !defined(__CYGWIN32__)\r\r#ifndef HAVE_SETITIMER\rstatic void\rpacemaker(struct timeval *tv)\r{\r    fd_set fds;\r    pid_t pid;\r    pid = getppid();\r    while(1){\r       FD_ZERO(&fds);\r FD_SET(0, &fds);\r       select(1, &fds, NULL, NULL, tv);\r       kill(pid, SIGALRM);\r    }\r}\r#endif\r\r/*\r * Generate size bytes of "random" data using timed interrupts.\r * It takes about 40ms/byte random data.\r * It's not neccessary to be root to run it.\r */\rvoid\rdes_rand_data(unsigned char *data, int size)\r{\r    struct itimerval tv, otv;\r#ifdef HAVE_SIGACTION\r    struct sigaction sa, osa;\r#else\r    RETSIGTYPE (*osa)(int);\r#endif\r    int i, j;\r#ifndef HAVE_SETITIMER\r    pid_t pid;\r#endif\r    char *rnd_devices[] = {"/dev/random",\r                      "/dev/srandom",\r                        "/dev/urandom",\r                        NULL};\r    char **p;\r\r    for(p = rnd_devices; *p; p++) {\r      int fd = open(*p, O_RDONLY | O_NDELAY);\r      \r      if(fd >= 0 && read(fd, data, size) == size) {\r  close(fd);\r     return;\r      }\r      close(fd);\r    }\r\r    /* Paranoia? Initialize data from /dev/mem if we can read it. */\r    if (size >= 8)\r      sumFile("/dev/mem", (1024*1024*2), data);\r\r    gdata = data;\r    gsize = size;\r    igdata = 0;\r\r#ifdef HAVE_SIGACTION\r    /* Setup signal handler */\r    sa.sa_handler = sigALRM;\r    sa.sa_flags = 0;\r    sigemptyset(&sa.sa_mask);\r    sigaction(SIGALRM, &sa, &osa);\r#else\r    osa = signal(SIGALRM, sigALRM);\r#endif\r  \r    /* Start timer */\r    tv.it_value.tv_sec = 0;\r    tv.it_value.tv_usec = 10 * 1000; /* 10 ms */\r    tv.it_interval = tv.it_value;\r#ifdef HAVE_SETITIMER\r    setitimer(ITIMER_REAL, &tv, &otv);\r#else\r    pid = fork();\r    if(pid == -1){\r des_not_rand_data(data, size);\r return;\r    }\r    if(pid == 0)\r pacemaker(&tv.it_interval);\r#endif\r\r    for(i = 0; i < 4; i++) {\r       for (igdata = 0; igdata < size;) /* igdata++ in sigALRM */\r         counter++;\r for (j = 0; j < size; j++) /* Only use 2 bits each lap */\r          gdata[j] = (gdata[j]>>2) | (gdata[j]<<6);\r    }\r#ifdef HAVE_SETITIMER\r    setitimer(ITIMER_REAL, &otv, 0);\r#else\r    kill(pid, SIGKILL);\r    waitpid(pid, NULL, 0);\r#endif\r#ifdef HAVE_SIGACTION\r    sigaction(SIGALRM, &osa, 0);\r#else\r    signal(SIGALRM, osa != SIG_ERR ? osa : SIG_DFL);\r#endif\r}\r#else\rvoid\rdes_rand_data(unsigned char *p, int s)\r{\r  des_not_rand_data (p, s);\r}\r#endif\r\rvoid\rdes_generate_random_block(des_cblock *block)\r{\r  des_rand_data((unsigned char *)block, sizeof(*block));\r}\r\r/*\r * Generate a "random" DES key.\r */\rvoid\rdes_rand_data_key(des_cblock *key)\r{\r    unsigned char data[8];\r    des_key_schedule sched;\r    do {\r   des_rand_data(data, sizeof(data));\r     des_rand_data((unsigned char*)key, sizeof(des_cblock));\r        des_set_odd_parity(key);\r       des_key_sched(key, sched);\r     des_ecb_encrypt(&data, key, sched, DES_ENCRYPT);\r       memset(&data, 0, sizeof(data));\r        memset(&sched, 0, sizeof(sched));\r      des_set_odd_parity(key);\r    } while(des_is_weak_key(key));\r}\r\r/*\r * Generate "random" data by checksumming /dev/mem\r *\r * It's neccessary to be root to run it. Returns -1 if there were any\r * problems with permissions.\r */\rint\rdes_mem_rand8(unsigned char *data)\r{\r  return 1;\r}\r\r/*\r * In case the generator does not get initialized use this as fallback.\r */\rstatic int initialized;\r\rstatic void\rdo_initialize(void)\r{\r    des_cblock default_seed;\r    do {\r        des_generate_random_block(&default_seed);\r      des_set_odd_parity(&default_seed);\r    } while (des_is_weak_key(&default_seed));\r    des_init_random_number_generator(&default_seed);\r}\r\r#define zero_long_long(ll) do { ll[0] = ll[1] = 0; } while (0)\r\r#define incr_long_long(ll) do { if (++ll[0] == 0) ++ll[1]; } while (0)\r\r#define set_sequence_number(ll) \\rmemcpy((char *)sequence_index, (ll), sizeof(sequence_index));\r\r/*\r * Set the sequnce number to this value (a long long).\r */\rvoid\rdes_set_sequence_number(unsigned char *ll)\r{\r    set_sequence_number(ll);\r}\r\r/*\r * Set the generator seed and reset the sequence number to 0.\r */\rvoid\rdes_set_random_generator_seed(des_cblock *seed)\r{\r    des_key_sched(seed, sequence_seed);\r    zero_long_long(sequence_index);\r    initialized = 1;\r}\r\r/*\r * Generate a sequence of random des keys\r * using the random block sequence, fixup\r * parity and skip weak keys.\r */\rint\rdes_new_random_key(des_cblock *key)\r{\r    if (!initialized)\r     do_initialize();\r\r    do {\r     des_ecb_encrypt((des_cblock *) sequence_index,\r                 key,\r                   sequence_seed,\r                 DES_ENCRYPT);\r  incr_long_long(sequence_index);\r        /* random key must have odd parity and not be weak */\r  des_set_odd_parity(key);\r    } while (des_is_weak_key(key));\r    return(0);\r}\r\r/*\r * des_init_random_number_generator:\r *\r * Initialize the sequence of random 64 bit blocks.  The input seed\r * can be a secret key since it should be well hidden and is also not\r * kept.\r *\r */\rvoid \rdes_init_random_number_generator(des_cblock *seed)\r{\r    struct timeval now;\r    des_cblock uniq;\r    des_cblock new_key;\r\r    gettimeofday(&now, (struct timezone *)0);\r    des_generate_random_block(&uniq);\r\r    /* Pick a unique random key from the shared sequence. */\r    des_set_random_generator_seed(seed);\r    set_sequence_number((unsigned char *)&uniq);\r    des_new_random_key(&new_key);\r\r    /* Select a new nonshared sequence, */\r    des_set_random_generator_seed(&new_key);\r\r    /* and use the current time to pick a key for the new sequence. */\r    set_sequence_number((unsigned char *)&now);\r    des_new_random_key(&new_key);\r    des_set_random_generator_seed(&new_key);\r}\r\r/* This is for backwards compatibility. */\rvoid\rdes_random_key(des_cblock ret)\r{\r    des_new_random_key((des_cblock *)ret);\r}\r\r#ifdef TESTRUN\rint\rmain()\r{\r    unsigned char data[8];\r    int i;\r\r    while (1)\r        {\r            if (sumFile("/dev/mem", (1024*1024*8), data) != 0)\r       { perror("sumFile"); exit(1); }\r            for (i = 0; i < 8; i++)\r                printf("%02x", data[i]);\r            printf("\n");\r        }\r}\r#endif\r\r#ifdef TESTRUN2\rint\rmain()\r{\r    des_cblock data;\r    int i;\r\r    while (1)\r        {\r     do_initialize();\r            des_random_key(data);\r            for (i = 0; i < 8; i++)\r                printf("%02x", data[i]);\r            printf("\n");\r        }\r}\r#endif\r
\ No newline at end of file
diff --git a/mac/libdes/src/rpc_des.h b/mac/libdes/src/rpc_des.h
new file mode 100755 (executable)
index 0000000..86dda94
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/rpc_des.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/*  @(#)des.h  2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI  */\r/*\r * Sun RPC is a product of Sun Microsystems, Inc. and is provided for\r * unrestricted use provided that this legend is included on all tape\r * media and as a part of the software program in whole or part.  Users\r * may copy or modify Sun RPC without charge, but are not authorized\r * to license or distribute it to anyone else except as part of a product or\r * program developed by the user.\r * \r * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE\r * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR\r * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.\r * \r * Sun RPC is provided with no support and without any obligation on the\r * part of Sun Microsystems, Inc. to assist in its use, correction,\r * modification or enhancement.\r * \r * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE\r * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC\r * OR ANY PART THEREOF.\r * \r * In no event will Sun Microsystems, Inc. be liable for any lost revenue\r * or profits or other special, indirect and consequential damages, even if\r * Sun has been advised of the possibility of such damages.\r * \r * Sun Microsystems, Inc.\r * 2550 Garcia Avenue\r * Mountain View, California  94043\r */\r/*\r * Generic DES driver interface\r * Keep this file hardware independent!\r * Copyright (c) 1986 by Sun Microsystems, Inc.\r */\r\r#define DES_MAXLEN      65536   /* maximum # of bytes to encrypt  */\r#define DES_QUICKLEN       16      /* maximum # of bytes to encrypt quickly */\r\r#ifdef HEADER_DES_H\r#undef ENCRYPT\r#undef DECRYPT\r#endif\r\renum desdir { ENCRYPT, DECRYPT };\renum desmode { CBC, ECB };\r\r/*\r * parameters to ioctl call\r */\rstruct desparams {\r     unsigned char des_key[8];       /* key (with low bit parity) */\r        enum desdir des_dir;    /* direction */\r        enum desmode des_mode;  /* mode */\r     unsigned char des_ivec[8];      /* input vector */\r     unsigned des_len;       /* number of bytes to crypt */\r union {\r                unsigned char UDES_data[DES_QUICKLEN];\r         unsigned char *UDES_buf;\r       } UDES;\r#       define des_data UDES.UDES_data  /* direct data here if quick */\r#       define des_buf  UDES.UDES_buf   /* otherwise, pointer to data */\r};\r\r/*\r * Encrypt an arbitrary sized buffer\r */\r#define        DESIOCBLOCK     _IOWR(d, 6, struct desparams)\r\r/* \r * Encrypt of small amount of data, quickly\r */\r#define DESIOCQUICK  _IOWR(d, 7, struct desparams) \r\r
\ No newline at end of file
diff --git a/mac/libdes/src/rpc_enc.c b/mac/libdes/src/rpc_enc.c
new file mode 100755 (executable)
index 0000000..eae7b1e
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/rpc_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "rpc_des.h"\r#include "des_locl.h"\r#include "des_ver.h"\r\r#ifndef NOPROTO\rint _des_crypt(char *buf,int len,struct desparams *desp);\r#else\rint _des_crypt();\r#endif\r\rint _des_crypt(buf, len, desp)\rchar *buf;\rint len;\rstruct desparams *desp;\r {\r      des_key_schedule ks;\r   int enc;\r\r      des_set_key((des_cblock *)desp->des_key,ks);\r   enc=(desp->des_dir == ENCRYPT)?DES_ENCRYPT:DES_DECRYPT;\r\r       if (desp->des_mode == CBC)\r             des_ecb_encrypt((des_cblock *)desp->UDES.UDES_buf,\r                             (des_cblock *)desp->UDES.UDES_buf,ks,enc);\r     else\r           {\r              des_ncbc_encrypt((des_cblock *)desp->UDES.UDES_buf,\r                            (des_cblock *)desp->UDES.UDES_buf,\r                             (long)len,ks,\r                          (des_cblock *)desp->des_ivec,enc);\r#ifdef undef\r                /* len will always be %8 if called from common_crypt\r            * in secure_rpc.\r               * Libdes's cbc encrypt does not copy back the iv,\r              * so we have to do it here. */\r                /* It does now :-) eay 20/09/95 */\r\r            a=(char *)&(desp->UDES.UDES_buf[len-8]);\r               b=(char *)&(desp->des_ivec[0]);\r\r               *(a++)= *(b++); *(a++)= *(b++);\r                *(a++)= *(b++); *(a++)= *(b++);\r                *(a++)= *(b++); *(a++)= *(b++);\r                *(a++)= *(b++); *(a++)= *(b++);\r#endif\r         }\r      return(1);      \r       }\r\r
\ No newline at end of file
diff --git a/mac/libdes/src/rpw.c b/mac/libdes/src/rpw.c
new file mode 100755 (executable)
index 0000000..c10c24f
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/rpw.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\r#endif\r#include <stdio.h>\r#include "des.h"\r\rint main(argc,argv)\rint argc;\rchar *argv[];\r  {\r      des_cblock k,k1;\r       int i;\r\r        printf("read passwd\n");\r       if ((i=des_read_password((C_Block *)k,"Enter password:",0)) == 0)\r              {\r              printf("password = ");\r         for (i=0; i<8; i++)\r                    printf("%02x ",k[i]);\r          }\r      else\r           printf("error %d\n",i);\r        printf("\n");\r  printf("read 2passwds and verify\n");\r  if ((i=des_read_2passwords((C_Block *)k,(C_Block *)k1,\r         "Enter verified password:",1)) == 0)\r           {\r              printf("password1 = ");\r                for (i=0; i<8; i++)\r                    printf("%02x ",k[i]);\r          printf("\n");\r          printf("password2 = ");\r                for (i=0; i<8; i++)\r                    printf("%02x ",k1[i]);\r         printf("\n");\r          exit(1);\r               }\r      else\r           {\r              printf("error %d\n",i);\r                exit(0);\r               }\r#ifdef LINT\r  return(0);\r#endif\r      }\r
\ No newline at end of file
diff --git a/mac/libdes/src/set_key.c b/mac/libdes/src/set_key.c
new file mode 100755 (executable)
index 0000000..432034a
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/set_key.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* set_key.c v 1.4 eay 24/9/91\r * 1.4 Speed up by 400% :-)\r * 1.3 added register declarations.\r * 1.2 unrolled make_key_sched a bit more\r * 1.1 added norm_expand_bits\r * 1.0 First working version\r */\r#include "des_locl.h"\r#include "podd.h"\r#include "sk.h"\r\r#ifndef NOPROTO\rstatic int check_parity(des_cblock (*key));\r#else\rstatic int check_parity();\r#endif\r\rint des_check_key=0;\r\rvoid des_set_odd_parity(key)\rdes_cblock (*key);\r   {\r      int i;\r\r        for (i=0; i<DES_KEY_SZ; i++)\r           (*key)[i]=odd_parity[(*key)[i]];\r       }\r\rstatic int check_parity(key)\rdes_cblock (*key);\r     {\r      int i;\r\r        for (i=0; i<DES_KEY_SZ; i++)\r           {\r              if ((*key)[i] != odd_parity[(*key)[i]])\r                        return(0);\r             }\r      return(1);\r     }\r\r/* Weak and semi week keys as take from\r * %A D.W. Davies\r * %A W.L. Price\r * %T Security for Computer Networks\r * %I John Wiley & Sons\r * %D 1984\r * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference\r * (and actual cblock values).\r */\r#define NUM_WEAK_KEY 16\rstatic des_cblock weak_keys[NUM_WEAK_KEY]={\r /* weak keys */\r        {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},\r     {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},\r     {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},\r     {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},\r     /* semi-weak keys */\r   {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},\r     {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},\r     {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},\r     {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},\r     {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},\r     {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},\r     {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},\r     {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},\r     {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},\r     {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},\r     {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},\r     {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};\r\rint des_is_weak_key(key)\rdes_cblock (*key);\r       {\r      int i;\r\r        for (i=0; i<NUM_WEAK_KEY; i++)\r         /* Added == 0 to comparision, I obviously don't run\r             * this section very often :-(, thanks to\r               * engineering@MorningStar.Com for the fix\r              * eay 93/06/29 */\r             if (memcmp(weak_keys[i],key,sizeof(key)) == 0) return(1);\r      return(0);\r     }\r\r/* NOW DEFINED IN des_local.h\r * See ecb_encrypt.c for a pseudo description of these macros. \r * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\\r *         (b)^=(t),\\r *   (a)=((a)^((t)<<(n))))\r */\r\r#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\\r        (a)=(a)^(t)^(t>>(16-(n))))\r\r/* return 0 if key parity is odd (correct),\r * return -1 if key parity error,\r * return -2 if illegal weak key.\r */\rint des_set_key(key, schedule)\rdes_cblock (*key);\rdes_key_schedule schedule;\r   {\r      static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};\r      register DES_LONG c,d,t,s,t2;\r  register unsigned char *in;\r    register DES_LONG *k;\r  register int i;\r\r       if (des_check_key)\r             {\r              if (!check_parity(key))\r                        return(-1);\r\r           if (des_is_weak_key(key))\r                      return(-2);\r            }\r\r     k=(DES_LONG *)schedule;\r        in=(unsigned char *)key;\r\r      c2l(in,c);\r     c2l(in,d);\r\r    /* do PC1 in 60 simple operations */ \r/*        PERM_OP(d,c,t,4,0x0f0f0f0fL);\r  HPERM_OP(c,t,-2, 0xcccc0000L);\r HPERM_OP(c,t,-1, 0xaaaa0000L);\r HPERM_OP(c,t, 8, 0x00ff0000L);\r HPERM_OP(c,t,-1, 0xaaaa0000L);\r HPERM_OP(d,t,-8, 0xff000000L);\r HPERM_OP(d,t, 8, 0x00ff0000L);\r HPERM_OP(d,t, 2, 0x33330000L);\r d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);\r d=(d>>8)|((c&0xf0000000L)>>4);\r c&=0x0fffffffL; */\r\r    /* I now do it in 47 simple operations :-)\r      * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)\r         * for the inspiration. :-) */\r PERM_OP (d,c,t,4,0x0f0f0f0fL);\r HPERM_OP(c,t,-2,0xcccc0000L);\r  HPERM_OP(d,t,-2,0xcccc0000L);\r  PERM_OP (d,c,t,1,0x55555555L);\r PERM_OP (c,d,t,8,0x00ff00ffL);\r PERM_OP (d,c,t,1,0x55555555L);\r d=      (((d&0x000000ffL)<<16L)| (d&0x0000ff00L)     |\r          ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));\r        c&=0x0fffffffL;\r\r       for (i=0; i<ITERATIONS; i++)\r           {\r              if (shifts2[i])\r                        { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }\r                else\r                   { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }\r                c&=0x0fffffffL;\r                d&=0x0fffffffL;\r                /* could be a few less shifts but I am to lazy at this\r          * point in time to investigate */\r             s=      des_skb[0][ (c    )&0x3f                ]|\r                     des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|\r                    des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|\r                    des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |\r                                              ((c>>22L)&0x38)];\r            t=      des_skb[4][ (d    )&0x3f                ]|\r                     des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|\r                   des_skb[6][ (d>>15L)&0x3f                ]|\r                    des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];\r\r          /* table contained 0213 4657 */\r                t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;\r             *(k++)=ROTATE(t2,30)&0xffffffffL;\r\r             t2=((s>>16L)|(t&0xffff0000L));\r         *(k++)=ROTATE(t2,26)&0xffffffffL;\r              }\r      return(0);\r     }\r\rint des_key_sched(key, schedule)\rdes_cblock (*key);\rdes_key_schedule schedule;\r      {\r      return(des_set_key(key,schedule));\r     }\r
\ No newline at end of file
diff --git a/mac/libdes/src/sha.c b/mac/libdes/src/sha.c
new file mode 100755 (executable)
index 0000000..818abd8
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r#ifdef HAVE_CONFIG_H\r#include "config.h"\r\rRCSID("$Id: sha.c,v 1.2 2001/12/04 02:06:31 rjs3 Exp $");\r#endif\r\r#include <stdlib.h>\r#include <string.h>\r\r#include "sha.h"\r\r#ifndef min\r#define min(a,b) (((a)>(b))?(b):(a))\r#endif\r\r#define A m->counter[0]\r#define B m->counter[1]\r#define C m->counter[2]\r#define D m->counter[3]\r#define E m->counter[4]\r#define X data\r\rvoid\rsha_init (struct sha *m)\r{\r  m->offset = 0;\r  m->sz = 0;\r  A = 0x67452301;\r  B = 0xefcdab89;\r  C = 0x98badcfe;\r  D = 0x10325476;\r  E = 0xc3d2e1f0;\r}\r\rstatic inline u_int32_t\rcshift (u_int32_t x, unsigned int n)\r{\r  return (x << n) | (x >> (32 - n));\r}\r\r#define F0(x,y,z) ((x & y) | (~x & z))\r#define F1(x,y,z) (x ^ y ^ z)\r#define F2(x,y,z) ((x & y) | (x & z) | (y & z))\r#define F3(x,y,z) F1(x,y,z)\r\r#define K0 0x5a827999\r#define K1 0x6ed9eba1\r#define K2 0x8f1bbcdc\r#define K3 0xca62c1d6\r\r#define DO(t,f,k) \\rdo { \\r  u_int32_t temp; \\r \\r  temp = cshift(AA, 5) + f(BB,CC,DD) + EE + data[t] + k; \\r  EE = DD; \\r  DD = CC; \\r  CC = cshift(BB, 30); \\r  BB = AA; \\r  AA = temp; \\r} while(0)\r\rstatic inline void\rcalc (struct sha *m, u_int32_t *in)\r{\r  u_int32_t AA, BB, CC, DD, EE;\r  u_int32_t data[80];\r  int i;\r\r  AA = A;\r  BB = B;\r  CC = C;\r  DD = D;\r  EE = E;\r\r  for (i = 0; i < 16; ++i)\r    data[i] = in[i];\r  for (i = 16; i < 80; ++i)\r    data[i] = cshift(data[i-3] ^ data[i-8] ^ data[i-14] ^ data[i-16], 1);\r\r  /* t=[0,19] */\r\r  DO(0,F0,K0);\r  DO(1,F0,K0);\r  DO(2,F0,K0);\r  DO(3,F0,K0);\r  DO(4,F0,K0);\r  DO(5,F0,K0);\r  DO(6,F0,K0);\r  DO(7,F0,K0);\r  DO(8,F0,K0);\r  DO(9,F0,K0);\r  DO(10,F0,K0);\r  DO(11,F0,K0);\r  DO(12,F0,K0);\r  DO(13,F0,K0);\r  DO(14,F0,K0);\r  DO(15,F0,K0);\r  DO(16,F0,K0);\r  DO(17,F0,K0);\r  DO(18,F0,K0);\r  DO(19,F0,K0);\r\r  /* t=[20,39] */\r\r  DO(20,F1,K1);\r  DO(21,F1,K1);\r  DO(22,F1,K1);\r  DO(23,F1,K1);\r  DO(24,F1,K1);\r  DO(25,F1,K1);\r  DO(26,F1,K1);\r  DO(27,F1,K1);\r  DO(28,F1,K1);\r  DO(29,F1,K1);\r  DO(30,F1,K1);\r  DO(31,F1,K1);\r  DO(32,F1,K1);\r  DO(33,F1,K1);\r  DO(34,F1,K1);\r  DO(35,F1,K1);\r  DO(36,F1,K1);\r  DO(37,F1,K1);\r  DO(38,F1,K1);\r  DO(39,F1,K1);\r\r  /* t=[40,59] */\r\r  DO(40,F2,K2);\r  DO(41,F2,K2);\r  DO(42,F2,K2);\r  DO(43,F2,K2);\r  DO(44,F2,K2);\r  DO(45,F2,K2);\r  DO(46,F2,K2);\r  DO(47,F2,K2);\r  DO(48,F2,K2);\r  DO(49,F2,K2);\r  DO(50,F2,K2);\r  DO(51,F2,K2);\r  DO(52,F2,K2);\r  DO(53,F2,K2);\r  DO(54,F2,K2);\r  DO(55,F2,K2);\r  DO(56,F2,K2);\r  DO(57,F2,K2);\r  DO(58,F2,K2);\r  DO(59,F2,K2);\r\r  /* t=[60,79] */\r\r  DO(60,F3,K3);\r  DO(61,F3,K3);\r  DO(62,F3,K3);\r  DO(63,F3,K3);\r  DO(64,F3,K3);\r  DO(65,F3,K3);\r  DO(66,F3,K3);\r  DO(67,F3,K3);\r  DO(68,F3,K3);\r  DO(69,F3,K3);\r  DO(70,F3,K3);\r  DO(71,F3,K3);\r  DO(72,F3,K3);\r  DO(73,F3,K3);\r  DO(74,F3,K3);\r  DO(75,F3,K3);\r  DO(76,F3,K3);\r  DO(77,F3,K3);\r  DO(78,F3,K3);\r  DO(79,F3,K3);\r\r  A += AA;\r  B += BB;\r  C += CC;\r  D += DD;\r  E += EE;\r}\r\r/*\r * From `Performance analysis of SHA' by Joseph D. Touch <touch@isi.edu>\r */\r\rstatic inline u_int32_t\rswap_u_int32_t (u_int32_t t)\r{\r#if !defined(WORDS_BIGENDIAN)\r#define ROL(x,n) ((x)<<(n))|((x)>>(32-(n)))\r  u_int32_t temp1, temp2;\r\r  temp1   = ROL(t,16);\r  temp2   = temp1 >> 8;\r  temp1  &= 0x00ff00ff;\r  temp2  &= 0x00ff00ff;\r  temp1 <<= 8;\r  return temp1 | temp2;\r#else\r  return t;\r#endif\r}\r\rstruct x32{\r  unsigned int a:32;\r  unsigned int b:32;\r};\r\rvoid\rsha_update (struct sha *m, const void *v, size_t len)\r{\r  const unsigned char *p = v;\r  m->sz += len;\r  while(len > 0){\r    size_t l = min(len, 64 - m->offset);\r    memcpy(m->save + m->offset, p, l);\r    m->offset += l;\r    p += l;\r    len -= l;\r    if(m->offset == 64){\r#if !defined(WORDS_BIGENDIAN) || defined(_CRAY)\r      int i;\r      u_int32_t current[16];\r      struct x32 *u = (struct x32*)m->save;\r      for(i = 0; i < 8; i++){\r      current[2*i+0] = swap_u_int32_t(u[i].a);\r       current[2*i+1] = swap_u_int32_t(u[i].b);\r      }\r      calc(m, current);\r#else\r      calc(m, (u_int32_t*)m->save);\r#endif\r      m->offset = 0;\r    }\r  }\r}\r\rvoid\rsha_finito (struct sha *m, void *res)\r{\r  static unsigned char zeros[72];\r  u_int32_t len;\r  unsigned int dstart = (120 - m->offset - 1) % 64 + 1;\r\r  *zeros = 0x80;\r  memset (zeros + 1, 0, sizeof(zeros) - 1);\r  len = 8 * m->sz;\r  zeros[dstart+7] = (len >> 0) & 0xff;\r  zeros[dstart+6] = (len >> 8) & 0xff;\r  zeros[dstart+5] = (len >> 16) & 0xff;\r  zeros[dstart+4] = (len >> 24) & 0xff;\r  sha_update (m, zeros, dstart + 8);\r  {\r      int i;\r      unsigned char *r = (unsigned char*)res;\r\r      for (i = 0; i < 5; ++i) {\r          r[4*i+3] = m->counter[i] & 0xFF;\r       r[4*i+2] = (m->counter[i] >> 8) & 0xFF;\r        r[4*i+1] = (m->counter[i] >> 16) & 0xFF;\r       r[4*i]   = (m->counter[i] >> 24) & 0xFF;\r      }\r  }\r#if 0\r  {\r    int i;\r    u_int32_t *r = (u_int32_t *)res;\r\r    for (i = 0; i < 5; ++i)\r      r[i] = swap_u_int32_t (m->counter[i]);\r  }\r#endif\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/sha.h b/mac/libdes/src/sha.h
new file mode 100755 (executable)
index 0000000..779369a
--- /dev/null
@@ -0,0 +1 @@
+/*\r * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska H\9agskolan\r * (Royal Institute of Technology, Stockholm, Sweden).\r * All rights reserved.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * \r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * \r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * \r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *      This product includes software developed by the Kungliga Tekniska\r *      H\9agskolan and its contributors.\r * \r * 4. Neither the name of the Institute nor the names of its contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r * \r * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r */\r\r/* $Id: sha.h,v 1.2 2001/12/04 02:06:31 rjs3 Exp $ */\r\r#include <stdlib.h>\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r#ifdef HAVE_SYS_BITYPES_H\r#include <sys/bitypes.h>\r#endif\r#ifdef KRB5\r#include <krb5-types.h>\r#elif defined(KRB4)\r#include <ktypes.h>\r#endif\r\rstruct sha {\r  unsigned int offset;\r  unsigned int sz;\r  u_int32_t counter[5];\r  unsigned char save[64];\r};\r\rvoid sha_init (struct sha *m);\rvoid sha_update (struct sha *m, const void *v, size_t len);\rvoid sha_finito (struct sha *m, void *res);\r
\ No newline at end of file
diff --git a/mac/libdes/src/shifts.pl b/mac/libdes/src/shifts.pl
new file mode 100755 (executable)
index 0000000..9f8eb85
--- /dev/null
@@ -0,0 +1 @@
+#/usr/local/bin/perl\r\rsub lab_shift\r   {\r      local(*a,$n)=@_;\r       local(@r,$i,$j,$k,$d,@z);\r\r     @r=&shift(*a,$n);\r      foreach $i (0 .. 31)\r           {\r              @z=split(/\^/,$r[$i]);\r         for ($j=0; $j <= $#z; $j++)\r                    {\r                      ($d)=($z[$j] =~ /^(..)/);\r                      ($k)=($z[$j] =~ /\[(.*)\]$/);\r                  $k.=",$n" if ($k ne "");\r                       $k="$n"   if ($k eq "");\r                       $d="$d[$k]";\r                   $z[$j]=$d;\r                     }\r              $r[$i]=join('^',@z);\r           }\r      return(@r);\r    }\r\rsub shift\r   {\r      local(*a,$n)=@_;\r       local(@f);\r\r    if ($n > 0)\r            {\r              @f=&shiftl(*a,$n);\r             }\r      else\r           {\r              @f=&shiftr(*a,-$n);\r            }\r      return(@f);\r    }\r\rsub rotate\r  {\r      local(*a,$n)=@_;\r       local(@f);\r\r    if ($n > 0)\r            { @f=&rotatel(*a,$n); }\r        else\r           { @f=&rotater(*a,-$n); }\r       return(@f);\r    }\r\rsub rotater\r {\r      local(*a,$n)=@_;\r       local(@f,@g);\r\r @f=&shiftr(*a,$n);\r     @g=&shiftl(*a,32-$n);\r  $#f=31;\r        $#g=31;\r        return(&or(*f,*g));\r    }\r\rsub rotatel\r {\r      local(*a,$n)=@_;\r       local(@f,@g);\r\r @f=&shiftl(*a,$n);\r     @g=&shiftr(*a,32-$n);\r  $#f=31;\r        $#g=31;\r        return(&or(*f,*g));\r    }\r\rsub shiftr\r  {\r      local(*a,$n)=@_;\r       local(@r,$i);\r\r $#r=31;\r        foreach $i (0 .. 31)\r           {\r              if (($i+$n) > 31)\r                      {\r                      $r[$i]="--";\r                   }\r              else\r                   {\r                      $r[$i]=$a[$i+$n];\r                      }\r              }\r      return(@r);\r    }\r\rsub shiftl\r  {\r      local(*a,$n)=@_;\r       local(@r,$i);\r\r $#r=31;\r        foreach $i (0 .. 31)\r           {\r              if ($i < $n)\r                   {\r                      $r[$i]="--";\r                   }\r              else\r                   {\r                      $r[$i]=$a[$i-$n];\r                      }\r              }\r      return(@r);\r    }\r\rsub printit\r {\r      local(@a)=@_;\r  local($i);\r\r    foreach $i (0 .. 31)\r           {\r              printf "%2s  ",$a[$i];\r         print "\n" if (($i%8) == 7);\r           }\r      print "\n";\r    }\r\rsub xor\r     {\r      local(*a,*b)=@_;\r       local(@r,$i);\r\r $#r=31;\r        foreach $i (0 .. 31)\r           {\r              $r[$i]=&compress($a[$i].'^'.$b[$i]);\r#          $r[$i]=$a[$i]."^".$b[$i];\r              }\r      return(@r);\r    }\r\rsub and\r     {\r      local(*a,$m)=@_;\r       local(@r,$i);\r\r $#r=31;\r        foreach $i (0 .. 31)\r           {\r              $r[$i]=(($m & (1<<$i))?($a[$i]):('--'));\r               }\r      return(@r);\r    }\r\rsub or\r      {\r      local(*a,*b)=@_;\r       local(@r,$i);\r\r $#r=31;\r        foreach $i (0 .. 31)\r           {\r              $r[$i]='--'   if (($a[$i] eq '--') && ($b[$i] eq '--'));\r               $r[$i]=$a[$i] if (($a[$i] ne '--') && ($b[$i] eq '--'));\r               $r[$i]=$b[$i] if (($a[$i] eq '--') && ($b[$i] ne '--'));\r               $r[$i]='++'   if (($a[$i] ne '--') && ($b[$i] ne '--'));\r               }\r      return(@r);\r    }\r\rsub compress\r        {\r      local($s)=@_;\r  local($_,$i,@a,%a,$r);\r\r        $s =~ s/\^\^/\^/g;\r     $s =~ s/^\^//;\r $s =~ s/\^$//;\r @a=split(/\^/,$s);\r\r    while ($#a >= 0)\r               {\r              $_=shift(@a);\r          next unless /\d/;\r              $a{$_}++;\r              }\r      foreach $i (sort keys %a)\r              {\r              next if ($a{$i}%2 == 0);\r               $r.="$i^";\r             }\r      chop($r);\r      return($r);\r    }\r1;\r
\ No newline at end of file
diff --git a/mac/libdes/src/sk.h b/mac/libdes/src/sk.h
new file mode 100755 (executable)
index 0000000..27d7c80
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/sk.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\rstatic const DES_LONG des_skb[8][64]={\r{\r/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */\r0x00000000L,0x00000010L,0x20000000L,0x20000010L,\r0x00010000L,0x00010010L,0x20010000L,0x20010010L,\r0x00000800L,0x00000810L,0x20000800L,0x20000810L,\r0x00010800L,0x00010810L,0x20010800L,0x20010810L,\r0x00000020L,0x00000030L,0x20000020L,0x20000030L,\r0x00010020L,0x00010030L,0x20010020L,0x20010030L,\r0x00000820L,0x00000830L,0x20000820L,0x20000830L,\r0x00010820L,0x00010830L,0x20010820L,0x20010830L,\r0x00080000L,0x00080010L,0x20080000L,0x20080010L,\r0x00090000L,0x00090010L,0x20090000L,0x20090010L,\r0x00080800L,0x00080810L,0x20080800L,0x20080810L,\r0x00090800L,0x00090810L,0x20090800L,0x20090810L,\r0x00080020L,0x00080030L,0x20080020L,0x20080030L,\r0x00090020L,0x00090030L,0x20090020L,0x20090030L,\r0x00080820L,0x00080830L,0x20080820L,0x20080830L,\r0x00090820L,0x00090830L,0x20090820L,0x20090830L,\r},{\r/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */\r0x00000000L,0x02000000L,0x00002000L,0x02002000L,\r0x00200000L,0x02200000L,0x00202000L,0x02202000L,\r0x00000004L,0x02000004L,0x00002004L,0x02002004L,\r0x00200004L,0x02200004L,0x00202004L,0x02202004L,\r0x00000400L,0x02000400L,0x00002400L,0x02002400L,\r0x00200400L,0x02200400L,0x00202400L,0x02202400L,\r0x00000404L,0x02000404L,0x00002404L,0x02002404L,\r0x00200404L,0x02200404L,0x00202404L,0x02202404L,\r0x10000000L,0x12000000L,0x10002000L,0x12002000L,\r0x10200000L,0x12200000L,0x10202000L,0x12202000L,\r0x10000004L,0x12000004L,0x10002004L,0x12002004L,\r0x10200004L,0x12200004L,0x10202004L,0x12202004L,\r0x10000400L,0x12000400L,0x10002400L,0x12002400L,\r0x10200400L,0x12200400L,0x10202400L,0x12202400L,\r0x10000404L,0x12000404L,0x10002404L,0x12002404L,\r0x10200404L,0x12200404L,0x10202404L,0x12202404L,\r},{\r/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */\r0x00000000L,0x00000001L,0x00040000L,0x00040001L,\r0x01000000L,0x01000001L,0x01040000L,0x01040001L,\r0x00000002L,0x00000003L,0x00040002L,0x00040003L,\r0x01000002L,0x01000003L,0x01040002L,0x01040003L,\r0x00000200L,0x00000201L,0x00040200L,0x00040201L,\r0x01000200L,0x01000201L,0x01040200L,0x01040201L,\r0x00000202L,0x00000203L,0x00040202L,0x00040203L,\r0x01000202L,0x01000203L,0x01040202L,0x01040203L,\r0x08000000L,0x08000001L,0x08040000L,0x08040001L,\r0x09000000L,0x09000001L,0x09040000L,0x09040001L,\r0x08000002L,0x08000003L,0x08040002L,0x08040003L,\r0x09000002L,0x09000003L,0x09040002L,0x09040003L,\r0x08000200L,0x08000201L,0x08040200L,0x08040201L,\r0x09000200L,0x09000201L,0x09040200L,0x09040201L,\r0x08000202L,0x08000203L,0x08040202L,0x08040203L,\r0x09000202L,0x09000203L,0x09040202L,0x09040203L,\r},{\r/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */\r0x00000000L,0x00100000L,0x00000100L,0x00100100L,\r0x00000008L,0x00100008L,0x00000108L,0x00100108L,\r0x00001000L,0x00101000L,0x00001100L,0x00101100L,\r0x00001008L,0x00101008L,0x00001108L,0x00101108L,\r0x04000000L,0x04100000L,0x04000100L,0x04100100L,\r0x04000008L,0x04100008L,0x04000108L,0x04100108L,\r0x04001000L,0x04101000L,0x04001100L,0x04101100L,\r0x04001008L,0x04101008L,0x04001108L,0x04101108L,\r0x00020000L,0x00120000L,0x00020100L,0x00120100L,\r0x00020008L,0x00120008L,0x00020108L,0x00120108L,\r0x00021000L,0x00121000L,0x00021100L,0x00121100L,\r0x00021008L,0x00121008L,0x00021108L,0x00121108L,\r0x04020000L,0x04120000L,0x04020100L,0x04120100L,\r0x04020008L,0x04120008L,0x04020108L,0x04120108L,\r0x04021000L,0x04121000L,0x04021100L,0x04121100L,\r0x04021008L,0x04121008L,0x04021108L,0x04121108L,\r},{\r/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */\r0x00000000L,0x10000000L,0x00010000L,0x10010000L,\r0x00000004L,0x10000004L,0x00010004L,0x10010004L,\r0x20000000L,0x30000000L,0x20010000L,0x30010000L,\r0x20000004L,0x30000004L,0x20010004L,0x30010004L,\r0x00100000L,0x10100000L,0x00110000L,0x10110000L,\r0x00100004L,0x10100004L,0x00110004L,0x10110004L,\r0x20100000L,0x30100000L,0x20110000L,0x30110000L,\r0x20100004L,0x30100004L,0x20110004L,0x30110004L,\r0x00001000L,0x10001000L,0x00011000L,0x10011000L,\r0x00001004L,0x10001004L,0x00011004L,0x10011004L,\r0x20001000L,0x30001000L,0x20011000L,0x30011000L,\r0x20001004L,0x30001004L,0x20011004L,0x30011004L,\r0x00101000L,0x10101000L,0x00111000L,0x10111000L,\r0x00101004L,0x10101004L,0x00111004L,0x10111004L,\r0x20101000L,0x30101000L,0x20111000L,0x30111000L,\r0x20101004L,0x30101004L,0x20111004L,0x30111004L,\r},{\r/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */\r0x00000000L,0x08000000L,0x00000008L,0x08000008L,\r0x00000400L,0x08000400L,0x00000408L,0x08000408L,\r0x00020000L,0x08020000L,0x00020008L,0x08020008L,\r0x00020400L,0x08020400L,0x00020408L,0x08020408L,\r0x00000001L,0x08000001L,0x00000009L,0x08000009L,\r0x00000401L,0x08000401L,0x00000409L,0x08000409L,\r0x00020001L,0x08020001L,0x00020009L,0x08020009L,\r0x00020401L,0x08020401L,0x00020409L,0x08020409L,\r0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,\r0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,\r0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,\r0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,\r0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,\r0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,\r0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,\r0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,\r},{\r/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */\r0x00000000L,0x00000100L,0x00080000L,0x00080100L,\r0x01000000L,0x01000100L,0x01080000L,0x01080100L,\r0x00000010L,0x00000110L,0x00080010L,0x00080110L,\r0x01000010L,0x01000110L,0x01080010L,0x01080110L,\r0x00200000L,0x00200100L,0x00280000L,0x00280100L,\r0x01200000L,0x01200100L,0x01280000L,0x01280100L,\r0x00200010L,0x00200110L,0x00280010L,0x00280110L,\r0x01200010L,0x01200110L,0x01280010L,0x01280110L,\r0x00000200L,0x00000300L,0x00080200L,0x00080300L,\r0x01000200L,0x01000300L,0x01080200L,0x01080300L,\r0x00000210L,0x00000310L,0x00080210L,0x00080310L,\r0x01000210L,0x01000310L,0x01080210L,0x01080310L,\r0x00200200L,0x00200300L,0x00280200L,0x00280300L,\r0x01200200L,0x01200300L,0x01280200L,0x01280300L,\r0x00200210L,0x00200310L,0x00280210L,0x00280310L,\r0x01200210L,0x01200310L,0x01280210L,0x01280310L,\r},{\r/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */\r0x00000000L,0x04000000L,0x00040000L,0x04040000L,\r0x00000002L,0x04000002L,0x00040002L,0x04040002L,\r0x00002000L,0x04002000L,0x00042000L,0x04042000L,\r0x00002002L,0x04002002L,0x00042002L,0x04042002L,\r0x00000020L,0x04000020L,0x00040020L,0x04040020L,\r0x00000022L,0x04000022L,0x00040022L,0x04040022L,\r0x00002020L,0x04002020L,0x00042020L,0x04042020L,\r0x00002022L,0x04002022L,0x00042022L,0x04042022L,\r0x00000800L,0x04000800L,0x00040800L,0x04040800L,\r0x00000802L,0x04000802L,0x00040802L,0x04040802L,\r0x00002800L,0x04002800L,0x00042800L,0x04042800L,\r0x00002802L,0x04002802L,0x00042802L,0x04042802L,\r0x00000820L,0x04000820L,0x00040820L,0x04040820L,\r0x00000822L,0x04000822L,0x00040822L,0x04040822L,\r0x00002820L,0x04002820L,0x00042820L,0x04042820L,\r0x00002822L,0x04002822L,0x00042822L,0x04042822L,\r}};\r
\ No newline at end of file
diff --git a/mac/libdes/src/speed.c b/mac/libdes/src/speed.c
new file mode 100755 (executable)
index 0000000..0c4e181
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/speed.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/* 11-Sep-92 Andrew Daviel   Support for Silicon Graphics IRIX added */\r/* 06-Apr-92 Luke Brennan    Support for VMS and add extra signal calls */\r\r#ifdef HAVE_CONFIG_H\r#include <config.h>\r#endif\r\r#if !defined(MSDOS) && !defined(WIN32)\r#define TIMES\r#endif\r\r#include <stdio.h>\r#ifdef HAVE_UNISTD_H\r#include <unistd.h>\r#endif\r#include <signal.h>\r#ifdef HAVE_TIME_H\r#include <time.h>\r#endif\r#ifdef HAVE_SYS_TYPES_H\r#include <sys/types.h>\r#endif\r#ifdef HAVE_SYS_TIMES_H\r#include <sys/times.h>\r#endif\r\r#ifdef VMS\r#include <types.h>\rstruct tms {\r    time_t tms_utime;\r      time_t tms_stime;\r      time_t tms_uchild;      /* I dunno...  */\r      time_t tms_uchildsys;   /* so these names are a guess :-) */\r   }\r#endif\r\r#ifdef HAVE_SYS_TIMEB_H\r#include <sys/timeb.h>\r#endif\r\r#include <limits.h>\r#ifdef HAVE_SYS_PARAM_H\r#include <sys/param.h>\r#endif\r\r#include "des.h"\r\r/* The following if from times(3) man page.  It may need to be changed */\r#ifndef HZ\r#ifndef CLK_TCK\r#ifndef VMS\r#define HZ       100.0\r#else /* VMS */\r#define HZ        100.0\r#endif\r#else /* CLK_TCK */\r#define HZ ((double)CLK_TCK)\r#endif\r#endif\r\r#define BUFSIZE    ((long)1024)\rlong run=0;\r\r#ifndef NOPROTO\rdouble Time_F(int s);\r#else\rdouble Time_F();\r#endif\r\r#ifdef SIGALRM\r#if defined(__STDC__) || defined(sgi)\r#define SIGRETTYPE void\r#else\r#define SIGRETTYPE int\r#endif\r\r#ifndef NOPROTO\rSIGRETTYPE sig_done(int sig);\r#else\rSIGRETTYPE sig_done();\r#endif\r\rSIGRETTYPE sig_done(sig)\rint sig;\r  {\r      signal(SIGALRM,sig_done);\r      run=0;\r#ifdef LINT\r     sig=sig;\r#endif\r        }\r#endif\r\r#define START 0\r#define STOP  1\r\rdouble Time_F(s)\rint s;\r     {\r      double ret;\r#ifdef TIMES\r       static struct tms tstart,tend;\r\r        if (s == START)\r                {\r              times(&tstart);\r                return(0);\r             }\r      else\r           {\r              times(&tend);\r          ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;\r            return((ret == 0.0)?1e-6:ret);\r         }\r#else /* !times() */\r static struct timeb tstart,tend;\r       long i;\r\r       if (s == START)\r                {\r              ftime(&tstart);\r                return(0);\r             }\r      else\r           {\r              ftime(&tend);\r          i=(long)tend.millitm-(long)tstart.millitm;\r             ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;\r              return((ret == 0.0)?1e-6:ret);\r         }\r#endif\r       }\r\rint main(argc,argv)\rint argc;\rchar **argv;\r  {\r      long count;\r    static unsigned char buf[BUFSIZE];\r     static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};\r      static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};\r      static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};\r      des_key_schedule sch,sch2,sch3;\r        double a,b,c,d,e;\r#ifndef SIGALRM\r      long ca,cb,cc,cd,ce;\r#endif\r\r#ifndef TIMES\r     printf("To get the most acurate results, try to run this\n");\r  printf("program when this computer is idle.\n");\r#endif\r\r       des_set_key((C_Block *)key2,sch2);\r     des_set_key((C_Block *)key3,sch3);\r\r#ifndef SIGALRM\r    printf("First we calculate the approximate speed ...\n");\r      des_set_key((C_Block *)key,sch);\r       count=10;\r      do      {\r              long i;\r                DES_LONG data[2];\r\r             count*=2;\r              Time_F(START);\r         for (i=count; i; i--)\r                  des_encrypt(data,&(sch[0]),DES_ENCRYPT);\r               d=Time_F(STOP);\r                } while (d < 3.0);\r     ca=count;\r      cb=count*3;\r    cc=count*3*8/BUFSIZE+1;\r        cd=count*8/BUFSIZE+1;\r  ce=count/20+1;\r printf("Doing set_key %ld times\n",ca);\r#define COND(d) (count != (d))\r#define COUNT(d) (d)\r#else\r#define COND(c)       (run)\r#define COUNT(d) (count)\r signal(SIGALRM,sig_done);\r      printf("Doing set_key for 10 seconds\n");\r      alarm(10);\r#endif\r\r     Time_F(START);\r for (count=0,run=1; COND(ca); count++)\r         des_set_key((C_Block *)key,sch);\r       d=Time_F(STOP);\r        printf("%ld set_key's in %.2f seconds\n",count,d);\r     a=((double)COUNT(ca))/d;\r\r#ifdef SIGALRM\r       printf("Doing des_encrypt's for 10 seconds\n");\r        alarm(10);\r#else\r       printf("Doing des_encrypt %ld times\n",cb);\r#endif\r     Time_F(START);\r for (count=0,run=1; COND(cb); count++)\r         {\r              DES_LONG data[2];\r\r             des_encrypt(data,&(sch[0]),DES_ENCRYPT);\r               }\r      d=Time_F(STOP);\r        printf("%ld des_encrypt's in %.2f second\n",count,d);\r  b=((double)COUNT(cb)*8)/d;\r\r#ifdef SIGALRM\r     printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",\r            BUFSIZE);\r      alarm(10);\r#else\r       printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,\r              BUFSIZE);\r#endif\r       Time_F(START);\r for (count=0,run=1; COND(cc); count++)\r         des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),\r                      (C_Block *)&(key[0]),DES_ENCRYPT);\r     d=Time_F(STOP);\r        printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",\r            count,BUFSIZE,d);\r      c=((double)COUNT(cc)*BUFSIZE)/d;\r\r#ifdef SIGALRM\r       printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",\r                BUFSIZE);\r      alarm(10);\r#else\r       printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,\r          BUFSIZE);\r#endif\r       Time_F(START);\r for (count=0,run=1; COND(cd); count++)\r         des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,\r                    &(sch[0]),\r                     &(sch2[0]),\r                    &(sch3[0]),\r                    (C_Block *)&(key[0]),\r                  DES_ENCRYPT);\r  d=Time_F(STOP);\r        printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",\r                count,BUFSIZE,d);\r      d=((double)COUNT(cd)*BUFSIZE)/d;\r\r#ifdef SIGALRM\r       printf("Doing crypt for 10 seconds\n");\r        alarm(10);\r#else\r       printf("Doing crypt %ld times\n",ce);\r#endif\r   Time_F(START);\r for (count=0,run=1; COND(ce); count++)\r         crypt("testing1","ef");\r        e=Time_F(STOP);\r        printf("%ld crypts in %.2f second\n",count,e);\r e=((double)COUNT(ce))/e;\r\r      printf("set_key            per sec = %12.2f (%5.1fuS)\n",a,1.0e6/a);\r   printf("DES raw ecb bytes  per sec = %12.2f (%5.1fuS)\n",b,8.0e6/b);\r   printf("DES cbc bytes      per sec = %12.2f (%5.1fuS)\n",c,8.0e6/c);\r   printf("DES ede cbc bytes  per sec = %12.2f (%5.1fuS)\n",d,8.0e6/d);\r   printf("crypt              per sec = %12.2f (%5.1fuS)\n",e,1.0e6/e);\r   exit(0);\r#if defined(LINT) || defined(MSDOS)\r   return(0);\r#endif\r      }\r
\ No newline at end of file
diff --git a/mac/libdes/src/spr.h b/mac/libdes/src/spr.h
new file mode 100755 (executable)
index 0000000..2718e51
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/spr.h */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\rconst DES_LONG des_SPtrans[8][64]={\r{\r/* nibble 0 */\r0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,\r0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,\r0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,\r0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,\r0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,\r0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,\r0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,\r0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,\r0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,\r0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,\r0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,\r0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,\r0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,\r0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,\r0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,\r0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,\r},{\r/* nibble 1 */\r0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,\r0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,\r0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,\r0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,\r0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,\r0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,\r0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,\r0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,\r0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,\r0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,\r0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,\r0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,\r0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,\r0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,\r0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,\r0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,\r},{\r/* nibble 2 */\r0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,\r0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,\r0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,\r0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,\r0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,\r0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,\r0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,\r0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,\r0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,\r0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,\r0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,\r0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,\r0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,\r0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,\r0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,\r0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,\r},{\r/* nibble 3 */\r0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,\r0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,\r0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,\r0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,\r0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,\r0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,\r0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,\r0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,\r0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,\r0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,\r0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,\r0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,\r0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,\r0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,\r0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,\r0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,\r},{\r/* nibble 4 */\r0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,\r0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,\r0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,\r0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,\r0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,\r0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,\r0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,\r0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,\r0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,\r0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,\r0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,\r0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,\r0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,\r0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,\r0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,\r0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,\r},{\r/* nibble 5 */\r0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,\r0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,\r0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,\r0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,\r0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,\r0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,\r0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,\r0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,\r0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,\r0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,\r0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,\r0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,\r0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,\r0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,\r0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,\r0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,\r},{\r/* nibble 6 */\r0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,\r0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,\r0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,\r0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,\r0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,\r0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,\r0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,\r0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,\r0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,\r0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,\r0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,\r0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,\r0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,\r0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,\r0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,\r0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,\r},{\r/* nibble 7 */\r0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,\r0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,\r0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,\r0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,\r0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,\r0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,\r0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,\r0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,\r0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,\r0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,\r0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,\r0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,\r0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,\r0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,\r0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,\r0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,\r}};\r
\ No newline at end of file
diff --git a/mac/libdes/src/str2key.c b/mac/libdes/src/str2key.c
new file mode 100755 (executable)
index 0000000..86366b6
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/str2key.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\rextern int des_check_key;\r\rvoid des_string_to_key(str, key)\rchar *str;\rdes_cblock (*key);\r      {\r      des_key_schedule ks;\r   int i,length;\r  register unsigned char j;\r\r     memset(key,0,8);\r       length=strlen(str);\r#ifdef OLD_STR_TO_KEY\r      for (i=0; i<length; i++)\r               (*key)[i%8]^=(str[i]<<1);\r#else /* MIT COMPATIBLE */\r   for (i=0; i<length; i++)\r               {\r              j=str[i];\r              if ((i%16) < 8)\r                        (*key)[i%8]^=(j<<1);\r           else\r                   {\r                      /* Reverse the bit order 05/05/92 eay */\r                       j=((j<<4)&0xf0)|((j>>4)&0x0f);\r                 j=((j<<2)&0xcc)|((j>>2)&0x33);\r                 j=((j<<1)&0xaa)|((j>>1)&0x55);\r                 (*key)[7-(i%8)]^=j;\r                    }\r              }\r#endif\r       des_set_odd_parity((des_cblock *)key);\r i=des_check_key;\r       des_check_key=0;\r       des_set_key((des_cblock *)key,ks);\r     des_check_key=i;\r       des_cbc_cksum((des_cblock *)str,(des_cblock *)key,(long)length,ks,\r             (des_cblock *)key);\r    memset(ks,0,sizeof(ks));\r       des_set_odd_parity((des_cblock *)key);\r }\r\rvoid des_string_to_2keys(str, key1, key2)\rchar *str;\rdes_cblock (*key1);\rdes_cblock (*key2);\r        {\r      des_key_schedule ks;\r   int i,length;\r  register unsigned char j;\r\r     memset(key1,0,8);\r      memset(key2,0,8);\r      length=strlen(str);\r#ifdef OLD_STR_TO_KEY\r      if (length <= 8)\r               {\r              for (i=0; i<length; i++)\r                       {\r                      (*key2)[i]=(*key1)[i]=(str[i]<<1);\r                     }\r              }\r      else\r           {\r              for (i=0; i<length; i++)\r                       {\r                      if ((i/8)&1)\r                           (*key2)[i%8]^=(str[i]<<1);\r                     else\r                           (*key1)[i%8]^=(str[i]<<1);\r                     }\r              }\r#else /* MIT COMPATIBLE */\r   for (i=0; i<length; i++)\r               {\r              j=str[i];\r              if ((i%32) < 16)\r                       {\r                      if ((i%16) < 8)\r                                (*key1)[i%8]^=(j<<1);\r                  else\r                           (*key2)[i%8]^=(j<<1);\r                  }\r              else\r                   {\r                      j=((j<<4)&0xf0)|((j>>4)&0x0f);\r                 j=((j<<2)&0xcc)|((j>>2)&0x33);\r                 j=((j<<1)&0xaa)|((j>>1)&0x55);\r                 if ((i%16) < 8)\r                                (*key1)[7-(i%8)]^=j;\r                   else\r                           (*key2)[7-(i%8)]^=j;\r                   }\r              }\r      if (length <= 8) memcpy(key2,key1,8);\r#endif\r   des_set_odd_parity((des_cblock *)key1);\r        des_set_odd_parity((des_cblock *)key2);\r        i=des_check_key;\r       des_check_key=0;\r       des_set_key((des_cblock *)key1,ks);\r    des_cbc_cksum((des_cblock *)str,(des_cblock *)key1,(long)length,ks,\r            (des_cblock *)key1);\r   des_set_key((des_cblock *)key2,ks);\r    des_cbc_cksum((des_cblock *)str,(des_cblock *)key2,(long)length,ks,\r            (des_cblock *)key2);\r   des_check_key=i;\r       memset(ks,0,sizeof(ks));\r       des_set_odd_parity(key1);\r      des_set_odd_parity(key2);\r      }\r
\ No newline at end of file
diff --git a/mac/libdes/src/supp.c b/mac/libdes/src/supp.c
new file mode 100755 (executable)
index 0000000..5ea6631
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/supp.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r/*\r * Copyright (c) 1995\r *       Mark Murray.  All rights reserved.\r *\r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the above copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    This product includes software developed by Mark Murray\r * 4. Neither the name of the author nor the names of any co-contributors\r *    may be used to endorse or promote products derived from this software\r *    without specific prior written permission.\r *\r * THIS SOFTWARE IS PROVIDED BY MARK MURRAY AND CONTRIBUTORS ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r *\r * $Id: supp.c,v 1.2 2001/12/04 02:06:32 rjs3 Exp $\r */\r\r#include <stdio.h>\r#include "des_locl.h"\r\rvoid des_cblock_print_file(cb, fp)\r        des_cblock *cb;\r        FILE *fp;\r{\r    int i;\r unsigned int *p = (unsigned int *)cb;\r\r fprintf(fp, " 0x { ");\r for (i = 0; i < 8; i++) {\r              fprintf(fp, "%x", p[i]);\r               if (i != 7) fprintf(fp, ", ");\r }\r      fprintf(fp, " }");\r}\r
\ No newline at end of file
diff --git a/mac/libdes/src/testdes.pl b/mac/libdes/src/testdes.pl
new file mode 100755 (executable)
index 0000000..16c4172
--- /dev/null
@@ -0,0 +1 @@
+#!/usr/local/bin/perl\r\r# des.pl tesing code\r\rrequire 'des.pl';\r\r$num_tests=34;\r@key_data=(\r    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\r       0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\r       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,\r       0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57,\r       0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E,\r       0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86,\r       0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E,\r       0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6,\r       0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE,\r       0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6,\r       0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE,\r       0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16,\r       0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F,\r       0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46,\r       0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E,\r       0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76,\r       0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07,\r       0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F,\r       0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7,\r       0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF,\r       0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6,\r       0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF,\r       0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,\r       0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E,\r       0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE,\r       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10,\r       );\r\r@plain_data=(\r      0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\r       0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01,\r       0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\r       0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42,\r       0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA,\r       0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72,\r       0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A,\r       0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2,\r       0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A,\r       0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2,\r       0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A,\r       0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02,\r       0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A,\r       0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32,\r       0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA,\r       0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62,\r       0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2,\r       0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA,\r       0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92,\r       0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A,\r       0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2,\r       0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,\r       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,\r       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\r       0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);\r\r@cipher_data=(\r      0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7,\r       0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58,\r       0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B,\r       0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33,\r       0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D,\r       0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD,\r       0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7,\r       0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4,\r       0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B,\r       0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71,\r       0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A,\r       0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A,\r       0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95,\r       0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B,\r       0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09,\r       0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A,\r       0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F,\r       0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88,\r       0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77,\r       0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A,\r       0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56,\r       0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56,\r       0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56,\r       0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC,\r       0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A,\r       0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41,\r       0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93,\r       0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00,\r       0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06,\r       0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7,\r       0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51,\r       0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE,\r       0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D,\r       0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2);\r\rprint "Doing ecb tests\n";\rfor ($i=0; $i<$num_tests; $i++)\r  {\r      printf "Doing test $i\n";\r      $key =pack("C8",splice(@key_data   ,0,8));\r     $data=pack("C8",splice(@plain_data ,0,8));\r     $res =pack("C8",splice(@cipher_data,0,8));\r\r    @ks=  &des_set_key($key);\r      $out1= &des_ecb_encrypt(*ks,1,$data);\r  $out2= &des_ecb_encrypt(*ks,0,$out1);\r  $out3= &des_ecb_encrypt(*ks,0,$res);\r   &eprint("encryption failure",$res,$out1)\r               if ($out1 ne $res);\r    &eprint("encryption/decryption failure",$data,$out2)\r           if ($out2 ne $data);\r   &eprint("decryption failure",$data,$out3)\r              if ($data ne $out3);\r   }\rprint "Done\n";\r\rprint "doing speed test over 30 seconds\n";\r$SIG{'ALRM'}='done';\rsub done {$done=1;}\r$done=0;\r\r$count=0;\r$d=pack("C8",0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef);\r@ks=  &des_set_key($d);\ralarm(30);\r$start=(times)[0];\rwhile (!$done)\r        {\r      $count++;\r      $d=&des_ecb_encrypt(*ks,1,$d);\r }\r$end=(times)[0];\r$t=$end-$start;\rprintf "$count DESs in %.2f seconds is %.2f DESs/sec or %.2f bytes/sec\n",\r  1.0*$t,1.0*$count/$t,$count*8.0/$t;\r\rsub eprint\r        {\r      local($s,$c,$e)=@_;\r    local(@k);\r\r    @k=unpack("C8",$c);\r    printf "%02x%02x%02x%02x %02x%02x%02x%02x - ",unpack("C8",$c);\r printf "%02x%02x%02x%02x %02x%02x%02x%02x :",unpack("C8",$e);\r  print " $s\n";\r }\r
\ No newline at end of file
diff --git a/mac/libdes/src/times b/mac/libdes/src/times
new file mode 100755 (executable)
index 0000000..9a24983
--- /dev/null
@@ -0,0 +1 @@
+existing library on a DEC 3000/500\rset_key            per sec =    256294.06 (  3.9uS)\rDES ecb bytes      per sec =   3553694.40 (  2.3uS)\rDES cbc bytes      per sec =   3661004.80 (  2.2uS)\rDES ede cbc bytes  per sec =   1353115.99 (  5.9uS)\rcrypt              per sec =     16829.40 ( 59.4uS)\r\rIntel P6/200 (NEXTSTEP) - cc -O3 (cc: gcc 2.5.8)\rset_key            per sec =    219220.82 (  4.6uS)\rDES ecb bytes      per sec =   2438014.04 (  3.3uS)\rDES cbc bytes      per sec =   2467648.85 (  3.2uS)\rDES ede cbc bytes  per sec =    942121.58 (  8.5uS)\rcrypt              per sec =     11398.73 ( 87.7uS)\r\r# DECstation Alpha 3000 Model 700 AXP / OSF1 V3.0\r# gcc 2.6.3 / Young libdes 3.21\rset_key            per sec =    149369.74 (  6.7uS)\rDES ecb bytes      per sec =   2011976.68 (  4.0uS)\rDES cbc bytes      per sec =   2002245.35 (  4.0uS)\rDES ede cbc bytes  per sec =    793677.19 ( 10.1uS)\rcrypt              per sec =      9244.52 (108.2uS)\r\r# Sun Ultra I gcc 2.7.2 / Young libdes 3.21\rset_key            per sec =    147172.22 (  6.8uS)\rDES ecb bytes      per sec =   1815054.70 (  4.4uS)\rDES cbc bytes      per sec =   1829405.18 (  4.4uS)\rDES ede cbc bytes  per sec =    714490.23 ( 11.2uS)\rcrypt              per sec =      8896.24 (112.4uS)\r\rSGI Challenge (MIPS R4400 200mhz) - gcc -O2\rset_key       per sec =    114141.13 (  8.8uS)\rDES ecb bytes per sec =   1573472.84 (  5.1uS)\rDES cbc bytes per sec =   1580418.20 (  5.1uS)\rcrypt         per sec =      7137.84 (140.1uS)\r\rDEC Alpha DEC  4000/710 AXP OSF/1 v 3.0 - gcc -O2 2.6.1\rset_key       per sec =    123138.49 (  8.1uS)\rDES ecb bytes per sec =   1407546.76 (  5.7uS)\rDES cbc bytes per sec =   1404103.21 (  5.7uS)\rcrypt         per sec =      7746.76 (129.1uS)\r\rDEC Alpha DEC  4000/710 AXP OSF/1 v 3.0 - cc -O4 'DEC Compiler Driver 3.11'\rset_key       per sec =    135160.83 (  7.4uS)\rDES ecb bytes per sec =   1267753.22 (  6.3uS)\rDES cbc bytes per sec =   1260564.90 (  6.3uS)\rcrypt         per sec =      6479.37 (154.3uS)\r\rSGI Challenge (MIPS R4400 200mhz) - cc -O2\rset_key       per sec =    124000.10 (  8.1uS)\rDES ecb bytes per sec =   1338138.45 (  6.0uS)\rDES cbc bytes per sec =   1356515.84 (  5.9uS)\rcrypt         per sec =      6223.92 (160.7uS)\r\rIntel P5/133 (NEXTSTEP) - cc -O3 (cc: gcc 2.5.8)\rset_key            per sec =     81923.10 ( 12.2uS)\rDES ecb bytes      per sec =   1104711.61 (  7.2uS)\rDES cbc bytes      per sec =   1091536.05 (  7.3uS)\rDES ede cbc bytes  per sec =    410502.62 ( 19.5uS)\rcrypt              per sec =      4849.60 (206.2uS)\r\rSun SPARC 20 (NEXTSTEP) - cc -O3 (cc: gcc 2.5.8)\rset_key            per sec =     60973.05 ( 16.4uS)\rDES ecb bytes      per sec =    806032.15 (  9.9uS)\rDES cbc bytes      per sec =    801534.95 ( 10.0uS)\rDES ede cbc bytes  per sec =    298799.73 ( 26.8uS)\rcrypt              per sec =      3678.42 (271.9uS)\r\rSGI Indy (MIPS R4600 133mhz) -cc -O2\rset_key       per sec =     88470.54 ( 11.3uS)\rDES ecb bytes per sec =   1023040.33 (  7.8uS)\rDES cbc bytes per sec =   1033610.01 (  7.7uS)\rcrypt         per sec =      4641.51 (215.4uS)\r\rHP-UX 9000/887 cc +O3\rset_key       per sec =     76824.30 ( 13.0uS)\rDES ecb bytes per sec =   1048911.20 (  7.6uS)\rDES cbc bytes per sec =   1072332.80 (  7.5uS)\rcrypt         per sec =      4968.64 (201.3uS)\r\rIRIX 5.2 IP22 (R4000) cc -O2 (galilo)\rset_key       per sec =     60615.73 ( 16.5uS)\rDES ecb bytes per sec =    584741.32 ( 13.7uS)\rDES cbc bytes per sec =    584306.94 ( 13.7uS)\rcrypt         per sec =      3049.33 (327.9uS)\r\rHP-UX 9000/867 cc -O\rset_key       per sec =     48600.00 ( 20.6uS)\rDES ecb bytes per sec =    616235.14 ( 13.0uS)\rDES cbc bytes per sec =    638669.44 ( 12.5uS)\rcrypt         per sec =      3016.68 (331.5uS)\r\rHP-UX 9000/867 gcc -O2\rset_key       per sec =     52120.50 ( 19.2uS)\rDES ecb bytes per sec =    715156.55 ( 11.2uS)\rDES cbc bytes per sec =    724424.28 ( 11.0uS)\rcrypt         per sec =      3295.87 (303.4uS)\r\rDGUX AViiON mc88110 gcc -O2\rset_key       per sec =     55604.91 ( 18.0uS)\rDES ecb bytes per sec =    658513.25 ( 12.1uS)\rDES cbc bytes per sec =    675552.71 ( 11.8uS)\rcrypt         per sec =      3438.10 (290.9uS)\r\rSparc 10 cc -O2 (orb)\rset_key       per sec =     53002.30 ( 18.9uS)\rDES ecb bytes per sec =    705250.40 ( 11.3uS)\rDES cbc bytes per sec =    714342.40 ( 11.2uS)\rcrypt         per sec =      2943.99 (339.7uS)\r\rSparc 10 gcc -O2 (orb)\rset_key       per sec =     58681.21 ( 17.0uS)\rDES ecb bytes per sec =    772390.20 ( 10.4uS)\rDES cbc bytes per sec =    774144.00 ( 10.3uS)\rcrypt         per sec =      3606.90 (277.2uS)\r\rDEC Alpha DEC  4000/610 AXP OSF/1 v 1.3 - gcc v 2.3.3\rset_key       per sec =    101840.19 (  9.8uS)\rDES ecb bytes per sec =   1223712.35 (  6.5uS)\rDES cbc bytes per sec =   1230542.98 (  6.5uS)\rcrypt         per sec =      6428.75 (155.6uS)\r\rDEC Alpha DEC 4000/610 APX OSF/1 v 1.3 - cc -O2 - OSF/1 AXP\rset_key       per sec =    114198.91 (  8.8uS)\rDES ecb bytes per sec =   1022710.93 (  7.8uS)\rDES cbc bytes per sec =   1008821.93 (  7.9uS)\rcrypt         per sec =      5454.13 (183.3uS)\r\rDEC Alpha - DEC 3000/500 AXP OSF/1 - cc -O2 - 02/12/92\rset_key       per sec =     83587.04 ( 12.0uS)\rDES ecb bytes per sec =    822620.82 (  9.7uS)\rDES cbc bytes per sec =    832929.60 (  9.6uS)\rcrypt         per sec =      4807.62 (208.0uS)\r\rsun sparc 10/30 - gcc -O2\rset_key       per sec =     42005.24 ( 23.8uS)\rDES ecb bytes per sec =    555949.47 ( 14.4uS)\rDES cbc bytes per sec =    549440.28 ( 14.6uS)\rcrypt         per sec =      2580.25 (387.6uS)\r\rPA-RISC 1.1 HP 710\rset_key       per sec =     38916.86\rDES ecb bytes per sec =    505971.82\rDES cbc bytes per sec =    515381.13\rcrypt         per sec =      2438.24\r\riris (spike) cc -O2\rset_key       per sec =     23128.83 ( 43.2uS)\rDES ecb bytes per sec =    261577.94 ( 30.6uS)\rDES cbc bytes per sec =    261746.41 ( 30.6uS)\rcrypt         per sec =      1231.76 (811.8uS)\r\rsun sparc 10/30 - cc -O4\rset_key       per sec =     38379.86 ( 26.1uS)\rDES ecb bytes per sec =    460051.34 ( 17.4uS)\rDES cbc bytes per sec =    464970.54 ( 17.2uS)\rcrypt         per sec =      2092.64 (477.9uS)\r\rsun sparc 2 - gcc2 -O2\rset_key       per sec =     21559.10\rDES ecb bytes per sec =    305566.92\rDES cbc bytes per sec =    303497.50\rcrypt         per sec =      1410.48\r\rRS/6000 model 320\rset_key       per sec =     14371.93\rDES ecb bytes per sec =    222231.26\rDES cbc bytes per sec =    223926.79\rcrypt         per sec =       981.20\r\r80486dx/66MHz Solaris 2.1 - gcc -O2 (gcc 2.6.3)\rset_key       per sec =     26814.15 ( 37.3uS)\rDES ecb bytes per sec =    345029.95 ( 23.2uS)\rDES cbc bytes per sec =    344064.00 ( 23.3uS)\rcrypt         per sec =      1551.97 (644.3uS)\r\r80486dx/50MHz Solaris 2.1 - gcc -O2 (gcc 2.5.2)\rset_key       per sec =     18558.29 ( 53.9uS)\rDES ecb bytes per sec =    240873.90 ( 33.2uS)\rDES cbc bytes per sec =    239993.37 ( 33.3uS)\rcrypt         per sec =      1073.67 (931.4uS)\r\r80486dx/50MHz Solaris 2.1 - cc -xO4 (cc: PC2.0.1 30 April 1993)\rset_key       per sec =     18302.79 ( 54.6uS)\rDES ecb bytes per sec =    242640.29 ( 33.0uS)\rDES cbc bytes per sec =    239568.89 ( 33.4uS)\rcrypt         per sec =      1057.92 (945.2uS)\r\r68030 HP400\rset_key       per sec =      5251.28\rDES ecb bytes per sec =     56186.56\rDES cbc bytes per sec =     58681.53\rcrypt         per sec =       276.15\r\r80486sx/33MHz MSDOS Turbo C v 2.0\rset_key       per sec =      1883.22 (531.0uS)\rDES ecb bytes per sec =     63393.31 (126.2uS)\rDES cbc bytes per sec =     63416.83 (126.1uS)\rcrypt         per sec =       158.71 (6300.6uS)\r\r80486sx/33MHz MSDOS djgpp gcc 1.39 (32bit compiler)\rset_key       per sec =     12603.08 (79.3)\rDES ecb bytes per sec =    158875.15 (50.4)\rDES cbc bytes per sec =    159893.85 (50.0)\rcrypt         per sec =       780.24 (1281.7)\r\rVersion 1.99 26/08/92\r8MHz 68000 Atari-ST gcc 2.1 -O2 MiNT 0.94\rset_key       per sec =       325.68 (3070.5uS)\rDES ecb bytes per sec =      4173.67 (1916.8uS)\rDES cbc bytes per sec =      4249.89 (1882.4uS)\rcrypt         per sec =        20.19 (49521.6uS)\r\r8088/4.77mh MSDOS Turbo C v 2.0\rset_key       per sec =        35.09\rDES ecb bytes per sec =       563.63\rcrypt         per sec =         2.69\r
\ No newline at end of file
diff --git a/mac/libdes/src/typemap b/mac/libdes/src/typemap
new file mode 100755 (executable)
index 0000000..1b4d07b
--- /dev/null
@@ -0,0 +1 @@
+#\r# DES SECTION\r#\rdeschar *    T_DESCHARP\rdes_cblock * T_CBLOCK\rdes_cblock     T_CBLOCK\rdes_key_schedule       T_SCHEDULE\rdes_key_schedule *   T_SCHEDULE\r\rINPUT\rT_CBLOCK\r     $var=(des_cblock *)SvPV($arg,len);\r     if (len < DES_KEY_SZ)\r          {\r              croak(\"$var needs to be at least %u bytes long\",DES_KEY_SZ);\r         }\r\rT_SCHEDULE\r  $var=(des_key_schedule *)SvPV($arg,len);\r       if (len < DES_SCHEDULE_SZ)\r             {\r              croak(\"$var needs to be at least %u bytes long\",\r                     DES_SCHEDULE_SZ);\r              }\r\rOUTPUT\rT_CBLOCK\r     sv_setpvn($arg,(char *)$var,DES_KEY_SZ);\r\rT_SCHEDULE\r   sv_setpvn($arg,(char *)$var,DES_SCHEDULE_SZ);\r\rT_DESCHARP\r      sv_setpvn($arg,(char *)$var,len);\r
\ No newline at end of file
diff --git a/mac/libdes/src/version.h b/mac/libdes/src/version.h
new file mode 100755 (executable)
index 0000000..4674d83
--- /dev/null
@@ -0,0 +1 @@
+/* lib/des/version.h */\r/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r * \r * This file is part of an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL\r * specification.  This library and applications are\r * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE\r * as long as the following conditions are aheared to.\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.  If this code is used in a product,\r * Eric Young should be given attribution as the author of the parts used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    This product includes software developed by Eric Young (eay@mincom.oz.au)\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\rextern char *DES_version;\r
\ No newline at end of file
diff --git a/mac/libdes/src/vms.com b/mac/libdes/src/vms.com
new file mode 100755 (executable)
index 0000000..885ea8e
--- /dev/null
@@ -0,0 +1,90 @@
+$! --- VMS.com ---
+$!
+$ GoSub defines
+$ GoSub linker_options
+$ If (P1 .nes. "")
+$ Then 
+$   GoSub 'P1'
+$ Else
+$   GoSub lib
+$   GoSub destest
+$   GoSub rpw
+$   GoSub speed
+$   GoSub des
+$ EndIF
+$!
+$ Exit
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$DEFINES:
+$ OPT_FILE := "VAX_LINKER_OPTIONS.OPT"
+$!
+$ CC_OPTS := "/NODebug/OPTimize/NOWarn"
+$!
+$ LINK_OPTS := "/NODebug/NOTraceback/Contiguous"
+$!
+$ OBJS  = "cbc_cksm.obj,cbc_enc.obj,ecb_enc.obj,pcbc_enc.obj," + -
+          "qud_cksm.obj,rand_key.obj,read_pwd.obj,set_key.obj,"      + -
+          "str2key.obj,enc_read.obj,enc_writ.obj,fcrypt.obj,"           + -
+         "cfb_enc.obj,3ecb_enc.obj,ofb_enc.obj"
+          
+          
+$!
+$ LIBDES = "cbc_cksm.c,cbc_enc.c,ecb_enc.c,enc_read.c,"           + -
+           "enc_writ.c,pcbc_enc.c,qud_cksm.c,rand_key.c,"         + -
+           "read_pwd.c,set_key.c,str2key.c,fcrypt.c,"                + -
+          "cfb_enc.c,3ecb_enc.c,ofb_enc.c"
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$LINKER_OPTIONS:
+$ If (f$search(OPT_FILE) .eqs. "")
+$ Then
+$   Create 'OPT_FILE'
+$DECK
+! Default system options file to link against the sharable C runtime library
+!
+Sys$Share:VAXcRTL.exe/Share
+$EOD
+$ EndIF
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$LIB:
+$ CC 'CC_OPTS' 'LIBDES'
+$ If (f$search("LIBDES.OLB") .nes. "")
+$ Then Library /Object /Replace libdes 'OBJS'
+$ Else Library /Create /Object  libdes 'OBJS'
+$ EndIF
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$DESTEST:
+$ CC 'CC_OPTS' destest
+$ Link 'link_opts' /Exec=destest destest.obj,libdes/LIBRARY,'opt_file'/Option
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$RPW:
+$ CC 'CC_OPTS' rpw
+$ Link 'link_opts' /Exec=rpw  rpw.obj,libdes/LIBRARY,'opt_file'/Option
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$SPEED:
+$ CC 'CC_OPTS' speed
+$ Link 'link_opts' /Exec=speed speed.obj,libdes/LIBRARY,'opt_file'/Option
+$ Return
+$!
+$!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+$!
+$DES:
+$ CC 'CC_OPTS' des
+$ Link 'link_opts' /Exec=des des.obj,libdes/LIBRARY,'opt_file'/Option
+$ Return
diff --git a/mac/libdes/src/xcbc_enc.c b/mac/libdes/src/xcbc_enc.c
new file mode 100755 (executable)
index 0000000..62645b9
--- /dev/null
@@ -0,0 +1 @@
+/* crypto/des/xcbc_enc.c */\r/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)\r * All rights reserved.\r *\r * This package is an SSL implementation written\r * by Eric Young (eay@mincom.oz.au).\r * The implementation was written so as to conform with Netscapes SSL.\r * \r * This library is free for commercial and non-commercial use as long as\r * the following conditions are aheared to.  The following conditions\r * apply to all code found in this distribution, be it the RC4, RSA,\r * lhash, DES, etc., code; not just the SSL code.  The SSL documentation\r * included with this distribution is covered by the same copyright terms\r * except that the holder is Tim Hudson (tjh@mincom.oz.au).\r * \r * Copyright remains Eric Young's, and as such any Copyright notices in\r * the code are not to be removed.\r * If this package is used in a product, Eric Young should be given attribution\r * as the author of the parts of the library used.\r * This can be in the form of a textual message at program startup or\r * in documentation (online or textual) provided with the package.\r * \r * Redistribution and use in source and binary forms, with or without\r * modification, are permitted provided that the following conditions\r * are met:\r * 1. Redistributions of source code must retain the copyright\r *    notice, this list of conditions and the following disclaimer.\r * 2. Redistributions in binary form must reproduce the above copyright\r *    notice, this list of conditions and the following disclaimer in the\r *    documentation and/or other materials provided with the distribution.\r * 3. All advertising materials mentioning features or use of this software\r *    must display the following acknowledgement:\r *    "This product includes cryptographic software written by\r *     Eric Young (eay@mincom.oz.au)"\r *    The word 'cryptographic' can be left out if the rouines from the library\r *    being used are not cryptographic related :-).\r * 4. If you include any Windows specific code (or a derivative thereof) from \r *    the apps directory (application code) you must include an acknowledgement:\r *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"\r * \r * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND\r * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\r * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r * SUCH DAMAGE.\r * \r * The licence and distribution terms for any publically available version or\r * derivative of this code cannot be changed.  i.e. this code cannot simply be\r * copied and put under another distribution licence\r * [including the GNU Public Licence.]\r */\r\r#include "des_locl.h"\r\r/* RSA's DESX */\r\rstatic unsigned char desx_white_in2out[256]={\r0xBD,0x56,0xEA,0xF2,0xA2,0xF1,0xAC,0x2A,0xB0,0x93,0xD1,0x9C,0x1B,0x33,0xFD,0xD0,\r0x30,0x04,0xB6,0xDC,0x7D,0xDF,0x32,0x4B,0xF7,0xCB,0x45,0x9B,0x31,0xBB,0x21,0x5A,\r0x41,0x9F,0xE1,0xD9,0x4A,0x4D,0x9E,0xDA,0xA0,0x68,0x2C,0xC3,0x27,0x5F,0x80,0x36,\r0x3E,0xEE,0xFB,0x95,0x1A,0xFE,0xCE,0xA8,0x34,0xA9,0x13,0xF0,0xA6,0x3F,0xD8,0x0C,\r0x78,0x24,0xAF,0x23,0x52,0xC1,0x67,0x17,0xF5,0x66,0x90,0xE7,0xE8,0x07,0xB8,0x60,\r0x48,0xE6,0x1E,0x53,0xF3,0x92,0xA4,0x72,0x8C,0x08,0x15,0x6E,0x86,0x00,0x84,0xFA,\r0xF4,0x7F,0x8A,0x42,0x19,0xF6,0xDB,0xCD,0x14,0x8D,0x50,0x12,0xBA,0x3C,0x06,0x4E,\r0xEC,0xB3,0x35,0x11,0xA1,0x88,0x8E,0x2B,0x94,0x99,0xB7,0x71,0x74,0xD3,0xE4,0xBF,\r0x3A,0xDE,0x96,0x0E,0xBC,0x0A,0xED,0x77,0xFC,0x37,0x6B,0x03,0x79,0x89,0x62,0xC6,\r0xD7,0xC0,0xD2,0x7C,0x6A,0x8B,0x22,0xA3,0x5B,0x05,0x5D,0x02,0x75,0xD5,0x61,0xE3,\r0x18,0x8F,0x55,0x51,0xAD,0x1F,0x0B,0x5E,0x85,0xE5,0xC2,0x57,0x63,0xCA,0x3D,0x6C,\r0xB4,0xC5,0xCC,0x70,0xB2,0x91,0x59,0x0D,0x47,0x20,0xC8,0x4F,0x58,0xE0,0x01,0xE2,\r0x16,0x38,0xC4,0x6F,0x3B,0x0F,0x65,0x46,0xBE,0x7E,0x2D,0x7B,0x82,0xF9,0x40,0xB5,\r0x1D,0x73,0xF8,0xEB,0x26,0xC7,0x87,0x97,0x25,0x54,0xB1,0x28,0xAA,0x98,0x9D,0xA5,\r0x64,0x6D,0x7A,0xD4,0x10,0x81,0x44,0xEF,0x49,0xD6,0xAE,0x2E,0xDD,0x76,0x5C,0x2F,\r0xA7,0x1C,0xC9,0x09,0x69,0x9A,0x83,0xCF,0x29,0x39,0xB9,0xE9,0x4C,0xFF,0x43,0xAB,\r       };\r\rvoid des_xwhite_in2out(des_key,in_white,out_white)\rdes_cblock (*des_key);\rdes_cblock (*in_white);\rdes_cblock (*out_white);\r {\r      unsigned char *key,*in,*out;\r   int out0,out1;\r int i;\r\r        key=(unsigned char *)des_key;\r  in=(unsigned char *)in_white;\r  out=(unsigned char *)out_white;\r\r       out[0]=out[1]=out[2]=out[3]=out[4]=out[5]=out[6]=out[7]=0;\r     out0=out1=0;\r   for (i=0; i<8; i++)\r            {\r              out[i]=key[i]^desx_white_in2out[out0^out1];\r            out0=out1;\r             out1=(int)out[i&0x07];\r         }\r\r     out0=out[0];\r   out1=out[i];\r   for (i=0; i<8; i++)\r            {\r              out[i]=in[i]^desx_white_in2out[out0^out1];\r             out0=out1;\r             out1=(int)out[i&0x07];\r         }\r      }\r\rvoid des_xcbc_encrypt(input, output, length, schedule, ivec, inw,outw,encrypt)\rdes_cblock (*input);\rdes_cblock (*output);\rlong length;\rdes_key_schedule schedule;\rdes_cblock (*ivec);\rdes_cblock (*inw);\rdes_cblock (*outw);\rint encrypt;\r   {\r      register DES_LONG tin0,tin1;\r   register DES_LONG tout0,tout1,xor0,xor1;\r       register DES_LONG inW0,inW1,outW0,outW1;\r       register unsigned char *in,*out;\r       register long l=length;\r        DES_LONG tin[2];\r       unsigned char *iv;\r\r    in=(unsigned char *)inw;\r       c2l(in,inW0);\r  c2l(in,inW1);\r  in=(unsigned char *)outw;\r      c2l(in,outW0);\r c2l(in,outW1);\r\r        in=(unsigned char *)input;\r     out=(unsigned char *)output;\r   iv=(unsigned char *)ivec;\r\r     if (encrypt)\r           {\r              c2l(iv,tout0);\r         c2l(iv,tout1);\r         for (l-=8; l>=0; l-=8)\r                 {\r                      c2l(in,tin0);\r                  c2l(in,tin1);\r                  tin0^=tout0^inW0; tin[0]=tin0;\r                 tin1^=tout1^inW1; tin[1]=tin1;\r                 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]^outW0; l2c(tout0,out);\r                    tout1=tin[1]^outW1; l2c(tout1,out);\r                    }\r              if (l != -8)\r                   {\r                      c2ln(in,tin0,tin1,l+8);\r                        tin0^=tout0^inW0; tin[0]=tin0;\r                 tin1^=tout1^inW1; tin[1]=tin1;\r                 des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);\r                     tout0=tin[0]^outW0; l2c(tout0,out);\r                    tout1=tin[1]^outW1; l2c(tout1,out);\r                    }\r              iv=(unsigned char *)ivec;\r              l2c(tout0,iv);\r         l2c(tout1,iv);\r         }\r      else\r           {\r              c2l(iv,xor0);\r          c2l(iv,xor1);\r          for (l-=8; l>0; l-=8)\r                  {\r                      c2l(in,tin0); tin[0]=tin0^outW0;\r                       c2l(in,tin1); tin[1]=tin1^outW1;\r                       des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0^inW0;\r                        tout1=tin[1]^xor1^inW1;\r                        l2c(tout0,out);\r                        l2c(tout1,out);\r                        xor0=tin0;\r                     xor1=tin1;\r                     }\r              if (l != -8)\r                   {\r                      c2l(in,tin0); tin[0]=tin0^outW0;\r                       c2l(in,tin1); tin[1]=tin1^outW1;\r                       des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);\r                     tout0=tin[0]^xor0^inW0;\r                        tout1=tin[1]^xor1^inW1;\r                        l2cn(tout0,tout1,out,l+8);\r                     xor0=tin0;\r                     xor1=tin1;\r                     }\r\r             iv=(unsigned char *)ivec;\r              l2c(xor0,iv);\r          l2c(xor1,iv);\r          }\r      tin0=tin1=tout0=tout1=xor0=xor1=0;\r     inW0=inW1=outW0=outW1=0;\r       tin[0]=tin[1]=0;\r       }\r\r
\ No newline at end of file
diff --git a/mac/libsasl/libsasl b/mac/libsasl/libsasl
new file mode 100755 (executable)
index 0000000..4aed4ba
Binary files /dev/null and b/mac/libsasl/libsasl differ
diff --git a/mac/libsasl/libsasl.Carbon b/mac/libsasl/libsasl.Carbon
new file mode 100755 (executable)
index 0000000..d654f3d
Binary files /dev/null and b/mac/libsasl/libsasl.Carbon differ
diff --git a/mac/libsasl/libsasl.Carbon.exp b/mac/libsasl/libsasl.Carbon.exp
new file mode 100755 (executable)
index 0000000..ad2553d
--- /dev/null
@@ -0,0 +1,55 @@
+#xxx_sasl_gethostname
+#xxx_sasl_strdup
+#sasl_free_secret
+#sasl_client_auth
+sasl_client_step
+sasl_client_start
+sasl_client_new
+sasl_client_init
+sasl_churn
+sasl_rand
+sasl_randseed
+sasl_randfree
+sasl_randcreate
+sasl_utf8verify
+sasl_mkchal
+sasl_decode64
+sasl_encode64
+sasl_idle
+sasl_errstring
+#sasl_usererr
+sasl_errdetail
+sasl_setprop
+sasl_getprop
+sasl_dispose
+sasl_done
+sasl_set_alloc
+sasl_decode
+sasl_encode
+sasl_set_mutex
+#sasl_config_getswitch
+#sasl_config_getint
+#sasl_config_getstring
+#sasl_config_init
+#_sasl_allocation_utils
+#_sasl_mutex_utils
+#_sasl_server_putsecret_hook
+#_sasl_server_getsecret_hook
+#_sasl_server_idle_hook
+#_sasl_client_idle_hook
+#_sasl_server_cleanup_hook
+#_sasl_client_cleanup_hook
+#_sasl_find_verifyfile_callback
+#_sasl_find_getpath_callback
+#_sasl_free_utils
+#_sasl_alloc_utils
+#_sasl_log
+#_sasl_getcallback
+#_sasl_conn_dispose
+#_sasl_conn_init
+#_sasl_strdup
+#_sasl_done_with_plugin
+#_sasl_get_mech_list
+sasl_encodev
+sasl_erasebuffer
+sasl_seterror
\ No newline at end of file
diff --git a/mac/libsasl/libsasl.exp b/mac/libsasl/libsasl.exp
new file mode 100755 (executable)
index 0000000..7eb99a3
--- /dev/null
@@ -0,0 +1,52 @@
+#xxx_sasl_gethostname
+xxx_sasl_strdup
+#sasl_free_secret
+#sasl_client_auth
+sasl_client_step
+sasl_client_start
+sasl_client_new
+sasl_client_init
+sasl_churn
+sasl_rand
+sasl_randseed
+sasl_randfree
+sasl_randcreate
+sasl_utf8verify
+sasl_mkchal
+sasl_decode64
+sasl_encode64
+sasl_idle
+sasl_errstring
+#sasl_usererr
+sasl_errdetail
+sasl_setprop
+sasl_getprop
+sasl_dispose
+sasl_done
+sasl_set_alloc
+sasl_decode
+sasl_encode
+sasl_set_mutex
+#sasl_config_getswitch
+#sasl_config_getint
+#sasl_config_getstring
+#sasl_config_init
+#_sasl_allocation_utils
+#_sasl_mutex_utils
+#_sasl_server_putsecret_hook
+#_sasl_server_getsecret_hook
+#_sasl_server_idle_hook
+#_sasl_client_idle_hook
+#_sasl_server_cleanup_hook
+#_sasl_client_cleanup_hook
+#_sasl_find_verifyfile_callback
+#_sasl_find_getpath_callback
+#_sasl_free_utils
+#_sasl_alloc_utils
+#_sasl_log
+#_sasl_getcallback
+#_sasl_conn_dispose
+#_sasl_conn_init
+#_sasl_strdup
+#_sasl_done_with_plugin
+#_sasl_get_mech_list
diff --git a/mac/libsasl/libsasl_prefix.h b/mac/libsasl/libsasl_prefix.h
new file mode 100755 (executable)
index 0000000..6b97426
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * compile the plugins into the library for nice debugging
+ */
+
+#define NO_SASL_MONOLITHIC
+
+/*
+ * compiler doesnt allow an empty file
+ */
+typedef int xxx_sc_foo;
diff --git a/mac/libsasl/libsasl_prefix_carbon.h b/mac/libsasl/libsasl_prefix_carbon.h
new file mode 100755 (executable)
index 0000000..0bc60fd
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * compile the plugins into the library for nice debugging
+ */
+
+#define NO_SASL_MONOLITHIC
+
+/*
+ * compiler doesnt allow an empty file
+ */
+typedef int xxx_sc_foo;
+
+#define TARGET_API_MAC_CARBON 1
diff --git a/mac/mac_lib/getopt.c b/mac/mac_lib/getopt.c
new file mode 100755 (executable)
index 0000000..853ce3a
--- /dev/null
@@ -0,0 +1,120 @@
+#include <config.h>
+
+/*
+ * $Id: getopt.c,v 1.2 2001/12/04 02:06:35 rjs3 Exp $
+ * Copyright (c) 1987, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c   8.2 (Berkeley) 4/2/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int    opterr = 1,             /* if error message should be printed */
+       optind = 1,             /* index into parent argv vector */
+       optopt,                 /* character checked for validity */
+       optreset;               /* reset getopt */
+char   *optarg;                /* argument associated with option */
+
+#define        BADCH   (int)'?'
+#define        BADARG  (int)':'
+#define        EMSG    ""
+
+/*
+ * getopt --
+ *     Parse argc/argv argument vector.
+ */
+int
+getopt(
+       int nargc,
+       char * const *nargv,
+       const char *ostr)
+{
+       extern char *__progname;
+       static char *place = EMSG;              /* option letter processing */
+       char *oli;                              /* option letter list index */
+
+       if (optreset || !*place) {              /* update scanning pointer */
+               optreset = 0;
+               if (optind >= nargc || *(place = nargv[optind]) != '-') {
+                       place = EMSG;
+                       return (EOF);
+               }
+               if (place[1] && *++place == '-') {      /* found "--" */
+                       ++optind;
+                       place = EMSG;
+                       return (EOF);
+               }
+       }                                       /* option letter okay? */
+       if ((optopt = (int)*place++) == (int)':' ||
+           !(oli = strchr(ostr, optopt))) {
+               /*
+                * if the user didn't specify '-' as an option,
+                * assume it means EOF.
+                */
+               if (optopt == (int)'-')
+                       return (EOF);
+               if (!*place)
+                       ++optind;
+               if (opterr && *ostr != ':')
+                       (void)fprintf(stderr,
+                           "%s: illegal option -- %c\n", __progname, optopt);
+               return (BADCH);
+       }
+       if (*++oli != ':') {                    /* don't need argument */
+               optarg = NULL;
+               if (!*place)
+                       ++optind;
+       }
+       else {                                  /* need an argument */
+               if (*place)                     /* no white space */
+                       optarg = place;
+               else if (nargc <= ++optind) {   /* no arg */
+                       place = EMSG;
+                       if (*ostr == ':')
+                               return (BADARG);
+                       if (opterr)
+                               (void)fprintf(stderr,
+                                   "%s: option requires an argument -- %c\n",
+                                   __progname, optopt);
+                       return (BADCH);
+               }
+               else                            /* white space */
+                       optarg = nargv[optind];
+               place = EMSG;
+               ++optind;
+       }
+       return (optopt);                        /* dump back option letter */
+}
diff --git a/mac/mac_lib/mac_dyn_dlopen.c b/mac/mac_lib/mac_dyn_dlopen.c
new file mode 100755 (executable)
index 0000000..f8aae3e
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * load the sasl plugins
+ * $Id: mac_dyn_dlopen.c,v 1.3 2003/02/13 19:55:59 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.
+ */
+
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sasl.h>
+#include "saslint.h"
+
+#include <CodeFragments.h>
+#include <Errors.h>
+#include <Resources.h>
+#include <Strings.h>
+#include <Folders.h>
+
+#ifdef RUBBISH
+#include <FSpCompat.h>
+#endif
+
+/*
+ * The following data structure defines the structure of a code fragment
+ * resource.  We can cast the resource to be of this type to access
+ * any fields we need to see.
+ */
+struct CfrgHeader {
+    long       res1;
+    long       res2;
+    long       version;
+    long       res3;
+    long       res4;
+    long       filler1;
+    long       filler2;
+    long       itemCount;
+    char       arrayStart;     /* Array of externalItems begins here. */
+};
+typedef struct CfrgHeader CfrgHeader, *CfrgHeaderPtr, **CfrgHeaderPtrHand;
+
+/*
+ * The below structure defines a cfrag item within the cfrag resource.
+ */
+struct CfrgItem {
+    OSType     archType;
+    long       updateLevel;
+    long       currVersion;
+    long       oldDefVersion;
+    long       appStackSize;
+    short      appSubFolder;
+    char       usage;
+    char       location;
+    long       codeOffset;
+    long       codeLength;
+    long       res1;
+    long       res2;
+    short      itemSize;
+    Str255     name;           /* This is actually variable sized. */
+};
+typedef struct CfrgItem CfrgItem;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#if TARGET_API_MAC_CARBON
+#define SASL_PLUGIN_DIR "\p:sasl v2:carbon:biff"
+#else
+#define SASL_PLUGIN_DIR "\p:sasl v2:biff"
+#endif
+
+typedef struct lib_list 
+{
+    struct lib_list *next;
+    void *library;
+} lib_list_t;
+
+static lib_list_t *lib_list_head = NULL;
+
+/*
+ * add the passed extension
+ */
+int _macsasl_get_fsspec(FSSpec *fspec,
+       void **libraryptr)
+{
+       int rc;
+    CFragConnectionID connID;
+    Ptr dummy;
+    unsigned long offset = 0;
+    unsigned long length = kCFragGoesToEOF;
+    unsigned char package_name[255];
+       Str255 error_text;
+       lib_list_t *newhead;
+
+    newhead = sasl_ALLOC(sizeof(lib_list_t));
+    if(!newhead) return SASL_NOMEM;
+
+       package_name[0] = 0;
+    rc=GetDiskFragment(fspec,offset,length,package_name,
+           kLoadCFrag,&connID,&dummy,error_text);
+       if(rc!=0) {
+               sasl_FREE(newhead);
+               return rc;
+       }
+
+    newhead->library = (void *)connID;
+    newhead->next = lib_list_head;
+    lib_list_head = newhead;
+
+    *libraryptr = (void *)connID;
+    return SASL_OK;
+}
+
+int _sasl_locate_entry(void *library, const char *entryname,
+                      void **entry_point) 
+{
+       int result;
+#if TARGET_API_MAC_CARBON
+    char cstr[256];
+#endif
+       Str255 pentry;
+    CFragSymbolClass symClass;
+    OSErr rc;
+
+    if(!entryname) {
+       return SASL_BADPARAM;
+    }
+
+    if(!library) {
+       return SASL_BADPARAM;
+    }
+
+    if(!entry_point) {
+       return SASL_BADPARAM;
+    }
+
+#if TARGET_API_MAC_CARBON
+       strcpy(cstr,entryname);
+    CopyCStringToPascal(cstr, pentry);
+#else
+       strcpy(pentry,entryname);
+    c2pstr(pentry);
+#endif
+
+    rc = FindSymbol((CFragConnectionID)library,pentry,entry_point, &symClass);
+    if ((rc!=noErr) || (symClass==kDataCFragSymbol))
+       return SASL_FAIL;
+
+       return SASL_OK;
+}
+
+static int _sasl_plugin_load(char *plugin, void *library,
+                            const char *entryname,
+                            int (*add_plugin)(const char *, void *)) 
+{
+    void *entry_point;
+    int result;
+    
+    result = _sasl_locate_entry(library, entryname, &entry_point);
+    if(result == SASL_OK) {
+       result = add_plugin(plugin, entry_point);
+//     if(result != SASL_OK)
+//         _sasl_log(NULL, SASL_LOG_ERR,
+//                   "_sasl_plugin_load failed on %s for plugin: %s\n",
+//                   entryname, plugin);
+    }
+
+    return result;
+}
+
+/*
+ * does the passed string a occur and the end of string b?
+ */
+int _macsasl_ends_in(char *a, char *b)
+{
+       int alen=strlen(a);
+       int blen=strlen(b);
+       if(blen<alen)
+               return FALSE;
+       return (memcmp(a,b+(blen-alen),alen)==0);
+}
+
+/*
+ * scan the passed directory loading sasl extensions
+ */
+int _macsasl_find_extensions_in_dir(short vref,long dir_id,
+       const add_plugin_list_t *entrypoints)
+{
+       CInfoPBRec cinfo;
+       unsigned char aname[300];
+       char plugname[256];
+       int findex=0;
+       FSSpec a_plugin;
+       lib_list_t *library;
+       char *c;
+       const add_plugin_list_t *cur_ep;
+
+       while(TRUE) {
+               int os;
+               memset(&cinfo,0,sizeof(cinfo));
+               aname[0] = 0;
+               cinfo.hFileInfo.ioVRefNum=vref;
+               cinfo.hFileInfo.ioNamePtr=aname;
+               cinfo.hFileInfo.ioFDirIndex=findex++;
+               cinfo.hFileInfo.ioDirID=dir_id;
+               os=PBGetCatInfo(&cinfo,FALSE);
+               if(os!=0)
+                       return SASL_OK;
+               aname[aname[0]+1] = 0;
+
+               /* skip over non shlb files */
+               if(!_macsasl_ends_in(".shlb",aname+1))
+                       continue;
+               os=FSMakeFSSpec(vref,dir_id,aname,&a_plugin);
+               if(os!=0)
+                       continue;
+
+               /* skip "lib" and cut off suffix --
+                  this only need be approximate */
+               strcpy(plugname, aname + 1);
+               c = strchr(plugname, (int)'.');
+               if(c) *c = '\0';
+
+               if (!_macsasl_get_fsspec(&a_plugin,&library))
+                       for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
+                               _sasl_plugin_load(plugname, library, cur_ep->entryname,
+                                                 cur_ep->add_plugin);
+                               /* If this fails, it's not the end of the world */
+                       }
+       }
+       return SASL_OK;
+}
+
+/* gets the list of mechanisms */
+int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
+                       const sasl_callback_t *getpath_cb,
+                       const sasl_callback_t *verifyfile_cb)
+{
+       int rc;
+       short extensions_vref;
+       long extensions_dirid;
+       FSSpec sasl_dir;
+       /* find the extensions folder */
+       rc=FindFolder(kOnSystemDisk,kExtensionFolderType,FALSE,
+               &extensions_vref,&extensions_dirid);
+       if(rc!=0)
+               return SASL_BADPARAM;
+       rc=FSMakeFSSpec(extensions_vref,extensions_dirid,SASL_PLUGIN_DIR,&sasl_dir);
+       /*
+        * if a plugin named biff exits or not we really dont care
+        * if it does get rc 0 if it does not get -43 (fnfErr)
+        * if the sasl dir doesnt exist we get -120 (dirNFFErr)
+        */
+       if((rc!=0)&&(rc!=fnfErr))
+               return SASL_BADPARAM;
+       /*
+        * now extensions_vref is volume
+        * sasl_dir.parID is dirid for sasl plugins folder
+        */
+       
+       return _macsasl_find_extensions_in_dir(extensions_vref,sasl_dir.parID,entrypoints);
+}
+
+int
+_sasl_done_with_plugins(void)
+{
+    lib_list_t *libptr, *libptr_next;
+    
+    for(libptr = lib_list_head; libptr; libptr = libptr_next) {
+       libptr_next = libptr->next;
+       if(libptr->library)
+           CloseConnection((CFragConnectionID*)&libptr->library);
+       sasl_FREE(libptr);
+    }
+
+    lib_list_head = NULL;
+
+    return SASL_OK;
+}
diff --git a/mac/mac_lib/mac_monolithic_dlopen.c b/mac/mac_lib/mac_monolithic_dlopen.c
new file mode 100755 (executable)
index 0000000..076bed4
--- /dev/null
@@ -0,0 +1,106 @@
+/* 
+ * 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.
+ */
+/* $Id: mac_monolithic_dlopen.c,v 1.3 2003/02/13 19:55:59 rjs3 Exp $ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sasl.h>
+#include "saslint.h"
+
+#include <sasl_plain_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <sasl_anonymous_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <sasl_cram_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <sasl_md5_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <sasl_scram_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <sasl_kerberos4_plugin_decl.h>
+#undef sasl_server_plug_init
+#undef sasl_client_plug_init
+
+#include <stdio.h>
+
+/* gets the list of mechanisms */
+int _sasl_get_mech_list(const char *entryname,
+                       const sasl_callback_t *getpath_cb,
+                       const sasl_callback_t *verifyfile_cb,
+                       int (*add_plugin)(void *,void *))
+{
+       if(strcmp(entryname,"sasl_client_plug_init")==0) {
+               (*add_plugin)(kerberos4_sasl_client_plug_init,(void*)1);
+               (*add_plugin)(anonymous_sasl_client_plug_init,(void*)1);
+               (*add_plugin)(cram_sasl_client_plug_init,(void*)1);
+               (*add_plugin)(scram_sasl_client_plug_init,(void*)1);
+               (*add_plugin)(md5_sasl_client_plug_init,(void*)1);
+               (*add_plugin)(plain_sasl_client_plug_init,(void*)1);
+       } else if(strcmp(entryname,"sasl_server_plug_init")==0) {
+               (*add_plugin)(kerberos4_sasl_server_plug_init,(void*)1);
+               (*add_plugin)(anonymous_sasl_server_plug_init,(void*)1);
+               (*add_plugin)(cram_sasl_server_plug_init,(void*)1);
+               (*add_plugin)(scram_sasl_server_plug_init,(void*)1);
+               (*add_plugin)(md5_sasl_server_plug_init,(void*)1);
+               (*add_plugin)(plain_sasl_server_plug_init,(void*)1);
+       } else
+               return SASL_BADPARAM;
+       
+       return SASL_OK;
+}
+
+int _sasl_done_with_plugin(void *plugin)
+{
+  if (! plugin)
+    return SASL_BADPARAM;
+
+  return SASL_OK;
+}
diff --git a/mac/mac_lib/parse_cmd_line.c b/mac/mac_lib/parse_cmd_line.c
new file mode 100755 (executable)
index 0000000..e2486d3
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * prompt for a command line
+ */
+/* $Id: parse_cmd_line.c,v 1.3 2003/02/13 19:55:59 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <parse_cmd_line.h>
+
+static char *skip_blanks(char *s)
+{
+       while(isspace(*s))
+               s++;
+       return s;
+}
+
+static void chomp(char *dst,char ch)
+{
+       dst=strchr(dst,ch);
+       if(dst!=0)
+               *dst=0;
+}
+
+int parse_cmd_line(int max_argc,char **argv,int line_size,char *line)
+{
+       int argc=1;
+       memset(line,0,line_size);
+       fprintf(stdout,"cmd>");
+       fflush(stdout);
+       fgets(line,line_size-1,stdin);
+       *argv++="prg";
+       chomp(line,'\n');
+       max_argc-=2;
+       while(line[0]!=0) {
+               line=skip_blanks(line);
+               if(line[0]==0)
+                       break;
+               if(argc>=max_argc)
+                       break;
+               *argv++=line;
+               argc++;
+               line=strchr(line,' ');
+               if(line==0)
+                       break;
+               *line++=0;
+       }
+       *argv=0;
+       return argc;
+}
diff --git a/mac/mac_lib/xxx_client_mac_lib.c b/mac/mac_lib/xxx_client_mac_lib.c
new file mode 100755 (executable)
index 0000000..07d7e6c
--- /dev/null
@@ -0,0 +1,111 @@
+/* $Id: xxx_client_mac_lib.c,v 1.3 2003/02/13 19:55:59 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.
+ */
+/*
+ * routines used by the sasl test programs and not provided
+ * by a mac.  see also xxx_mac_lib.c for routines needed by
+ * the sasl library and not supplied by the system runtime
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <config.h>
+#include <netinet/in.h>
+
+char *__progname="mac";
+
+struct hostent *gethostbyname(const char *hnam)
+{
+       static struct hostent result;
+       int bytes[4];
+       int i;
+       unsigned int ip=0;
+       if(sscanf(hnam,"%d.%d.%d.%d",bytes,bytes+1,bytes+2,bytes+3)!=4)
+               return 0;
+       for(i=0;i<4;i++) {
+               ip<<=8;
+               ip|=(bytes[i]&0x0ff);
+       }
+       memcpy(result.h_addr,&ip,4);
+       return &result;
+}
+
+/*
+ * ala perl chomp
+ */
+static void xxy_chomp(char *s,const char stop_here)
+{
+       char ch;
+       while((ch= (*s++))!=0)
+               if(ch==stop_here) {
+                       s[-1]=0;
+                       return;
+               }
+}
+
+char* getpass(const char *prompt)
+{
+       const int max_buf=200;
+       char *buf=malloc(max_buf);
+       if(buf==0)
+               return 0;
+       memset(buf,0,max_buf);  /* not likely to be a performance issue eheh */
+       printf("%s",prompt);
+       fgets(buf,max_buf-1,stdin);
+       xxy_chomp(buf,'\n');
+       return buf;
+}
+
+#ifdef TARGET_API_MAC_CARBON
+char *strdup(const char *str)
+{
+       if(str==0)
+               return 0;
+       {
+               const int len=strlen(str);
+               char *result=malloc(len+1);
+               strcpy(result,str);
+               return result;
+       }
+       
+}
+#endif
diff --git a/mac/mac_lib/xxx_mac_lib.c b/mac/mac_lib/xxx_mac_lib.c
new file mode 100755 (executable)
index 0000000..eb4c335
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ * internaly sasl or its test programs use some functions which are not availible
+ * on the macintosh.  these have common names like strdrup gethostname etc.  defining
+ * them as routines could make conflicts with clients of the library.  in config.h
+ * we macro define such names to start with xxx_.  The implementation for them is
+ * here.  The xxx_ is in hopes of not conflicting with a name in client program.
+ */
+/* $Id: xxx_mac_lib.c,v 1.3 2003/02/13 19:55:59 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.
+ */
+
+ #include <string.h>
+ #include <stdlib.h>
+ #include <ctype.h>
+ #include <config.h>
+// #include <netinet/in.h>
+
+/*
+ * return the smaller of two integers
+ */
+static int xxy_min(int a,int b)
+{
+       if(a<b)
+               return a;
+       return b;
+}
+
+static int limit_strcpy(char *dest,const char *src,int len)
+{
+       int slen=strlen(src);
+       if(len<1)
+               return 0;
+       slen=xxy_min(slen,len-1);
+       if(slen>0)
+               memcpy(dest,src,slen);
+       dest[slen]=0;
+       return slen;    
+}
+
+int strcpy_truncate(char *dest,char *src,int len)
+{
+       return limit_strcpy(dest,src,len);
+}
+
+int gethostname(char *dest,int destlen)
+{
+       limit_strcpy(dest,"localhost",destlen);
+       return 0;
+}
+
+char *strdup(const char *str)
+{
+       if(str==0)
+               return 0;
+       {
+               const int len=strlen(str);
+               char *result=malloc(len+1);
+               strcpy(result,str);
+               return result;
+       }
+       
+}
+int strncasecmp(const char *s1,const char *s2,int len)
+{
+       while(len-- >0) {
+               char c1= *s1++;
+               char c2= *s2++;
+               if((c1==0)&&(c2==0))
+                       return 0;
+               if(c1==0)
+                       return -1;
+               if(c2==0)
+                       return 1;
+               /* last ansi spec i read tolower was undefined for non uppercase chars
+                * but it works in most implementations
+                */
+               if(isupper(c1))
+                       c1=tolower(c1);
+               if(isupper(c2))
+                       c2=tolower(c2);
+               if(c1<c2)
+                       return -1;
+               if(c1>c2)
+                       return 1;
+       }
+       return 1;
+}
+
+int strcasecmp(const char *s1,const char *s2)
+{
+       while(1) {
+               char c1= *s1++;
+               char c2= *s2++;
+               if((c1==0)&&(c2==0))
+                       return 0;
+               if(c1==0)
+                       return -1;
+               if(c2==0)
+                       return 1;
+               /* last ansi spec i read tolower was undefined for non uppercase chars
+                * but it works in most implementations
+                */
+               if(isupper(c1))
+                       c1=tolower(c1);
+               if(isupper(c2))
+                       c2=tolower(c2);
+               if(c1<c2)
+                       return -1;
+               if(c1>c2)
+                       return 1;
+       }
+}
+
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+       char *cptr1, *cptr2, *cptr3;
+       long u;
+       char cptr0[256];
+       strcpy(cptr0, cp);
+
+       if (!(cptr1 = strchr(cptr0, '.'))) return 0;
+       *cptr1++ = 0;
+       if (!(cptr2 = strchr(cptr1, '.'))) return 0;
+       *cptr2++ = 0;
+       if (!(cptr3 = strchr(cptr2, '.'))) return 0;
+       *cptr3++ = 0;
+       if (!*cptr3) return 0;
+
+       u = ((atoi(cptr0) << 8 + atoi(cptr1)) << 8 + atoi(cptr2)) << 8 + atoi(cptr3);
+       inp->s_addr = htonl(u);
+       return 1;
+}
diff --git a/mac/mac_lib/yyy_mac_lib.c b/mac/mac_lib/yyy_mac_lib.c
new file mode 100755 (executable)
index 0000000..9e66907
--- /dev/null
@@ -0,0 +1,169 @@
+/* $Id: yyy_mac_lib.c,v 1.3 2003/02/13 19:55:59 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.
+ */
+#include "sasl_mac_krb_locl.h"
+#include <script.h>
+#include <ToolUtils.h>
+
+int krbONE=1;
+int krb_debug;
+
+int krb_get_config_bool(const char *variable)
+{
+       /* return the value of the only config variable we know of */
+       if(strcmp(variable,"reverse_lsb_test")==0)
+               return 0;
+       return 0;
+}
+
+/*
+ * compare two ip addresses
+ */
+int krb_equiv(
+       u_int32_t a,
+       u_int32_t b)
+{
+       if(a==0)
+               return 1;
+       if(b==0)
+               return 1;
+#ifdef STRICT_ADDRESS_EQUIV
+       return a==b;
+#else
+       return 1;
+#endif
+}
+
+int abs(int x)
+{
+  if(x>=0)
+       return x;
+  return -x;
+}
+
+
+/*
+ * from kerberos.c -- return the offset from gmt
+ */
+static long getTimeZoneOffset(void )
+{
+       MachineLocation         macLocation;
+       long                    gmtDelta;
+
+       macLocation.u.gmtDelta=0L;
+       ReadLocation(&macLocation);
+       gmtDelta=macLocation.u.gmtDelta & 0x00FFFFFF;
+       if (BitTst((void *)&gmtDelta,23L))
+               gmtDelta |= 0xFF000000;
+       gmtDelta /= 3600L;
+       return(gmtDelta);
+}
+
+/*
+ * from kerberos.c -- convert mac time to unix time
+ */
+static void mac_time_to_unix_time (unsigned long *time)
+{
+       *time -= 66L * 365L * 24L * 60L * 60L + 17L * 60L * 60L * 24L + getTimeZoneOffset() * 60L * 60L;
+}
+
+/*
+ * return the current unix time
+ */
+static unsigned long get_unix_time(void)
+{
+       unsigned long result;
+       GetDateTime(&result);
+       mac_time_to_unix_time(&result);
+       return result;
+}
+
+/*
+ * printf a warning
+ */
+void krb_warning(const char *fmt,...)
+{
+}
+
+void krb_kdctimeofday (struct timeval *tv)
+{
+       gettimeofday(tv,0);
+}
+
+int gettimeofday(struct timeval *tp, void *foo)
+{
+       tp->tv_sec=get_unix_time();
+       tp->tv_usec=0;
+       return 0;
+}
+
+void swab(char *src, char *dst,int len)
+{
+       while(len>=2) {
+               char a;
+               char b;
+               a= *src++;
+               b= *src++;
+               len-=2;
+               *dst++=b;
+               *dst++=a;
+       }
+}
+
+char *inet_ntoa(unsigned long n)
+{
+#define BYTE0(xxx) ((int)((xxx)&0x0ff))
+       static char buf[32];
+       sprintf(buf,"%d.%d.%d.%d",
+               BYTE0(n>>24),
+               BYTE0(n>>16),
+               BYTE0(n>>8),
+               BYTE0(n));
+       return buf;
+}
+
+#ifdef RUBBISH
+u_int32_t lsb_time(
+       time_t t,
+       struct sockaddr_in *src,
+       struct sockaddr_in *dst)
+{
+       return 0;
+}
+#endif
diff --git a/mac/osx_cfm_glue/cfmglue.c b/mac/osx_cfm_glue/cfmglue.c
new file mode 100755 (executable)
index 0000000..56bd825
--- /dev/null
@@ -0,0 +1,1117 @@
+/* cfmglue.c
+   by Rolf Braun, for CMU SASL on Mac OS X
+
+   This file provides routines to allow CFM (os 9 linkage) Carbon applications
+   to use the native Mach-O SASL libraries on Mac OS X, using CFBundle to
+   load the backend libraries and automatically allocated assembly callbacks
+   $Id: cfmglue.c,v 1.4 2003/06/12 00:33:05 rbraun 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.
+ */
+
+#include <Carbon.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sasl.h"
+#include "saslutil.h"
+#include "prop.h"
+
+/* prototypes for internal functions (from saslint.h) */
+int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add);
+int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen);
+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
+
+void   *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp );
+sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks);
+void DisposeCFMCallbacks(sasl_callback_t *callbacks);
+
+int _cfmsasl_haveCustomAlloc = 0;
+int _cfmsasl_haveCustomMutex = 0;
+int _cfmsasl_initted = 0;
+
+/* DO NOT change the order of this struct! It MUST match that
+   of the iovec struct in /usr/include/sys/uio.h on Mac OS X!
+   It MUST also match that of the Mac OS 9 Carbon config.h since
+   Carbon CFM stuff links at runtime against whatever it's running on! */
+struct iovec {
+    char *iov_base; 
+    long iov_len;
+};
+
+typedef struct                 
+{
+       CFURLRef                bundleURL;
+       CFBundleRef             myBundle;
+       sasl_callback_t *clientCallbacks;
+       sasl_callback_t *serverCallbacks;
+       int (*SASLClientNewPtr)(const char *service,
+                                                       const char *serverFQDN,
+                                                       const char *iplocalport,
+                                                       const char *ipremoteport,
+                                                       const sasl_callback_t *prompt_supp, 
+                                                       unsigned flags,
+                                                       sasl_conn_t **pconn);
+       int (*SASLClientStartPtr)(sasl_conn_t *conn,
+                                                               const char *mechlist,
+                                                               sasl_interact_t **prompt_need,
+                                                               const char **clientout,
+                                                               unsigned *clientoutlen,
+                                                               const char **mech);
+       int (*SASLClientStepPtr)(sasl_conn_t *conn,
+                                                               const char *serverin,
+                                                               unsigned serverinlen,
+                                                               sasl_interact_t **prompt_need,
+                                                               const char **clientout,
+                                                               unsigned *clientoutlen);
+       const char * (*SASLErrStringPtr)(int saslerr,
+                                                       const char *langlist,
+                                                       const char **outlang);
+       const char *(*sasl_errdetailPtr)(sasl_conn_t *conn);
+       int (*SASLGetPropPtr)(sasl_conn_t *conn, int propnum, const void **pvalue);
+       int (*SASLSetPropPtr)(sasl_conn_t *conn,
+                                                       int propnum,
+                                                       const void *value);
+       int (*SASLIdlePtr)(sasl_conn_t *conn);
+       int (*SASLEncodePtr)(sasl_conn_t *conn,
+                                                       const char *input, unsigned inputlen,
+                                                       const char **output, unsigned *outputlen);
+       int (*SASLDecodePtr)(sasl_conn_t *conn,
+                                                       const char *input, unsigned inputlen,
+                                                       const char **output, unsigned *outputlen);
+       int (*SASLEncodeVPtr)(sasl_conn_t *conn,
+                            const struct iovec *invec, unsigned numiov,
+                            const char **output, unsigned *outputlen);
+       int (*SASLDisposePtr)(sasl_conn_t **pconn);
+       int (*SASLDonePtr)();
+       void (*SASLSetAllocPtr)(sasl_malloc_t *, sasl_calloc_t *, sasl_realloc_t *, sasl_free_t *);
+       int (*sasl_decode64Ptr)(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen);
+       int (*sasl_encode64Ptr)(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen);
+       int (*sasl_mkchalPtr)(sasl_conn_t *conn, char *buf,
+                           unsigned maxlen, unsigned hostflag);
+       int (*sasl_utf8verifyPtr)(const char *str, unsigned len);
+       void (*sasl_churnPtr)(sasl_rand_t *rpool, 
+                           const char *data,
+                           unsigned len);
+       void (*sasl_randPtr)(sasl_rand_t *rpool,
+                          char *buf,
+                          unsigned len);
+       void (*sasl_randseedPtr)(sasl_rand_t *rpool,
+                              const char *seed,
+                              unsigned len);
+       void (*sasl_randfreePtr)(sasl_rand_t **rpool);
+       int (*sasl_randcreatePtr)(sasl_rand_t **rpool);
+       void (*SASLSetMutexPtr)(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
+                                sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md);
+       int (*SASLServerNewPtr)(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);
+       int (*sasl_listmechPtr)(sasl_conn_t *conn,
+                             const char *user,
+                             const char *prefix,
+                             const char *sep,
+                             const char *suffix,
+                             const char **result,
+                             unsigned *plen,
+                             int *pcount);
+       int (*SASLServerStartPtr)(sasl_conn_t *conn,
+                                 const char *mech,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen);
+       int (*SASLServerStepPtr)(sasl_conn_t *conn,
+                    const char *clientin,
+                    unsigned clientinlen,
+                    const char **serverout,
+                    unsigned *serveroutlen);
+       int (*sasl_checkpassPtr)(sasl_conn_t *conn,
+                              const char *user,
+                              unsigned userlen,
+                              const char *pass,
+                              unsigned passlen);
+       int (*sasl_user_existsPtr)(sasl_conn_t *conn,
+                        const char *service,
+                    const char *user_realm,
+                    const char *user);
+       int (*sasl_setpassPtr)(sasl_conn_t *conn,
+                const char *user,
+                const char *pass,
+                unsigned passlen,
+                const char *oldpass, unsigned oldpasslen,
+                unsigned flags);
+       int (*sasl_checkapopPtr)(sasl_conn_t *conn,
+                              const char *challenge, unsigned challen,
+                              const char *response, unsigned resplen);
+       int (*sasl_auxprop_requestPtr)(sasl_conn_t *conn,
+                                    const char **propnames);
+       struct propctx *(*sasl_auxprop_getctxPtr)(sasl_conn_t *conn);
+       void (*sasl_erasebufferPtr)(char *pass, unsigned len);
+       struct propctx *(*prop_newPtr)(unsigned estimate);
+       int (*prop_dupPtr)(struct propctx *src_ctx, struct propctx **dst_ctx);
+       const struct propval *(*prop_getPtr)(struct propctx *ctx);
+       int (*prop_getnamesPtr)(struct propctx *ctx, const char **names,
+                 struct propval *vals);
+       void (*prop_clearPtr)(struct propctx *ctx, int requests);
+       void (*prop_erasePtr)(struct propctx *ctx, const char *name);
+       void (*prop_disposePtr)(struct propctx **ctx);
+       int (*prop_formatPtr)(struct propctx *ctx, const char *sep, int seplen,
+               char *outbuf, unsigned outmax, unsigned *outlen);
+       int (*prop_setPtr)(struct propctx *ctx, const char *name,
+            const char *value, int vallen);
+       int (*prop_setvalsPtr)(struct propctx *ctx, const char *name,
+                const char **values);
+       int (*_sasl_add_stringPtr)(char **out, int *alloclen, int *outlen, const char *add);
+       int (*_buf_allocPtr)(char **rwbuf, unsigned *curlen, unsigned newlen);
+       void (*_sasl_get_errorbufPtr)(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl);
+
+} GlobalsRec;
+
+typedef struct
+{
+       sasl_malloc_t *custMalloc;
+       sasl_calloc_t *custCalloc;
+       sasl_realloc_t *custRealloc;
+       sasl_free_t *custFree;
+
+       sasl_mutex_alloc_t *custMutexNew;
+       sasl_mutex_lock_t *custMutexLock;
+       sasl_mutex_unlock_t *custMutexUnlock;
+       sasl_mutex_free_t *custMutexDispose;
+} GlobalParamsRec;
+
+typedef struct
+{
+       sasl_conn_t                     *ctx;
+       sasl_callback_t         *cbk;
+} cfm_sasl_conn_t;
+
+GlobalsRec     saslcfmglob;                                            //      The globals
+GlobalParamsRec saslcfmglobp;
+
+// From Apple sample code... (CarbonLib SDK, CFM->MachO->CFM)
+//
+//     This function allocates a block of CFM glue code which contains the instructions to call CFM routines
+//
+void   *MachOFunctionPointerForCFMFunctionPointer( void *cfmfp )
+{
+       UInt32 template[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
+    UInt32     *mfp = (UInt32*) NewPtr( sizeof(template) );            //      Must later dispose of allocated memory
+    mfp[0] = template[0] | ((UInt32)cfmfp >> 16);
+    mfp[1] = template[1] | ((UInt32)cfmfp & 0xFFFF);
+    mfp[2] = template[2];
+    mfp[3] = template[3];
+    mfp[4] = template[4];
+    mfp[5] = template[5];
+    MakeDataExecutable( mfp, sizeof(template) );
+    return( mfp );
+}
+
+sasl_callback_t *GetCFMCallbacks(const sasl_callback_t *callbacks)
+{
+       int cbksize = 0;
+       const sasl_callback_t *cbk = callbacks;
+       sasl_callback_t *ncbk, *new_callbacks;
+       while (cbk->id) {
+               cbksize++; cbk++;
+       }
+       cbksize++; cbk = callbacks;
+
+       ncbk = new_callbacks = (sasl_callback_t *)NewPtr(cbksize * sizeof(sasl_callback_t));
+       if (!ncbk) return nil;
+       while (cbksize--) {
+               ncbk->id = cbk->id;
+               ncbk->context = cbk->context;
+               if (cbk->proc)
+                       ncbk->proc = MachOFunctionPointerForCFMFunctionPointer(cbk->proc);
+               else ncbk->proc = nil;
+               ncbk++; cbk++;
+       }
+       return new_callbacks;
+}
+
+void DisposeCFMCallbacks(sasl_callback_t *callbacks)
+{
+       sasl_callback_t *cbk = callbacks;
+       if (!cbk) return;
+       while (cbk->id) {
+               if (cbk->proc) DisposePtr((Ptr)cbk->proc);
+               cbk++;
+       }
+       DisposePtr((Ptr)callbacks);
+}
+
+int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname);
+
+int _cfmsasl_common_init(const sasl_callback_t *callbacks, int isServer, const char *appname)
+{
+       int (*SASLClientInitPtr)(const sasl_callback_t *callbacks);
+       int (*SASLServerInitPtr)(const sasl_callback_t *callbacks, const char *appname);
+       int result = SASL_NOMEM;
+
+  if (!_cfmsasl_initted) {
+// The skeleton for this code originally came from the CFM->MachO->CFM sample
+// provided by Aple with the Carbon SDK. It shows how to use CFBundle to call MachO
+// libraries from CFM and how to encapsulate callbacks into CFM.
+       memset( &saslcfmglob, 0, sizeof(GlobalsRec) );                                          //      Initialize the globals
+
+       //      Make a CFURLRef from the CFString representation of the bundle's path.
+       //      See the Core Foundation URL Services chapter for details.
+       saslcfmglob.bundleURL   = CFURLCreateWithFileSystemPath( 
+                               nil,                                                                             //     workaround for Radar # 2452789
+                               CFSTR("/Library/Frameworks/SASL2.framework"), //        hard coded path for sample
+                               0,
+                               true );
+       if ( saslcfmglob.bundleURL != NULL )
+
+       // Make a bundle instance using the URLRef.
+       saslcfmglob.myBundle    = CFBundleCreate(
+                               NULL /* kCFAllocatorDefault */,                         //      workaround for Radar # 2452789
+                               saslcfmglob.bundleURL );
+
+       if ( saslcfmglob.myBundle && CFBundleLoadExecutable( saslcfmglob.myBundle )) {  //      Try to load the executable from my bundle.
+
+               // Now that the code is loaded, search for the functions we want by name.
+               saslcfmglob.SASLClientNewPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_client_new") );
+
+               saslcfmglob.SASLClientStartPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_client_start") );
+
+               saslcfmglob.SASLClientStepPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_client_step") );
+
+               saslcfmglob.SASLErrStringPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_errstring") );
+
+               saslcfmglob.sasl_errdetailPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_errdetail") );
+
+               saslcfmglob.SASLGetPropPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_getprop") );
+
+               saslcfmglob.SASLSetPropPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_setprop") );
+
+               saslcfmglob.SASLIdlePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_idle") );
+
+               saslcfmglob.SASLEncodePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_encode") );
+
+               saslcfmglob.SASLEncodeVPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_encodev") );
+
+               saslcfmglob.SASLDecodePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_decode") );
+
+               saslcfmglob.SASLDisposePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_dispose") );
+
+               saslcfmglob.SASLDonePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_done") );
+
+               saslcfmglob.SASLSetAllocPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_set_alloc") );
+
+               saslcfmglob.sasl_encode64Ptr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_encode64") );
+
+               saslcfmglob.sasl_decode64Ptr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_decode64") );
+               
+               saslcfmglob.sasl_mkchalPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_mkchal") );
+
+               saslcfmglob.sasl_utf8verifyPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_utf8verify") );
+
+               saslcfmglob.sasl_churnPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_churn") );
+
+               saslcfmglob.sasl_randPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_rand") );
+
+               saslcfmglob.sasl_randseedPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_randseed") );
+
+               saslcfmglob.sasl_randcreatePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_randcreate") );
+
+               saslcfmglob.sasl_randfreePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_randfree") );
+
+               saslcfmglob.SASLSetMutexPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_set_mutex") );
+
+               saslcfmglob.SASLServerNewPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_server_new") );
+
+               saslcfmglob.SASLServerStartPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_server_start") );
+
+               saslcfmglob.SASLServerStepPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_server_step") );
+
+               saslcfmglob.sasl_listmechPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_listmech") );
+
+               saslcfmglob.sasl_checkpassPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_checkpass") );
+
+               saslcfmglob.sasl_setpassPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_setpass") );
+
+               saslcfmglob.sasl_user_existsPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_user_exists") );
+
+               saslcfmglob.sasl_checkapopPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_checkapop") );
+
+               saslcfmglob.sasl_auxprop_requestPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_auxprop_request") );
+
+               saslcfmglob.sasl_auxprop_getctxPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_auxprop_getctx") );
+
+               saslcfmglob.sasl_erasebufferPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_erasebuffer") );
+
+               saslcfmglob.prop_newPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_new") );
+
+               saslcfmglob.prop_dupPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_dup") );
+
+               saslcfmglob.prop_getPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_get") );
+
+               saslcfmglob.prop_getnamesPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_getnames") );
+
+               saslcfmglob.prop_clearPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_clear") );
+
+               saslcfmglob.prop_erasePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_erase") );
+
+               saslcfmglob.prop_disposePtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_dispose") );
+
+               saslcfmglob.prop_formatPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_format") );
+
+               saslcfmglob.prop_setPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_set") );
+
+               saslcfmglob.prop_setvalsPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("prop_setvals") );
+
+/* These are internal functions used by our sasl_seterror */
+               saslcfmglob._sasl_add_stringPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("_sasl_add_string") );
+
+               saslcfmglob._buf_allocPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("_buf_alloc") );
+
+               saslcfmglob._sasl_get_errorbufPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("_sasl_get_errorbuf") );
+
+               if (!_cfmsasl_haveCustomAlloc) {
+                       saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(malloc);
+                       saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(calloc);
+                       saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(realloc);
+                       saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(free);
+                       
+                       _cfmsasl_haveCustomAlloc = 1;
+               }
+
+               saslcfmglob.SASLSetAllocPtr(saslcfmglobp.custMalloc, saslcfmglobp.custCalloc,
+                                                                       saslcfmglobp.custRealloc, saslcfmglobp.custFree);
+
+               if (_cfmsasl_haveCustomMutex) 
+                       saslcfmglob.SASLSetMutexPtr(saslcfmglobp.custMutexNew, saslcfmglobp.custMutexLock,
+                                                                               saslcfmglobp.custMutexUnlock, saslcfmglobp.custMutexDispose);
+
+       } else if (saslcfmglob.myBundle) {
+               CFRelease(saslcfmglob.myBundle);
+               saslcfmglob.myBundle = nil;
+       }
+
+       if (saslcfmglob.bundleURL && !saslcfmglob.myBundle) {
+               CFRelease(saslcfmglob.bundleURL);
+               saslcfmglob.bundleURL = nil;
+       }
+
+       if (saslcfmglob.myBundle)
+               _cfmsasl_initted = 1;
+  }
+
+       if (_cfmsasl_initted) {
+               if (isServer) {
+                       SASLServerInitPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_server_init") );
+                       if (SASLServerInitPtr != nil) {
+                       sasl_callback_t *new_callbacks = NULL;
+                               if (callbacks)
+                                       new_callbacks = GetCFMCallbacks(callbacks);
+                               result = SASLServerInitPtr(new_callbacks, appname);
+                               saslcfmglob.serverCallbacks = new_callbacks;
+                       }
+               } else {
+                       SASLClientInitPtr = (void*)CFBundleGetFunctionPointerForName(
+                                               saslcfmglob.myBundle, CFSTR("sasl_client_init") );
+                       if (SASLClientInitPtr != nil) {
+                       sasl_callback_t *new_callbacks = NULL;
+                               if (callbacks)
+                                       new_callbacks = GetCFMCallbacks(callbacks);
+                               result = SASLClientInitPtr(new_callbacks);
+                               saslcfmglob.clientCallbacks = new_callbacks;
+                       }
+               }
+       }
+       return result;
+}
+
+int sasl_server_init(const sasl_callback_t *callbacks,
+                                const char *appname)
+{
+       return _cfmsasl_common_init(callbacks, true, appname);
+}
+
+int sasl_client_init(const sasl_callback_t *callbacks)
+{
+       return _cfmsasl_common_init(callbacks, false, nil);
+}
+
+void sasl_done(void)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.SASLDonePtr) return;
+
+       saslcfmglob.SASLDonePtr();
+       DisposeCFMCallbacks(saslcfmglob.clientCallbacks);
+       DisposeCFMCallbacks(saslcfmglob.serverCallbacks);
+       CFBundleUnloadExecutable(saslcfmglob.myBundle);
+       CFRelease(saslcfmglob.myBundle);
+       CFRelease(saslcfmglob.bundleURL);
+       saslcfmglob.myBundle = NULL;
+       saslcfmglob.bundleURL = NULL;
+
+        _cfmsasl_initted = 0;
+}
+
+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)
+{
+       sasl_callback_t *new_ps = NULL;
+       int result;
+       cfm_sasl_conn_t *myconn;
+
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLClientNewPtr) return SASL_NOMEM;
+
+       if (prompt_supp)
+               new_ps = GetCFMCallbacks(prompt_supp);
+
+// this is commented out because sasl.h incorrectly described the api
+//     if (*pconn)
+//             DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
+//     else {
+       myconn = (cfm_sasl_conn_t *) NewPtr(sizeof(cfm_sasl_conn_t));
+       if (myconn == NULL) {
+               return SASL_NOMEM;
+       }
+
+       myconn->ctx = NULL;
+//     }
+
+       result = saslcfmglob.SASLClientNewPtr(service, serverFQDN, iplocalport,
+                               ipremoteport, new_ps, flags,
+                               &(myconn->ctx));
+       myconn->cbk = new_ps;
+
+       *pconn = (sasl_conn_t *)myconn;
+
+       return result;
+}
+
+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)
+{
+       sasl_callback_t *new_ps = NULL;
+       int result;
+
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLServerNewPtr) return SASL_NOMEM;
+
+       if (callbacks)
+               new_ps = GetCFMCallbacks(callbacks);
+       *pconn = (sasl_conn_t *)NewPtr(sizeof(cfm_sasl_conn_t));
+       ((cfm_sasl_conn_t *)*pconn)->ctx = nil;
+
+       result = saslcfmglob.SASLServerNewPtr(service, serverFQDN, user_realm,
+                               iplocalport, ipremoteport, new_ps, flags,
+                               &((cfm_sasl_conn_t *)*pconn)->ctx);
+       ((cfm_sasl_conn_t *)*pconn)->cbk = new_ps;
+
+       return result;
+}
+
+void sasl_dispose(sasl_conn_t **pconn)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.SASLDisposePtr) return;
+
+       if (!pconn) return;
+       if (!*pconn) return;
+
+       saslcfmglob.SASLDisposePtr(&((cfm_sasl_conn_t *)*pconn)->ctx);
+       DisposeCFMCallbacks(((cfm_sasl_conn_t *)*pconn)->cbk);
+       DisposePtr((Ptr)*pconn);
+       *pconn = NULL;
+}
+
+int sasl_client_start (sasl_conn_t *conn,
+                                               const char *mechlist,
+                                               sasl_interact_t **prompt_need,
+                                               const char **clientout,
+                                               unsigned *clientoutlen,
+                                               const char **mech)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLClientStartPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLClientStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mechlist,
+                               prompt_need, clientout, clientoutlen, mech);
+}
+
+int sasl_client_step (sasl_conn_t *conn,
+                                               const char *serverin,
+                                               unsigned serverinlen,
+                                               sasl_interact_t **prompt_need,
+                                               const char **clientout,
+                                               unsigned *clientoutlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLClientStepPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLClientStepPtr(((cfm_sasl_conn_t *)conn)->ctx, serverin,
+                                                       serverinlen, prompt_need, clientout, clientoutlen);
+}
+
+const char *sasl_errstring(int saslerr,
+                                                       const char *langlist,
+                                                       const char **outlang)
+{
+       if (!_cfmsasl_initted)
+               return NULL;
+       if (!saslcfmglob.SASLErrStringPtr) return NULL;
+
+       return saslcfmglob.SASLErrStringPtr(saslerr, langlist, outlang);
+}
+
+const char *sasl_errdetail(sasl_conn_t *conn)
+{
+       if (!_cfmsasl_initted)
+               return NULL;
+       if (!saslcfmglob.sasl_errdetailPtr) return NULL;
+
+       return saslcfmglob.sasl_errdetailPtr(((cfm_sasl_conn_t *)conn)->ctx);
+}
+
+int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLGetPropPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLGetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, pvalue);
+}
+
+int sasl_setprop(sasl_conn_t *conn,
+                                       int propnum,
+                                       const void *value)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLSetPropPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLSetPropPtr(((cfm_sasl_conn_t *)conn)->ctx, propnum, value);
+}
+
+int sasl_idle(sasl_conn_t *conn)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLIdlePtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLIdlePtr(((cfm_sasl_conn_t *)conn)->ctx);
+}
+
+int sasl_encode(sasl_conn_t *conn,
+                               const char *input, unsigned inputlen,
+                               const char **output, unsigned *outputlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLEncodePtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLEncodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
+                                                                                       output, outputlen);
+}
+
+int sasl_encodev(sasl_conn_t *conn,
+                            const struct iovec *invec, unsigned numiov,
+                            const char **output, unsigned *outputlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLEncodeVPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLEncodeVPtr(((cfm_sasl_conn_t *)conn)->ctx, invec, numiov,
+                                                                                       output, outputlen);
+}
+
+int sasl_decode(sasl_conn_t *conn,
+                               const char *input, unsigned inputlen,
+                               const char **output, unsigned *outputlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLDecodePtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLDecodePtr(((cfm_sasl_conn_t *)conn)->ctx, input, inputlen,
+                                                                                       output, outputlen);
+}
+
+int sasl_decode64(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_decode64Ptr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_decode64Ptr(in, inlen, out, outmax, outlen);
+}
+
+int sasl_encode64(const char *in, unsigned inlen,
+                             char *out, unsigned outmax, unsigned *outlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_encode64Ptr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_encode64Ptr(in, inlen, out, outmax, outlen);
+}
+
+void sasl_set_alloc(sasl_malloc_t *ma, sasl_calloc_t *ca, sasl_realloc_t *rea, sasl_free_t *fr)
+{
+       if (_cfmsasl_haveCustomAlloc) {
+               DisposePtr((Ptr)saslcfmglobp.custMalloc);
+               DisposePtr((Ptr)saslcfmglobp.custCalloc);
+               DisposePtr((Ptr)saslcfmglobp.custRealloc);
+               DisposePtr((Ptr)saslcfmglobp.custFree);
+       }
+       saslcfmglobp.custMalloc = MachOFunctionPointerForCFMFunctionPointer(ma);
+       saslcfmglobp.custCalloc = MachOFunctionPointerForCFMFunctionPointer(ca);
+       saslcfmglobp.custRealloc = MachOFunctionPointerForCFMFunctionPointer(rea);
+       saslcfmglobp.custFree = MachOFunctionPointerForCFMFunctionPointer(fr);
+       _cfmsasl_haveCustomAlloc = 1;
+}
+
+int sasl_mkchal(sasl_conn_t *conn, char *buf,
+                           unsigned maxlen, unsigned hostflag)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_mkchalPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_mkchalPtr(((cfm_sasl_conn_t *)conn)->ctx, buf, maxlen, hostflag);
+}
+
+int sasl_utf8verify(const char *str, unsigned len)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_utf8verifyPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_utf8verifyPtr(str, len);
+}
+
+void sasl_churn(sasl_rand_t *rpool, 
+                           const char *data,
+                           unsigned len)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.sasl_churnPtr) return;
+
+       saslcfmglob.sasl_churnPtr(rpool, data, len);
+}
+
+void sasl_rand(sasl_rand_t *rpool,
+                          char *buf,
+                          unsigned len)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.sasl_randPtr) return;
+
+       saslcfmglob.sasl_randPtr(rpool, buf, len);
+}
+
+void sasl_randseed(sasl_rand_t *rpool,
+                              const char *seed,
+                              unsigned len)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.sasl_randseedPtr) return;
+
+       saslcfmglob.sasl_randseedPtr(rpool, seed, len);
+}
+
+void sasl_randfree(sasl_rand_t **rpool)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.sasl_randfreePtr) return;
+
+       saslcfmglob.sasl_randfreePtr(rpool);
+}
+
+int sasl_randcreate(sasl_rand_t **rpool)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_randcreatePtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_randcreatePtr(rpool);
+}
+
+void sasl_set_mutex(sasl_mutex_alloc_t *mn, sasl_mutex_lock_t *ml,
+                                sasl_mutex_unlock_t *mu, sasl_mutex_free_t *md)
+{
+       if (_cfmsasl_haveCustomMutex) {
+               DisposePtr((Ptr)saslcfmglobp.custMutexNew);
+               DisposePtr((Ptr)saslcfmglobp.custMutexLock);
+               DisposePtr((Ptr)saslcfmglobp.custMutexUnlock);
+               DisposePtr((Ptr)saslcfmglobp.custMutexDispose);
+       }
+       saslcfmglobp.custMutexNew = MachOFunctionPointerForCFMFunctionPointer(mn);
+       saslcfmglobp.custMutexLock = MachOFunctionPointerForCFMFunctionPointer(ml);
+       saslcfmglobp.custMutexUnlock = MachOFunctionPointerForCFMFunctionPointer(mu);
+       saslcfmglobp.custMutexDispose = MachOFunctionPointerForCFMFunctionPointer(md);
+       _cfmsasl_haveCustomMutex = 1;
+}
+
+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)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_listmechPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_listmechPtr(((cfm_sasl_conn_t *)conn)->ctx, user, prefix, sep,
+                                                                                       suffix, result, plen, pcount);
+}
+
+int sasl_server_start(sasl_conn_t *conn,
+                                 const char *mech,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLServerStartPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLServerStartPtr(((cfm_sasl_conn_t *)conn)->ctx, mech, clientin,
+                                                                                       clientinlen, serverout, serveroutlen);
+}
+
+int sasl_server_step(sasl_conn_t *conn,
+                    const char *clientin,
+                    unsigned clientinlen,
+                    const char **serverout,
+                    unsigned *serveroutlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.SASLServerStepPtr) return SASL_NOMEM;
+
+       return saslcfmglob.SASLServerStepPtr(((cfm_sasl_conn_t *)conn)->ctx, clientin, clientinlen,
+                                                                                       serverout, serveroutlen);
+}
+
+int sasl_checkpass(sasl_conn_t *conn,
+                              const char *user,
+                              unsigned userlen,
+                              const char *pass,
+                              unsigned passlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_checkpassPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_checkpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, userlen, pass,
+                                                                                       passlen);
+}
+
+int sasl_user_exists(sasl_conn_t *conn,
+                        const char *service,
+                    const char *user_realm,
+                    const char *user)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_user_existsPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_user_existsPtr(((cfm_sasl_conn_t *)conn)->ctx,
+                                                                                               service, user_realm, user);
+}
+
+int sasl_setpass(sasl_conn_t *conn,
+                const char *user,
+                const char *pass,
+                unsigned passlen,
+                const char *oldpass, unsigned oldpasslen,
+                unsigned flags)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_setpassPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_setpassPtr(((cfm_sasl_conn_t *)conn)->ctx, user, pass,
+                                                                                       passlen, oldpass, oldpasslen, flags);
+}
+
+int sasl_checkapop(sasl_conn_t *conn,
+                              const char *challenge, unsigned challen,
+                              const char *response, unsigned resplen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_checkapopPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_checkapopPtr(((cfm_sasl_conn_t *)conn)->ctx, challenge, challen,
+                                                                                               response, resplen);
+}
+
+int sasl_auxprop_request(sasl_conn_t *conn,
+                                    const char **propnames)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.sasl_auxprop_requestPtr) return SASL_NOMEM;
+
+       return saslcfmglob.sasl_auxprop_requestPtr(((cfm_sasl_conn_t *)conn)->ctx, propnames);
+}
+
+struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn)
+{
+       if (!_cfmsasl_initted)
+               return NULL;
+       if (!saslcfmglob.sasl_auxprop_getctxPtr) return NULL;
+
+       return saslcfmglob.sasl_auxprop_getctxPtr(((cfm_sasl_conn_t *)conn)->ctx);
+}
+
+void sasl_erasebuffer(char *pass, unsigned len)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.sasl_erasebufferPtr) return;
+
+       saslcfmglob.sasl_erasebufferPtr(pass, len);
+}
+
+struct propctx *prop_new(unsigned estimate)
+{
+       if (!_cfmsasl_initted)
+               return NULL;
+       if (!saslcfmglob.prop_newPtr) return NULL;
+
+       return saslcfmglob.prop_newPtr(estimate);
+}
+
+int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.prop_dupPtr) return SASL_NOMEM;
+
+       return saslcfmglob.prop_dupPtr(src_ctx, dst_ctx);
+}
+
+const struct propval *prop_get(struct propctx *ctx)
+{
+       if (!_cfmsasl_initted)
+               return NULL;
+       if (!saslcfmglob.prop_getPtr) return NULL;
+
+       return saslcfmglob.prop_getPtr(ctx);
+}
+
+int prop_getnames(struct propctx *ctx, const char **names,
+                 struct propval *vals)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.prop_getnamesPtr) return SASL_NOMEM;
+
+       return saslcfmglob.prop_getnamesPtr(ctx, names, vals);
+}
+
+void prop_clear(struct propctx *ctx, int requests)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.prop_clearPtr) return;
+
+       saslcfmglob.prop_clearPtr(ctx, requests);
+}
+
+void prop_erase(struct propctx *ctx, const char *name)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.prop_erasePtr) return;
+
+       saslcfmglob.prop_erasePtr(ctx, name);
+}
+
+void prop_dispose(struct propctx **ctx)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob.prop_disposePtr) return;
+
+       saslcfmglob.prop_disposePtr(ctx);
+}
+
+int prop_format(struct propctx *ctx, const char *sep, int seplen,
+               char *outbuf, unsigned outmax, unsigned *outlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.prop_formatPtr) return SASL_NOMEM;
+
+       return saslcfmglob.prop_formatPtr(ctx, sep, seplen, outbuf, outmax, outlen);
+}
+
+int prop_set(struct propctx *ctx, const char *name,
+            const char *value, int vallen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.prop_setPtr) return SASL_NOMEM;
+
+       return saslcfmglob.prop_setPtr(ctx, name, value, vallen);
+}
+
+int prop_setvals(struct propctx *ctx, const char *name,
+                const char **values)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob.prop_setvalsPtr) return SASL_NOMEM;
+
+       return saslcfmglob.prop_setvalsPtr(ctx, name, values);
+}
+
+/* internal functions used by sasl_seterror follow */
+int _sasl_add_string(char **out, int *alloclen, int *outlen, const char *add)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob._sasl_add_stringPtr) return SASL_NOMEM;
+
+       return saslcfmglob._sasl_add_stringPtr(out, alloclen, outlen, add);
+}
+
+int _buf_alloc(char **rwbuf, unsigned *curlen, unsigned newlen)
+{
+       if (!_cfmsasl_initted)
+               return SASL_NOMEM;
+       if (!saslcfmglob._buf_allocPtr) return SASL_NOMEM;
+
+       return saslcfmglob._buf_allocPtr(rwbuf, curlen, newlen);
+}
+
+void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, unsigned **lenhdl)
+{
+       if (!_cfmsasl_initted)
+               return;
+       if (!saslcfmglob._sasl_add_stringPtr) return;
+
+       saslcfmglob._sasl_get_errorbufPtr(((cfm_sasl_conn_t *)conn)->ctx, bufhdl, lenhdl);
+}
diff --git a/mac/osx_cfm_glue/cfmglue.h b/mac/osx_cfm_glue/cfmglue.h
new file mode 100644 (file)
index 0000000..345405a
--- /dev/null
@@ -0,0 +1,4 @@
+#define TARGET_API_MAC_CARBON 1
+#define SASL_OSX_CFMGLUE 1
+
+#include <CarbonHeaders.c>
\ No newline at end of file
diff --git a/mac/osx_cfm_glue/cfmglue.proj b/mac/osx_cfm_glue/cfmglue.proj
new file mode 100755 (executable)
index 0000000..8f37fbe
Binary files /dev/null and b/mac/osx_cfm_glue/cfmglue.proj differ
diff --git a/mac/osx_cfm_glue/cfmglue.proj.exp b/mac/osx_cfm_glue/cfmglue.proj.exp
new file mode 100755 (executable)
index 0000000..374a70e
--- /dev/null
@@ -0,0 +1,48 @@
+sasl_decode
+sasl_encode
+sasl_idle
+sasl_setprop
+sasl_getprop
+sasl_errstring
+sasl_client_step
+sasl_client_start
+sasl_dispose
+sasl_client_new
+sasl_done
+sasl_client_init
+sasl_encode64
+sasl_decode64
+sasl_set_alloc
+sasl_mkchal
+sasl_utf8verify
+sasl_churn
+sasl_rand
+sasl_randseed
+sasl_randfree
+sasl_randcreate
+sasl_set_mutex
+sasl_server_init
+sasl_server_new
+sasl_listmech
+sasl_server_start
+sasl_server_step
+sasl_checkpass
+sasl_user_exists
+sasl_setpass
+sasl_errdetail
+sasl_checkapop
+sasl_auxprop_request
+sasl_auxprop_getctx
+sasl_erasebuffer
+sasl_encodev
+prop_new
+prop_dup
+prop_get
+prop_getnames
+prop_clear
+prop_erase
+prop_dispose
+prop_format
+prop_set
+prop_setvals
+sasl_seterror
\ No newline at end of file
diff --git a/mac/readme/mac_testing_notes.c b/mac/readme/mac_testing_notes.c
new file mode 100755 (executable)
index 0000000..7829b62
--- /dev/null
@@ -0,0 +1,28 @@
+#ifdef RUBBISH
+
+*** how to run the server on unix
+./sample-server -s rcmd -i local=0.0.0.0:23,remote=0.0.0.0:23 -m KERBEROS_V4
+
+*** arguements to the client on the mac
+
+Use this to test privacy:
+-b min=56,max=20000 -i local=0.0.0.0:23,remote=0.0.0.0:23 -s rcmd -n AKUTAKTAK.ANDREW.CMU.EDU -u n3liw
+
+Use this to test authenticity:
+-b min=1,max=1 -i local=0.0.0.0:23,remote=0.0.0.0:23 -s rcmd -n AKUTAKTAK.ANDREW.CMU.EDU -u n3liw
+
+Use this to test authentication only (no privacy no authenticity):
+-i local=0.0.0.0:23,remote=0.0.0.0:23 -s rcmd -n AKUTAKTAK.ANDREW.CMU.EDU -u n3liw
+
+
+C: BAYAQU5EUkVXLkNNVS5FRFUAOCBx+Dj9fo8RD0Wegm7Qr2iSopuKxKGTq6cA6ux+lEPfB4GFO9BxF9jWOKLa5Hw/sIqkSfcqwah+hLFCUakVHcviUo7UOTHX0CFWy8QsnCuz6qco9FzlS23r
+
+- check lifetimes of data returned by kerberos glue functions
+  like realm of host and gethostbyname
+C: AAAAbAQGAEFORFJFVy5DTVUuRURVADggcfg4/X6PEQ9FnoJu0K9okqKbisShk6unYXiKjun/vccUEytAAMdTj1pLaQjd3hkDltVId4q9la64zfZG+haHMETI+kDpHzLAtABnUTl4NHvzjbuwfwdvSA==
+
+-e ssf=-57 -i local=128.2.121.100:23,remote=128.2.121.2:23 -s rcmd -n AKUTAKTAK.ANDREW.CMU.EDU -u n3liw
+
+#endif
+
+static int bletch_the_compiler_wants_something_non_empty;
diff --git a/mac/sc_shlb/sc_shlb b/mac/sc_shlb/sc_shlb
new file mode 100755 (executable)
index 0000000..93254b6
Binary files /dev/null and b/mac/sc_shlb/sc_shlb differ
diff --git a/mac/sc_shlb/sc_shlb.Carbon b/mac/sc_shlb/sc_shlb.Carbon
new file mode 100755 (executable)
index 0000000..9f707d5
Binary files /dev/null and b/mac/sc_shlb/sc_shlb.Carbon differ
diff --git a/mac/sc_shlb/sc_shlb.mono b/mac/sc_shlb/sc_shlb.mono
new file mode 100755 (executable)
index 0000000..06e1d00
Binary files /dev/null and b/mac/sc_shlb/sc_shlb.mono differ
diff --git a/mac/sc_shlb/sc_shlb.rsrc.sit.hqx b/mac/sc_shlb/sc_shlb.rsrc.sit.hqx
new file mode 100644 (file)
index 0000000..ed1b1bf
--- /dev/null
@@ -0,0 +1 @@
+(This file must be converted with BinHex 4.0)\r:%(0MAh0SE')ZFR0bBbjcDA3!8dP8090*9#%!N!3"%`#3"*!!G90dG@CQ5A3J+'-\rT-6Nj0bda16Ni)%&XB@4ND@iJ8hPcG'9YFb`J5@jM,L`JD(4dF$S[,hH3!bjKE'&\rNC'PZFhPc,Q0[E5p6G(9QCNPd,`d+'J!&%!!!!4-!N!0b!!%!N!0bX'30TD95CA0\rPFRCPC+@P!+@3"!%!!$`!!,H$@B1hJeQ6!*!0$*bL!*!1Ff0IFfKXBLjbFh*M!!(\rZbR*cFQ058d9%!*!3J!#3#3%f!*!$-`#3"!m!3X(8q2@S2N23-B('m2KI(pa#6DA\r+L,R'QSirQM+#,h*hGLHl$"kFM'&fKK1,Gciq4Tk!er-!!!:\r
\ No newline at end of file
diff --git a/mac/sc_shlb/sc_shlb_carbon.h b/mac/sc_shlb/sc_shlb_carbon.h
new file mode 100755 (executable)
index 0000000..21aa715
--- /dev/null
@@ -0,0 +1 @@
+#define TARGET_API_MAC_CARBON 1
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644 (file)
index 0000000..358a2b0
--- /dev/null
@@ -0,0 +1,59 @@
+# Makefile.am for SASL documentation
+#
+################################################################
+# Copyright (c) 2001 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.
+#
+################################################################
+
+man_MANS = sasl_authorize_t.3 sasl_done.3 sasl_listmech.3 sasl_callbacks.3 \
+           sasl_encode.3 sasl_encodev.3 sasl_log_t.3 sasl_checkpass.3 \
+           sasl_errstring.3 sasl_dispose.3 sasl_canon_user_t.3 \
+           sasl_server_init.3 sasl_client_init.3 sasl_getopt_t.3 \
+           sasl_server_new.3 sasl_client_new.3 sasl_getpath_t.3  \
+           sasl_server_start.3 sasl_client_start.3 sasl_getprop.3 \
+           sasl_server_step.3 sasl_client_step.3  sasl_getsecret_t.3 \
+           sasl_setprop.3 sasl_decode.3 sasl_getsimple_t.3 sasl.3 \
+          sasl_checkapop.3 sasl_errors.3 sasl_verifyfile_t.3 \
+          sasl_getrealm_t.3 sasl_chalprompt_t.3 sasl_auxprop_request.3 \
+          sasl_auxprop_getctx.3 sasl_auxprop.3 sasl_idle.3 \
+          sasl_errdetail.3 sasl_user_exists.3 sasl_setpass.3 \
+          sasl_server_userdb_checkpass_t.3 sasl_server_userdb_setpass_t.3 \
+          sasl_global_listmech.3 sasl_getconfpath_t.3
+
+EXTRA_DIST = $(man_MANS)
diff --git a/man/Makefile.in b/man/Makefile.in
new file mode 100644 (file)
index 0000000..171bb35
--- /dev/null
@@ -0,0 +1,452 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for SASL documentation
+#
+################################################################
+# Copyright (c) 2001 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+man_MANS = sasl_authorize_t.3 sasl_done.3 sasl_listmech.3 sasl_callbacks.3 \
+           sasl_encode.3 sasl_encodev.3 sasl_log_t.3 sasl_checkpass.3 \
+           sasl_errstring.3 sasl_dispose.3 sasl_canon_user_t.3 \
+           sasl_server_init.3 sasl_client_init.3 sasl_getopt_t.3 \
+           sasl_server_new.3 sasl_client_new.3 sasl_getpath_t.3  \
+           sasl_server_start.3 sasl_client_start.3 sasl_getprop.3 \
+           sasl_server_step.3 sasl_client_step.3  sasl_getsecret_t.3 \
+           sasl_setprop.3 sasl_decode.3 sasl_getsimple_t.3 sasl.3 \
+          sasl_checkapop.3 sasl_errors.3 sasl_verifyfile_t.3 \
+          sasl_getrealm_t.3 sasl_chalprompt_t.3 sasl_auxprop_request.3 \
+          sasl_auxprop_getctx.3 sasl_auxprop.3 sasl_idle.3 \
+          sasl_errdetail.3 sasl_user_exists.3 sasl_setpass.3 \
+          sasl_server_userdb_checkpass_t.3 sasl_server_userdb_setpass_t.3 \
+          sasl_global_listmech.3 sasl_getconfpath_t.3
+
+
+EXTRA_DIST = $(man_MANS)
+subdir = man
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+DIST_SOURCES =
+
+NROFF = nroff
+MANS = $(man_MANS)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  man/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+man3dir = $(mandir)/man3
+install-man3: $(man3_MANS) $(man_MANS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(man3dir)
+       @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.3*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+         else file=$$i; fi; \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           3*) ;; \
+           *) ext='3' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst"; \
+         $(INSTALL_DATA) $$file $(DESTDIR)$(man3dir)/$$inst; \
+       done
+uninstall-man3:
+       @$(NORMAL_UNINSTALL)
+       @list='$(man3_MANS) $(dist_man3_MANS) $(nodist_man3_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.3*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           3*) ;; \
+           *) ext='3' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " rm -f $(DESTDIR)$(man3dir)/$$inst"; \
+         rm -f $(DESTDIR)$(man3dir)/$$inst; \
+       done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(MANS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(man3dir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+       -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man: install-man3
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man3
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+       distclean distclean-generic distclean-libtool distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-man install-man3 install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
+       uninstall-info-am uninstall-man uninstall-man3
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/man/sasl.3 b/man/sasl.3
new file mode 100644 (file)
index 0000000..f8b19da
--- /dev/null
@@ -0,0 +1,61 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH SASL "10 July 2001" SASL "SASL man pages"
+.SH NAME
+SASL \- SASL authentication library
+.SH DESCRIPTION
+The CMU Cyrus SASL library is a general purpose authentication library for sever and client applications.
+
+.B System Administrators:
+
+For information on setting up/configuring the SASL library see the 
+.I System Administrators Guide
+in the doc/ directory of the SASL distribution.
+
+.B Programmers:
+
+See man pages for individual sasl functions or the
+.I Programmers Guide
+in the doc/ directory of the SASL distribution.
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl_authorize_t(3), sasl_auxprop(3), sasl_auxprop_getctx(3), sasl_auxprop_request(3), sasl_canon_user_t(3), sasl_callbacks(3), sasl_chalprompt_t(3), sasl_checkapop(3), sasl_checkpass(3), sasl_client_init(3), sasl_client_new(3), sasl_client_start(3), sasl_client_step(3), sasl_decode(3), sasl_dispose(3), sasl_done(3), sasl_encode(3), sasl_encodev(3), sasl_errdetail(3), sasl_errors(3), sasl_errstring(3), sasl_errors(3), sasl_getopt_t(3), sasl_getpath_t(3), sasl_getprop(3), sasl_getrealm_t(3), sasl_getsecret_t(3), sasl_getsimple_t(3), sasl_idle(3), sasl_listmech(3), sasl_log_t(3), sasl_server_init(3), sasl_server_new(3), sasl_server_start(3), sasl_server_step(3), sasl_server_userdb_checkpass_t(3), sasl_server_userdb_setpass_t(3), sasl_setpass(3), sasl_setprop(3), sasl_user_exists(3), sasl_verifyfile_t(3), sasl_global_listmech(3)
diff --git a/man/sasl_authorize_t.3 b/man/sasl_authorize_t.3
new file mode 100644 (file)
index 0000000..40b3289
--- /dev/null
@@ -0,0 +1,76 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_authorize_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_authorize_t \- The SASL authorization callback
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_authorize_t(void " *context ", "
+.BI "                    const char " *requested_user ", unsigned " alen ","
+.BI "                    const char " *auth_identity ", unsigned " alen ","
+.BI "                    const char " *def_realm ", unsigned " urlen ","
+.BI "                    struct propctx " *propctx ") "
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_authorize_t
+is used to check whether the authorized user
+.I auth_identity
+may act as the user
+.I requested_user.
+For example the user root may wish to authenticate with his
+credentials but act as the user tmartin (with all of tmartin's rights
+not roots). A server application should be very careful, and probably
+err on the side of caution, when determining which users may proxy as
+whom.
+.PP
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3)
\ No newline at end of file
diff --git a/man/sasl_auxprop.3 b/man/sasl_auxprop.3
new file mode 100644 (file)
index 0000000..60f27a4
--- /dev/null
@@ -0,0 +1,213 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_auxprop "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_auxprop \- How to work with SASL auxiliary properties
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/prop.h>
+
+.BI "struct propctx *prop_new(unsigned " estimate ") "
+
+.BI "int prop_dup(struct propctx " *src_ctx ", "
+.BI "             struct propctx " *dst_ctx ")"
+
+.BI "int prop_request(struct propctx " *ctx ", "
+.BI "                 const char " **names ")"
+
+.BI "const struct propval *prop_get(struct propctx " *ctx ")"
+
+.BI "int prop_getnames(struct propctx " *ctx ", const char " **names ","
+.BI "                  struct porpval " *vals ")"
+
+.BI "void prop_clear(struct propctx " *ctx ", int " requests ")"
+
+.BI "void prop_erase(struct propctx " *ctx ", const char " *name ")"
+
+.BI "void prop_dispose(struct propctx " **ctx ")"
+
+.BI "int prop_format(struct propctx " *ctx ", const char " *sep ", int " seplen ", "
+.BI "                char " *outbuf ", unsigned " outmax ", unsigned " *outlen ")"
+
+.BI "int prop_set(struct propctx " *ctx ", const char " *name ","
+.BI "             const char " *value ", int " vallen ")"
+
+.BI "int prop_setvals(struct propctx " *ctx ", const char " *name ","
+.BI "                 const char " **values ")"
+.SH DESCRIPTION
+
+.B SASL auxiliary properties
+are used to obtain properties from external sources during the authentication
+process.  For example, a mechanism might need to query an LDAP server to
+obtain the authentication secret.  The application probably needs other
+information from there as well, such as home directory or UID.  The
+auxiliary property interface allows the two to cooperate, and only results
+in a single query against the LDAP server (or other property sources).
+
+Property lookups take place directly after user canonicalization occurs.
+Therefore, all requests should be registered with he context before that
+time.  Note that requests can also be registered using the
+sasl_auxprop_request(3) function.  Most of the functions listed below, 
+however, require a property context which can be obtained by calling
+sasl_auxprop_getctx(3).
+
+.SH API Description
+.TP 0.8i
+struct propctx *prop_new(unsigned estimate)
+Create a new property context.  Probably unnecessary for application
+developers to call this at any point.
+
+.I estimate
+is the estimate of storage needed total for requests & responses.
+A value of 0 will imply the library default.
+
+.TP 0.8i
+int prop_dup(struct propctx *src_ctx, struct propctx *dst_ctx)
+
+Duplicate a given property context.
+
+.TP 0.8i
+int prop_request(struct propctx *ctx, const char **names)
+
+Add properties to the request list of a given context.
+
+.I names
+is the NULL-terminated array of property names, and must persist until
+the requests are cleared or the context is disposed of with a call
+to prop_dispose.
+
+.TP 0.8i
+const struct propval *prop_get(struct propctx *ctx)
+
+Returns a NULL-terminated array of struct propval from the given context.
+
+.TP 0.8i
+int prop_getnames(struct propctx *ctx, const char **names,
+                  struct porpval *vals)
+
+Fill in a (provided) array of struct propval based on a list of property
+names.  This implies that the vals array is at least as long as the
+names array. The values that are filled in by this call
+persist until next call to prop_request, prop_clear,
+or prop_dispose on context.  If a name specified here was never requested,
+that its associated values entry will be set to NULL.
+
+Returns number of matching properties that were found, or a SASL error code.
+
+.TP 0.8i
+void prop_clear(struct propctx *ctx, int requests)
+
+Clear values and optionally requests from a property context.
+
+.I requests
+is 1 if the requests should be cleared, 0 otherwise.
+
+.TP 0.8i
+void prop_erase(struct propctx *ctx, const char *name)
+
+Securely erase the value of a property.
+
+.I name
+is the name of the property to erase.
+
+.TP 0.8i
+void prop_dispose(struct propctx **ctx)
+
+Disposes of a property context and NULLifys the pointer.
+
+.TP 0.8i
+int prop_format(struct propctx *ctx, const char *sep, int seplen,
+                char *outbuf, unsigned outmax, unsigned *outlen)
+
+Format the requested property names into a string.  This not intended
+for use by the application (only by auxprop plugins).
+
+.I sep
+Is the separator to use for the string
+
+.I outbuf
+Is the caller-allocated buffer of length
+.I outmax
+that the resulting string will be placed in (including NUL terminator).
+
+.I outlen
+if non-NULL, will contain the length of the resulting string (excluding NUL terminator).
+
+.TP 0.8i
+int prop_set(struct propctx *ctx, const char *name, const char *value,
+             int vallen)
+
+Adds a property value to the context.  This is intended for use by auxprop
+plugins only.
+
+.I name
+is the name of the property to receive the new value, or NULL, which
+implies that the value will be added to the same property as the last
+call to either prop_set or prop_setvals.
+
+.I value
+is a value for the property of length
+.I vallen
+
+.TP 0.8i
+int prop_setvals(struct propctx *ctx, const char *name, const char **values)
+
+Adds multiple values to a single property.  This is intended for use by
+auxprop plugins only.
+
+.I name
+has the same meaning as in 
+.B prop_set
+
+.I values
+are a NULL-terminated array of values to be added the property.
+
+.SH "RETURN VALUE"
+The property functions that return an int return SASL error codes.
+See sasl_errors(3).  Those that return pointers will return a valid pointer
+on success, or NULL on any error.
+
+.SH "CONFORMING TO"
+RFC 2222
+
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_auxprop_request(3), sasl_auxprop_getctx(3)
diff --git a/man/sasl_auxprop_getctx.3 b/man/sasl_auxprop_getctx.3
new file mode 100644 (file)
index 0000000..6dce5e1
--- /dev/null
@@ -0,0 +1,69 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_auxprop_getctx "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_auxprop_getctx \- Acquire an auxiliary property context
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_auxprop_getctx(sasl_conn_t " *conn ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_auxprop_getctx
+will return an auxiliary property context for the given sasl_conn_t on which
+the functions described in sasl_auxprop(3) can operate.
+
+.I conn
+the sasl_conn_t for which the request is being made.
+
+.SH "RETURN VALUE"
+Returns a pointer the the context on success.  Returns NULL on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_auxprop(3), sasl_auxprop_request(3)
\ No newline at end of file
diff --git a/man/sasl_auxprop_request.3 b/man/sasl_auxprop_request.3
new file mode 100644 (file)
index 0000000..fb92c46
--- /dev/null
@@ -0,0 +1,78 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_auxprop_request "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_auxprop_request \- Request Auxiliary Properties from SASL
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_auxprop_request(sasl_conn_t " *conn ", "
+.BI "                        const char ** " propnames ")" 
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_auxprop_request
+will request that the SASL library obtain properties from any auxiliary
+property plugins that might be installed (such as the user's home directory
+from an LDAP server for example).  Such lookup occurs just after username
+canonicalization is complete.  Therefore, the request should be made before
+the call to sasl_server_start(3), but after the call to sasl_server_new(3).
+
+.I conn
+the sasl_conn_t for which the request is being made.
+
+.I propnames
+a NULL-terminated array of property names to request.  Note that this
+array must persist until a call to sasl_dispose on the sasl_conn_t.
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success.  See sasl_errors(3) for meanings of other return
+codes.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_auxprop(3), sasl_auxprop_getctx(3),
+sasl_server_new(3), sasl_server_start(3)
diff --git a/man/sasl_callbacks.3 b/man/sasl_callbacks.3
new file mode 100644 (file)
index 0000000..6335889
--- /dev/null
@@ -0,0 +1,125 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2006 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.
+.\" 
+.TH sasl_callbacks "12 February 2006" SASL "SASL man pages"
+.SH NAME
+sasl_callbacks \- How to work with SASL callbacks
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_callbacks
+are used when the application needs some information from the
+application. Common reasons are getting for getting usernames and
+passwords. A client MUST specify what callbacks they support in the
+sasl_client/server_init() or sasl_client/server_new() calls. If an
+authentication mechanism needs a callback that the application does
+not state it supports it cannot be used. 
+
+If a callback has an
+.B id
+parameter that should be checked to make sure you are giving the appropriate value.
+
+If an application is using the client side of the library functions to handle the callbacks are not necessary. Instead the application may deal with callbacks via SASL_INTERACT's. See sasl_client_start/step() for more information.
+
+The list of callbacks follows:
+
+.SH Common Callbacks
+.TP 0.8i
+sasl_getopt_t
+Get an option value
+.TP 0.8i
+sasl_log_t
+Log message handler
+.TP 0.8i
+sasl_getpath_t
+Get path to search for plugins (e.g. SASL mechanisms)
+.TP 0.8i
+sasl_verifyfile_t
+Verify files for use by SASL
+.TP 0.8i
+sasl_canon_user_t
+Username canonicalization function.
+
+.SH Client-only Callbacks
+.TP 0.8i
+sasl_getsimple_t
+Get user/language list
+.TP 0.8i
+sasl_getsecret_t
+Get authentication secret
+.TP 0.8i
+sasl_chalprompt_t
+Display challenge and prompt for response
+.TP 0.8i
+sasl_getrealm_t
+Get the realm for authentication
+
+.SH Server-only Callbacks
+.TP 0.8i
+sasl_authorize_t
+Authorize policy callback
+.TP 0.8i
+sasl_server_userdb_checkpass_t
+verify plaintext password
+.TP 0.8i
+sasl_server_userdb_setpass_t
+set plaintext password
+.TP 0.8i
+sasl_getconfpath_t
+Get path to search for SASL configuration file (server side only). New in SASL 2.1.22.
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK typically indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_authorize_t(3), sasl_log_t(3), sasl_getpath_t(3),
+sasl_getconfpath_t(3), sasl_verifyfile_t(3), sasl_canon_user_t(3), sasl_getsimple(3),
+sasl_getsecret_t(3), sasl_chalprompt_t(3), sasl_getrealm_t(3),
+sasl_authorize_t(3), sasl_server_userdb_checkpass_t(3),
+sasl_server_userdb_setpass_t(3)
diff --git a/man/sasl_canon_user_t.3 b/man/sasl_canon_user_t.3
new file mode 100644 (file)
index 0000000..5fea87f
--- /dev/null
@@ -0,0 +1,94 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_userdb_checkpass_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_userdb_checkpass_t \- Plaintext Password Verification Callback
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_canon_user_t(sasl_conn_t " *conn ","
+.BI "                      void " *context ","
+.BI "                     const char " *user ", unsigned " ulen ","
+.BI "                      unsigned " flags ","
+.BI "                      const char " *user_realm ","
+.BI "                      char " *out_user ", unsigned " out_umax ","
+.BI "                      unsigned " *out_ulen ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_canon_user_t
+Is the callback for an application-supplied user canonicalization function.
+This function is subject to the requirements that all user canonicalization
+functions are: It must copy the result into the output buffers, but the
+output buffers and the input buffers may be the same.
+
+.I context
+context from the callback record
+
+.I user
+and
+.I ulen
+Un-canonicalized username (and length)
+
+.I flags
+Either SASL_CU_AUTHID (indicating the authentication ID is being canonicalized)
+or SASL_CU_AUTHZID (indicating the authorization ID is to be canonicalized)
+or a bitwise OR of the the two.
+
+.I user_realm
+Realm of authentication.
+
+.I out_user
+and
+.I out_umax
+and
+.I out_ulen
+The output buffer, max length, and actual length for the username.
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
diff --git a/man/sasl_chalprompt_t.3 b/man/sasl_chalprompt_t.3
new file mode 100644 (file)
index 0000000..54212b8
--- /dev/null
@@ -0,0 +1,86 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_chalprompt_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_chalprompt_t \- Realm Acquisition Callback
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_chalprompt_t(void " *context ", int " id ", "
+.BI "                     const char " *challenge ","
+.BI "                      const char " *prompt ", const char " *defresult ","
+.BI "                      const char " **result ", unsigned " *len ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_chalprompt_t
+is used to prompt for input in response to a server challenge.
+
+.I context
+context from the callback record
+
+.I id
+callback id (either SASL_CB_ECHOPROMPT or SASL_CB_NOECHOPROMPT)
+
+.I challenge
+the server's challenge
+
+.I prompt
+A prompt for the user
+
+.I defresult
+Default result (may be NULL)
+
+.I result
+The user's response (a NUL terminated string)
+
+.I len
+Length of the user's response.
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3)
\ No newline at end of file
diff --git a/man/sasl_checkapop.3 b/man/sasl_checkapop.3
new file mode 100644 (file)
index 0000000..74abd8a
--- /dev/null
@@ -0,0 +1,79 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_checkapop "29 June 2001" SASL "SASL man pages"
+.SH NAME
+sasl_checkapop \- Check an APOP challenge/response
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.BI "int sasl_checkapop(sasl_conn_t *" conn ", "
+.BI "                 const char *" challenge ", "
+.BI "                 unsigned " challen ", "
+.BI "                 const char *" response ", "
+.BI "                 unsigned " resplen "); "
+
+.SH DESCRIPTION
+
+.B sasl_checkapop()
+will check an APOP challenge/response.  APOP is an optional POP3 (RFC 1939)
+authentication command which uses a shared secret (password). The password is
+stored in the SASL secrets database.  For information on the SASL shared
+secrets database see the
+.I System Administrators Guide
+in the doc/ directory of the SASL distribution.
+.sp
+If called with a
+.BI "NULL" " challenge" ","
+.B sasl_checkapop()
+will check to see if the APOP mechanism is enabled.
+
+.SH "RETURN VALUE"
+sasl_checkapop returns an integer which corresponds to one of the
+following codes. SASL_OK indicates that the authentication is
+complete. All other return codes indicate errors and should either be
+handled or the authentication session should be quit.  See sasl_errors(3)
+for meanings of return codes.
+
+.SH "CONFORMING TO"
+RFC 2222, RFC 1939
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3)
\ No newline at end of file
diff --git a/man/sasl_checkpass.3 b/man/sasl_checkpass.3
new file mode 100644 (file)
index 0000000..f383bda
--- /dev/null
@@ -0,0 +1,71 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_checkpass "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_checkpass \- Check a plaintext password
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.BI "int sasl_checkpass(sasl_conn_t *" conn ", "
+.BI "                 const char *" user ", "
+.BI "                 unsigned " userlen ", "
+.BI "                 const char *" pass ", "
+.BI "                 unsigned " passlen "); "
+
+.SH DESCRIPTION
+
+.B sasl_checkpass()
+will check a plaintext password. This is needed for protocols that had a login method before SASL (for example the LOGIN command in IMAP). The password is checked with the
+.I pwcheck_method
+See sasl_callbacks(3) for information on how this parameter is set.
+
+.SH "RETURN VALUE"
+sasl_checkpass returns an integer which corresponds to one of the
+following codes. SASL_OK indicates that the authentication is
+complete. All other return codes indicate errors and should either be
+handled or the authentication session should be quit.  See sasl_errors(3)
+for meanings of return codes.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_callbacks(3), sasl_setpass(3)
diff --git a/man/sasl_client_init.3 b/man/sasl_client_init.3
new file mode 100644 (file)
index 0000000..ecdd775
--- /dev/null
@@ -0,0 +1,88 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_client_init "21 June 2001" SASL "SASL man pages"
+.SH NAME
+sasl_client_init \- SASL client authentication initialization
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_client_init(const  sasl_callback_t " *callbacks ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_client_init()
+initializes SASL. It must be called before any calls to
+sasl_client_start. This call initializes all SASL client drivers
+(e.g. authentication mechanisms). These are usually found in the
+/usr/lib/sasl2 directory but the directory may be overridden with the
+SASL_PATH environment variable.
+.PP
+.I callbacks
+specifies the base callbacks for all client connections. See the sasl_callbacks man page for more information
+.SH "RETURN VALUE"
+sasl_client_init returns an integer which corresponds to one of the
+following codes. SASL_OK is the only one that indicates success. All
+others indicate errors and should either be handled or the
+authentication session should be quit.
+
+
+.SH ERRORS
+.TP 0.8i
+.B SASL_OK
+Success
+.TP 0.8i
+.B SASL_BADVERS
+Mechanism version mismatch
+.TP 0.8i
+.B SASL_BADPARAM
+Error in config file
+.TP 0.8i
+.B SASL_NOMEM
+Not enough memory to complete operation
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_client_new(3), sasl_client_start(3), sasl_client_step(3)
diff --git a/man/sasl_client_new.3 b/man/sasl_client_new.3
new file mode 100644 (file)
index 0000000..00d0dfc
--- /dev/null
@@ -0,0 +1,127 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_client_new "21 June 2001" SASL "SASL man pages"
+.SH NAME
+sasl_client_new \- Create a new client authentication object
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_client_new(const char " *service ", "
+.BI "                   const char " *serverFQDN ", "
+.BI "                   const char " *iplocalport ", "
+.BI "                   const char " *ipremoteport ", "
+.BI "                   const sasl_callback_t " *prompt_supp,
+.BI "                   unsigned " flags ", "
+.BI "                   sasl_conn_t ** " pconn ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_client_new()
+creates a new SASL context. This context will be used for all SASL calls for one connection. It handles both authentication and integrity/encryption layers after authentication.
+.PP
+.I service
+is the registered name of the service (usually the protocol name) using SASL (e.g. "imap").
+.PP
+.I serverFQDN
+is the fully qualified domain name of the server (e.g. "serverhost.cmu.edu").
+.PP
+.I iplocalport
+is the IP and port of the local side of the connection, or NULL.  If
+iplocalport is NULL it will disable mechanisms that require IP address
+information.  This strings must be in one of the following formats:
+"a.b.c.d;port" (IPv4), "e:f:g:h:i:j:k:l;port" (IPv6),
+or "e:f:g:h:i:j:a.b.c.d;port" (IPv6)
+.PP
+.I ipremoteport
+is the IP and port of the remote side of the connection, or NULL (see
+iplocalport)
+.PP
+.I prompt_supp
+is a list of client interactions supported that is unique to this connection. If this parameter is NULL the global callbacks (specified in sasl_client_init) will be used. See sasl_callback for more information.
+.PP
+.I flags
+are connection flags (see below)
+.PP
+.I pconn
+is the connection context allocated by the library. This structure will be used for all future SASL calls for this connection.
+.PP
+.B Connection Flags
+.PP
+Flags that may be passed to
+.B sasl_server_new()
+include
+.TP 0.8i
+.B SASL_SUCCESS_DATA
+The protocol supports a server-last send
+.TP 0.8i
+.B SASL_NEED_PROXY
+Force the use of a mechanism that supports an authorization id that is
+not the authentication id.
+
+.SH "RETURN VALUE"
+
+sasl_client_new returns an integer which corresponds to one of the
+following codes. SASL_OK is the only one that indicates success. All
+others indicate errors and should either be handled or the
+authentication session should be quit.
+
+.SH ERRORS
+.TP 0.8i
+.B SASL_OK
+Success
+.TP 0.8i
+.B SASL_BADPARAM
+Error in config file or passed parameters
+.TP 0.8i
+.B SASL_NOMECH
+No mechanism meets requested properties
+.TP 0.8i
+.B SASL_NOMEM
+Not enough memory to complete operation
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_client_init(3), sasl_client_start(3), sasl_client_step(3), sasl_setprop(3)
diff --git a/man/sasl_client_start.3 b/man/sasl_client_start.3
new file mode 100644 (file)
index 0000000..4b56d5b
--- /dev/null
@@ -0,0 +1,112 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_client_start "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_client_start \- Begin an authentication negotiation
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_client_start(sasl_conn_t * " conn ", "
+.BI "                const char * " mechlist ", "
+.BI "                sasl_interact_t ** " prompt_need ", "
+.BI "                const char ** " clientout ", "
+.BI "                unsigned * " clientoutlen ", "
+.BI "                const char ** " mech ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_client_start()
+selects a mechanism for authentication and starts the authentication
+session. The mechlist is the list of mechanisms the client might like
+to use. The mechanisms in the list are not necessarily supported by
+the client or even valid. SASL determines which of these to use based
+upon the security preferences specified earlier. The list of
+mechanisms is typically a list of mechanisms the server supports
+acquired from a capability request.
+
+If SASL_INTERACT is returned the library needs some values to be
+filled in before it can proceed. The prompt_need structure will be
+filled in with requests. The application should fulfill these requests
+and call sasl_client_start again with identical parameters (the
+prompt_need parameter will be the same pointer as before but filled in
+by the application).
+
+.PP
+.I mechlist
+is a list of mechanisms the server has available. Punctuation if ignored.
+.PP
+.I prompt_need
+is filled in with a list of prompts needed to continue (if necessary).
+.PP
+.I clientout
+and
+.I clientoutlen
+is created. It is the initial client response to send to the
+server. It is the job of the
+client to send it over the network to the server.
+Any protocol specific encoding (such as base64
+encoding) necessary needs to be done by the client.
+
+If the protocol lacks client-send-first capability, then set
+.I clientout
+to NULL.
+
+If there is no initial client-send, then
+.I *clientout
+will be set to NULL on return.
+
+.I mech
+contains the name of the chosen SASL mechanism (on success)
+
+.SH "RETURN VALUE"
+
+sasl_client_start returns an integer which corresponds to one of the
+following codes. SASL_CONTINUE indicates success and that there are
+more steps needed in the authentication. All other return codes
+indicate errors and should either be handled or the authentication
+session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3), sasl_client_init(3), sasl_client_new(3), sasl_client_step(3)
diff --git a/man/sasl_client_step.3 b/man/sasl_client_step.3
new file mode 100644 (file)
index 0000000..0612147
--- /dev/null
@@ -0,0 +1,105 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_client_step "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_client_step \- Perform a step in the authentication negotiation
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_client_step(sasl_conn_t " *conn ", "
+.BI "               const char " *serverin ", "
+.BI "               unsigned " serverinlen ", "
+.BI "               sasl_interact_t ** " prompt_need ", "
+.BI "               const char ** " clientout ", "
+.BI "               unsigned * " clientoutlen ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_client_step()
+performs a step in the authentication negotiation. It returns SASL_OK
+if the whole negotiation is successful and SASL_CONTINUE if this step
+is ok but at least one more step is needed. A client should not assume
+an authentication negotiation is successful just because the server
+signaled success via protocol (i.e. if the server said ". OK
+Authentication succeeded" in IMAP sasl_client_step should still be
+called one more time with a serverinlen of zero.
+
+If SASL_INTERACT is returned the library needs some values to be
+filled in before it can proceed. The prompt_need structure will be
+filled in with requests. The application should fulfill these requests
+and call sasl_client_start again with identical parameters (the
+prompt_need parameter will be the same pointer as before but filled in
+by the application).
+
+.I conn
+is the SASL connection context
+.PP
+.I serverin
+is the data given by the server (decoded if the protocol encodes requests sent over the wire)
+.PP
+.I serverinlen
+is the length of serverin
+.PP
+.I clientout
+and
+.I clientoutlen
+is created. It is the initial client response to send to the
+server. It is the job of the
+client to send it over the network to the server.
+Any protocol specific encoding (such as base64
+encoding) necessary needs to be done by the client.
+
+.SH "RETURN VALUE"
+
+sasl_client_step returns an integer which corresponds to one of the
+following codes. SASL_CONTINUE indicates success and that there are
+more steps needed in the authentication. SASL_OK indicates that the
+authentication is complete. All other return codes indicate errors and
+should either be handled or the authentication session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3), sasl_client_init(3), sasl_client_new(3), sasl_client_start(3)
diff --git a/man/sasl_decode.3 b/man/sasl_decode.3
new file mode 100644 (file)
index 0000000..dfea870
--- /dev/null
@@ -0,0 +1,83 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_decode "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_decode \- Decode data received
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_decode(sasl_conn_t " *conn ", "
+.BI "               const char * " input ", " 
+.BI "                unsigned " inputlen ", " 
+.BI "               const char ** " output ", " 
+.BI "               unsigned * " outputlen ");"  
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_decode
+decodes data received. After successful authentication this function
+should be called on all data received. It decodes the data from
+encrypted or signed form to plain data. If there was no security layer
+negotiated the output is identical to the input.
+
+.I output
+contains the decoded data and is allocated/freed by the library.
+
+One should not to give sasl_decode more data than the negotiated maxbufsize (see sasl_getprop).
+
+Note that sasl_decode can succeed and outputlen can be zero. If this
+is the case simply wait for more data and call sasl_decode again.
+
+.PP
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. See sasl_errors(3) for meanings of other return
+codes.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_encode(3)
\ No newline at end of file
diff --git a/man/sasl_dispose.3 b/man/sasl_dispose.3
new file mode 100644 (file)
index 0000000..84574fe
--- /dev/null
@@ -0,0 +1,69 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_dispose "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_dispose \- Dispose of a SASL connection object
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "void sasl_dispose(" sasl_conn_t " **pconn )";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_dispose
+is called when a SASL connection object is no longer needed. Note that
+this is usually when the protocol session is done NOT when the
+authentication is done since a security layer may have been
+negotiated.
+
+.PP
+
+.SH "RETURN VALUE"
+No return values
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_server_new(3), sasl_client_new(3)
\ No newline at end of file
diff --git a/man/sasl_done.3 b/man/sasl_done.3
new file mode 100644 (file)
index 0000000..2c04814
--- /dev/null
@@ -0,0 +1,66 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_done "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_done \- Dispose of a SASL connection object
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "void sasl_done( void )";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_done
+is called when the application is completely done with the SASL library.
+
+.PP
+
+.SH "RETURN VALUE"
+No return values
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_server_init(3), sasl_client_init(3)
\ No newline at end of file
diff --git a/man/sasl_encode.3 b/man/sasl_encode.3
new file mode 100644 (file)
index 0000000..ba550e3
--- /dev/null
@@ -0,0 +1,82 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_encode "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_encode \- Encode data for transport to authenticated host
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_encode(sasl_conn_t " *conn ", "
+.BI "               const char * " input ", " 
+.BI "               unsigned " inputlen ", " 
+.BI "               const char ** " output ", " 
+.BI "               unsigned * " outputlen ");"  
+
+.BI "int sasl_encodev(sasl_conn_t " *conn ", "
+.BI "               const struct iovec * " invec ", " 
+.BI "               unsigned " numiov ", " 
+.BI "               const char ** " output ", " 
+.BI "               unsigned * " outputlen ");"  
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_encode
+encodes data to be sent to be sent to a remote host who we've had a successful authentication session with. If there is a negotiated security the data in signed/encrypted and the output should be sent without modification to the remote host. If there is no security layer the output is identical to the input.
+
+.B sasl_encodev
+does the same, but for a struct iovec instead of a character buffer.
+
+.I output
+contains the encoded data and is allocated/freed by the library.
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success.  See sasl_errors(3) for meanings of other return
+codes.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_decode(3)
\ No newline at end of file
diff --git a/man/sasl_encodev.3 b/man/sasl_encodev.3
new file mode 100644 (file)
index 0000000..ba550e3
--- /dev/null
@@ -0,0 +1,82 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_encode "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_encode \- Encode data for transport to authenticated host
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_encode(sasl_conn_t " *conn ", "
+.BI "               const char * " input ", " 
+.BI "               unsigned " inputlen ", " 
+.BI "               const char ** " output ", " 
+.BI "               unsigned * " outputlen ");"  
+
+.BI "int sasl_encodev(sasl_conn_t " *conn ", "
+.BI "               const struct iovec * " invec ", " 
+.BI "               unsigned " numiov ", " 
+.BI "               const char ** " output ", " 
+.BI "               unsigned * " outputlen ");"  
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_encode
+encodes data to be sent to be sent to a remote host who we've had a successful authentication session with. If there is a negotiated security the data in signed/encrypted and the output should be sent without modification to the remote host. If there is no security layer the output is identical to the input.
+
+.B sasl_encodev
+does the same, but for a struct iovec instead of a character buffer.
+
+.I output
+contains the encoded data and is allocated/freed by the library.
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success.  See sasl_errors(3) for meanings of other return
+codes.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_decode(3)
\ No newline at end of file
diff --git a/man/sasl_errdetail.3 b/man/sasl_errdetail.3
new file mode 100644 (file)
index 0000000..86b8d23
--- /dev/null
@@ -0,0 +1,69 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_errdetail "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_errdetail \- Retrieve detailed information about an error
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "const char *sasl_errdetail( sasl_conn_t *conn )";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_errdetail
+provides more detailed information about the most recent error to occur,
+beyond the information contained in the SASL result code.
+
+.I conn
+the connection context to inquire about.
+
+.SH "RETURN VALUE"
+Returns the string describing the error that occurred, or NULL if
+no error has occurred, or there was an error retrieving it.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3)
\ No newline at end of file
diff --git a/man/sasl_errors.3 b/man/sasl_errors.3
new file mode 100644 (file)
index 0000000..9bf30ee
--- /dev/null
@@ -0,0 +1,155 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_errors "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_errors \- SASL error codes
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.fi
+.SH DESCRIPTION
+
+The following are the general error codes that may be returned by
+calls into the SASL library, and their meanings (that may vary
+slightly based on context):
+
+.SH Common Result Codes
+.TP 0.8i
+SASL_OK
+Success
+.TP 0.8i
+SASL_CONTINUE
+Another step is needed in authentication
+.TP 0.8i
+SASL_FAIL
+Generic Failure
+.TP 0.8i
+SASL_NOMEM
+Memory shortage failure
+.TP 0.8i
+SASL_BUFOVER
+Overflowed buffer
+.TP 0.8i
+SASL_NOMECH
+Mechanism not supported / No mechanisms matched requirements
+.TP 0.8i
+SASL_BADPROT
+Bad / Invalid Protocol or Protocol cancel
+.TP 0.8i
+SASL_NOTDONE
+Can't request information / Not applicable until later in exchange
+.TP 0.8i
+SASL_BADPARAM
+Invalid Parameter Supplied
+.TP 0.8i
+SASL_TRYAGAIN
+Transient Failure (e.g. weak key)
+.TP 0.8i
+SASL_BADMAC
+Integrity Check Failed
+.TP 0.8i
+SASL_NOTINIT
+SASL library not initialized
+
+.SH Client-only Result Codes
+.TP 0.8i
+SASL_INTERACT
+Needs user interaction
+.TP 0.8i
+SASL_BADSERV
+Server failed mutual authentication step
+.TP 0.8i
+SASL_WRONGMECH
+Mechanism does not support requested feature
+
+.SH Server-only Result Codes
+.TP 0.8i
+SASL_BADAUTH
+Authentication Failure
+.TP 0.8i
+SASL_NOAUTHZ
+Authorization Failure
+.TP 0.8i
+SASL_TOOWEAK
+Mechanism too weak for this user
+.TP 0.8i
+SASL_ENCRYPT
+Encryption needed to use mechanism
+.TP 0.8i
+SASL_TRANS
+One time use of a plaintext password will enable requested mechanism for user
+.TP 0.8i
+SASL_EXPIRED
+Passphrase expired, must be reset
+.TP 0.8i
+SASL_DISABLED
+Account Disabled
+.TP 0.8i
+SASL_NOUSER
+User Not Found 
+.TP 0.8i
+SASL_BADVERS
+Version mismatch with plug-in
+.TP 0.8i
+SASL_NOVERIFY
+USer exists, but no verifier for user
+
+.SH Password Setting Result Codes
+.TP 0.8i
+SASL_PWLOCK
+Passphrase locked
+.TP 0.8i
+SASL_NOCHANGE
+Requested change was not needed
+.TP 0.8i
+SASL_WEAKPASS
+Passphrase is too week for security policy.
+.TP 0.8i
+SASL_NOUSERPASS
+User supplied passwords are not permitted
+
+.SH "CONFORMING TO"
+RFC 2222
+
+.SH "SEE ALSO"
+sasl(3)
diff --git a/man/sasl_errstring.3 b/man/sasl_errstring.3
new file mode 100644 (file)
index 0000000..6f653c4
--- /dev/null
@@ -0,0 +1,85 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_errstring "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_errstring \- Translate a SASL return code to a human-readable form
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "const char * sasl_errstring(int " saslerr ", "
+.BI "                          const char * " langlist ", "
+.BI "                          const char ** " outlang ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_usererr
+is called to convert a SASL return code (an integer) into a human
+readable string. At this time the only language available is american
+english written by programmers (aka gobbledygook).
+Note that a server should call sasl_usererr on a return code first if
+the string is going to be sent to the client.
+.PP
+.I saslerr
+specifies the error number to convert.
+.PP
+.I langlist
+is currently unused; Use NULL.
+.PP
+.I outlang
+specifies the desired RFC 1766 language for output.  NULL defaults to "en-us,"
+currently the only supported language.
+.PP
+It should be noted that this function is not the recommended means of
+extracting error code information from SASL, instead application should
+use sasl_errdetail(3), which contains this information (and more)
+.PP
+.SH "RETURN VALUE"
+Returns the string.  If langlist is NULL, US-ASCII is used.
+.PP
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errdetail(3), sasl_errors(3)
diff --git a/man/sasl_getconfpath_t.3 b/man/sasl_getconfpath_t.3
new file mode 100644 (file)
index 0000000..f50c774
--- /dev/null
@@ -0,0 +1,68 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2006 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.
+.\" 
+.TH sasl_getconfpath_t "12 February 2006" SASL "SASL man pages"
+.SH NAME
+sasl_getconfpath_t \- The SASL callback to indicate location of the config files
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl.h>
+
+.sp
+.BI "int sasl_getconfpath_t(void " *context ", "
+.BI "                  char ** " path ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getconfpath_t
+is used if the application wishes to use a different location for the SASL configuration files. If this callback is not used SASL will either use the location in the environment variable SASL_CONF_PATH (provided we are not SUID or SGID) or /etc/sasl2 by default.
+.PP
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
diff --git a/man/sasl_getopt_t.3 b/man/sasl_getopt_t.3
new file mode 100644 (file)
index 0000000..4a27393
--- /dev/null
@@ -0,0 +1,84 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getopt_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getopt_t \- The SASL get option callback
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getopt_t(void " *context ", "
+.BI "               const char " *plugin_name ", "
+.BI "               const char " *option ", "
+.BI "               const char ** " result ", "
+.BI "               unsigned * " len ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getopt_t
+is used to retrieve an option, often mechanism specific, from the
+application. An example of this is requested what KERBEROS_V4 srvtab
+file to use.
+.I plugin_name
+is the plugin this value if for.
+.I option
+is a string representing the option. A common option that all server
+applications should handle is \"pwcheck_method\" which represents the
+method for checking plaintext passwords. See the administrators guide
+for a full description of this option.
+.PP
+Memory management of options supplied by the getopt callback should be
+done by the application, however, any requested option must remain available
+until the callback is no longer valid.  That is, when sasl_dispose is called for a
+the connection it is associated with, or sasl_done is called for global callbacks.
+.PP
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
diff --git a/man/sasl_getpath_t.3 b/man/sasl_getpath_t.3
new file mode 100644 (file)
index 0000000..9c591f9
--- /dev/null
@@ -0,0 +1,68 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getpath_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getpath_t \- The SASL callback to indicate location of the mechanism drivers
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getpath_t(void " *context ", "
+.BI "                  char ** " path ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getpath_t
+is used if the application wishes to use a different location for the SASL mechanism drivers (the shared library files). If this callback is not used SASL will either use the location in the environment variable SASL_PATH or /usr/lib/sasl2 by default.
+.PP
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
diff --git a/man/sasl_getprop.3 b/man/sasl_getprop.3
new file mode 100644 (file)
index 0000000..4fddd78
--- /dev/null
@@ -0,0 +1,96 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getprop "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getprop \- Get a SASL property
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getprop(sasl_conn_t " *conn ", "
+.BI "                   int " propnum ", " 
+.BI "                   const void ** " pvalue ");"  
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getprop
+gets the value of a SASL property. For example after successful
+authentication a server may wish to know the authorization name. Or a
+client application may wish to know the strength of the negotiated
+security layer.
+
+.I conn
+is the SASL connection object.
+.I propnum
+is the identifier for the property requested and
+.I pvalue
+is filled in on success. List of properties follows:
+
+.nf
+SASL_USERNAME     -  pointer to NUL terminated user name 
+SASL_SSF          -  security layer security strength factor,
+                     if 0, call to sasl_encode, sasl_decode unnecessary
+SASL_MAXOUTBUF    -  security layer max output buf unsigned 
+SASL_DEFUSERREALM -  server authentication realm used 
+SASL_GETOPTCTX    -  context for getopt callback 
+SASL_IPLOCALPORT  -  local address string
+SASL_IPREMOTEPORT -  remote address string
+SASL_SERVICE      -  service passed to sasl_*_new
+SASL_SERVERFQDN   -  serverFQDN passed to sasl_*_new
+SASL_AUTHSOURCE   -  name of auth source last used, useful for failed
+                     authentication tracking
+SASL_MECHNAME     -  active mechanism name, if any
+SASL_PLUGERR      -  similar to sasl_errdetail
+.fi
+
+.PP
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. SASL error code on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_server_new(3), sasl_client_new(3)
diff --git a/man/sasl_getrealm_t.3 b/man/sasl_getrealm_t.3
new file mode 100644 (file)
index 0000000..3938bfe
--- /dev/null
@@ -0,0 +1,81 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getrealm_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getrealm_t \- Realm Acquisition Callback
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getrealm_t(void " *context ", int " id ", "
+.BI "                   const char " **availrealms ","
+.BI "                    const char " **result ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getrealm_t
+is used when there is an interaction with SASL_CB_GETREALM as the type.
+
+If a mechanism would use this callback, but it is not present, then the first
+realm listed is automatically selected.  (Note that a mechanism may still
+force the existence of a getrealm callback by SASL_CB_GETREALM to its
+required_prompts list).
+
+.I context
+context from the callback record
+
+.I id
+callback ID (SASL_CB_GETREALM)
+
+.I availrealms
+A string list of the available realms.  NULL terminated, may be empty.
+
+.I result
+The chosen realm. (a NUL terminated string)
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3)
diff --git a/man/sasl_getsecret_t.3 b/man/sasl_getsecret_t.3
new file mode 100644 (file)
index 0000000..b0c1346
--- /dev/null
@@ -0,0 +1,74 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getsecret_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getsecret_t \- The SASL callback for secrets (passwords)
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getsecret_t(sasl_conn_t " *conn ", "
+.BI "                     void " *context ", "
+.BI "                    int " id ", "
+.BI "                    sasl_secret_t ** " psecret ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getsecret_t
+is used to retrieve the secret from the application. A sasl_secret_t should be allocated to length sizeof(sasl_secret_t)+<length of secret>. It has two fields
+.I len
+which is the length of the secret in bytes and
+.I data
+which contains the secret itself (does not need to be null terminated).
+.PP
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
\ No newline at end of file
diff --git a/man/sasl_getsimple_t.3 b/man/sasl_getsimple_t.3
new file mode 100644 (file)
index 0000000..11c5018
--- /dev/null
@@ -0,0 +1,81 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_getsimple_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_getsimple_t \- The SASL callback for username/authname/realm
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_getsimple_t(void " *context ", "
+.BI "                    int " id ", "
+.BI "                    const char ** " result ", "
+.BI "                    unsigned * " len ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_getsimple_t
+is used to retrieve simple things from the application. In practice this is authentication name, authorization name, and realm. The
+.BI id
+parameter indicates which value is being requested.
+Possible values include:
+
+.nf
+SASL_CB_USER     - Client user identity to login as
+SASL_CB_AUTHNAME - Client authentication name
+SASL_CB_LANGUAGE - Comma-separated list of RFC 1766 languages
+SASL_CB_CNONCE   - Client-nonce (for testing mostly)
+.fi
+
+.PP
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
\ No newline at end of file
diff --git a/man/sasl_global_listmech.3 b/man/sasl_global_listmech.3
new file mode 100644 (file)
index 0000000..c5ca119
--- /dev/null
@@ -0,0 +1,65 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_listmech "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_listmech \- Retrieve a list of the supported SASL mechanisms
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+
+.BI "const char ** sasl_global_listmech()"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_global_listmech()
+returns a null-terminated array of strings that lists all mechanisms that
+are loaded by either the client or server side of the library.
+
+.SH "RETURN VALUE"
+Returns a pointer to the array on success. NULL on failure (sasl library
+uninitialized).
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_listmech(3), sasl_server_init(3), sasl_client_init(3)
diff --git a/man/sasl_idle.3 b/man/sasl_idle.3
new file mode 100644 (file)
index 0000000..eafe776
--- /dev/null
@@ -0,0 +1,68 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_idle "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_idle \- Perform precalculations during an idle period
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_idle( sasl_conn_t " *conn ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_idle
+may be called during an idle period to allow the SASL library or any mechanisms
+to perform any necessary precalculation.
+
+.I conn
+may be NULL to do precalculation prior to a connection taking place.
+
+.SH "RETURN VALUE"
+Returns 1 if action was taken, 0 if no action was taken.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3)
diff --git a/man/sasl_listmech.3 b/man/sasl_listmech.3
new file mode 100644 (file)
index 0000000..5348338
--- /dev/null
@@ -0,0 +1,97 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_listmech "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_listmech \- Retrieve a list of the supported SASL mechanisms
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+
+.BI "int sasl_listmech(sasl_conn_t *" conn ", "
+.BI "                 const char *" user ", "
+.BI "                 const char *" prefix ", "
+.BI "                 const char *" sep ", "
+.BI "                 const char *" suffix ", "
+.BI "                 const char **" result ", "
+.BI "                 unsigned *" plen ", "
+.BI "                 int *" pcount ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_listmech()
+returns a string listing the SASL names of all the mechanisms available to the specified user. This is typically given to the client through a capability command or initial server response. Client applications need this list so that they know what mechanisms the server supports.
+
+.I conn
+the SASL context for this connection
+.I user
+(optional) restricts the mechanism list to only those available to the user.
+.I prefix
+appended to beginning of result
+.I sep
+appended between mechanisms
+.I suffix
+appended to end of result
+.I result
+NULL terminated result string (allocated/freed by library)
+.I plen
+length of result filled in by library. May be NULL
+.I pcount
+Number of mechanisms available (filled in by library). May be NULL
+
+.nf
+Example:
+
+sasl_listmech(conn,NULL,"(",",",")",&mechlist,NULL,NULL);
+
+may give the string 
+.BI (ANONYMOUS,KERBEROS_V4,DIGEST-MD5)
+as a result
+.PP
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. SASL error code on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_server_new(3), sasl_client_new(3)
diff --git a/man/sasl_log_t.3 b/man/sasl_log_t.3
new file mode 100644 (file)
index 0000000..b292d9d
--- /dev/null
@@ -0,0 +1,70 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_log_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_log_t \- The SASL logging callback
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_log_t(void " *context ", "
+.BI "              int " level ", "
+.BI "              const char * " message ")";
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_log_t
+is used to log warning/error messages from the SASL library. If not
+specified syslog will be used.
+.PP
+
+.SH "RETURN VALUE"
+
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3)
\ No newline at end of file
diff --git a/man/sasl_server_init.3 b/man/sasl_server_init.3
new file mode 100644 (file)
index 0000000..075a4ef
--- /dev/null
@@ -0,0 +1,83 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_init "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_init \- SASL server authentication initialization
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_server_init(const sasl_callback_t " *callbacks ", "
+.BI "                     const char " *appname ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_server_init()
+initializes SASL. It must be called before any calls to
+sasl_server_start, and only once per process.
+This call initializes all SASL mechanism drivers
+(e.g. authentication mechanisms). These are usually found in the
+/usr/lib/sasl2 directory but the directory may be overridden with the
+SASL_PATH environment variable (or at compile time).
+.PP
+.I callbacks
+specifies the base callbacks for all client connections. See
+the sasl_callbacks man page for more information.
+.PP
+.I appname
+is the name of the application. It is used for where to find the
+default configuration file.
+.PP
+
+.SH "RETURN VALUE"
+
+sasl_server_init returns an integer which corresponds to one of the
+SASL error codes. SASL_OK is the only one that indicates success. All
+others indicate errors and should either be handled or the
+authentication session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3), sasl_server_new(3), sasl_server_start(3), sasl_server_step(3)
diff --git a/man/sasl_server_new.3 b/man/sasl_server_new.3
new file mode 100644 (file)
index 0000000..b45f785
--- /dev/null
@@ -0,0 +1,115 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_new "16 May 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_new \- Create a new server authentication object
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_server_new(const char " *service ", "
+.BI "                   const char " *serverFQDN ", "
+.BI "                   const char " *user_realm ", "
+.BI "                   const char " *iplocalport ", "
+.BI "                   const char " *ipremoteport ", "
+.BI "                   const sasl_callback_t " *callbacks ", "
+.BI "                   unsigned " flags ", "
+.BI "                   sasl_conn_t ** " pconn ");"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_server_new()
+creates a new SASL context. This context will be used for all SASL
+calls for one connection. It handles both authentication and
+integrity/encryption layers after authentication.
+.PP
+.I service
+is the registered name of the service (usually the protocol name) using SASL (e.g. "imap").
+.PP
+.I serverFQDN
+is the fully qualified server domain name.  NULL means use gethostname().  This is useful for multi-homed servers.
+.PP
+.I user_realm
+is the domain of the user agent. This is usually not necessary (NULL is default)
+.PP
+.I iplocalport
+is the IP and port of the local side of the connection, or NULL.  If
+iplocalport is NULL it will disable mechanisms that require IP address
+information.  This strings must be in one of the following formats:
+"a.b.c.d;port" (IPv4), "e:f:g:h:i:j:k:l;port" (IPv6),
+or "e:f:g:h:i:j:a.b.c.d;port" (IPv6)
+.PP
+.I ipremoteport
+is the IP and port of the remote side of the connection, or NULL (see
+iplocalport)
+.PP
+.I flags
+are connection flags (see below)
+.PP
+.I pconn
+is a pointer to the connection context allocated by the library. This
+structure will be used for all future SASL calls for this connection.
+.PP
+
+.B Connection Flags
+.TP 0.8i
+.B SASL_SUCCESS_DATA
+The protocol supports a server-last send
+.TP 0.8i
+.B SASL_NEED_PROXY
+Force the use of a mechanism that supports an authorization id that is
+not the authentication id.
+
+.SH "RETURN VALUE"
+
+.B sasl_server_new()
+returns an integer which corresponds to one of the
+SASL error codes. SASL_OK is the only one that indicates success. All
+others indicate errors and should either be handled or the
+authentication session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_server_init(3), sasl_server_start(3), sasl_server_step(3), sasl_setprop(3)
diff --git a/man/sasl_server_start.3 b/man/sasl_server_start.3
new file mode 100644 (file)
index 0000000..8f55b8e
--- /dev/null
@@ -0,0 +1,105 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_start "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_start \- Begin an authentication negotiation
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_server_start(sasl_conn_t * " conn ", "
+.BI "                     const char * " mech ", "
+.BI "                     const char * " clientin ", "
+.BI "                     unsigned * " clientinlen ", "
+.BI "                     const char ** " serverout ", "
+.BI "                     unsigned * " serveroutlen ");"
+.fi
+.SH DESCRIPTION
+
+.B sasl_server_start()
+begins the authentication with the mechanism specified with mech. This
+fails if the mechanism is not supported. SASL_OK is returned if the
+authentication is complete and the user is
+authenticated. SASL_CONTINUE is returned if one or more steps are
+still required in the authentication. All other return values indicate
+failure.
+
+.PP
+.I conn
+is the SASL context for this connection
+.PP
+.I mech
+is the mechanism name that the client requested
+.PP
+.I clientin
+is the client initial response, NULL if the protocol lacks support for
+client-send-first or if the other end did not have an initial send.  Note that
+no initial client send is distinct from an initial send of a null string,
+and the protocol MUST account for this difference.
+
+.PP
+.I clientinlen
+is the length of initial response
+.PP
+.I serverout
+is created by the plugin library. It is the initial server response to send to the client. This is allocated/freed by the library and it is the job of the client to send it over the network to the server. Also protocol specific encoding (such as base64 encoding) must needs to be done by the server.
+.PP
+.I serveroutlen
+is set to the length of initial server challenge
+.PP
+
+.PP
+
+.SH "RETURN VALUE"
+
+sasl_server_start returns an integer which corresponds to one of the
+SASL errorcodes. SASL_OK indicates that authentication is completed
+successfully. SASL_CONTINUE indicates success and that there are
+more steps needed in the authentication. All other return codes
+indicate errors and should either be handled or the authentication
+session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_server_init(3), sasl_server_new(3), sasl_server_step(3)
diff --git a/man/sasl_server_step.3 b/man/sasl_server_step.3
new file mode 100644 (file)
index 0000000..0a8634d
--- /dev/null
@@ -0,0 +1,90 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_step "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_step \- Perform a step in the authentication negotiation
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+.sp
+.BI "int sasl_server_step(sasl_conn_t " *conn ", "
+.BI "                    const char " *clientin ", "
+.BI "                    unsigned " clientinlen ", "
+.BI "                    const char ** " serverout ", "
+.BI "                    unsigned * " serveroutlen ");"
+
+
+.SH DESCRIPTION
+
+.B sasl_server_step()
+performs a step in the authentication negotiation. It returns SASL_OK
+if the whole negotiation is successful and SASL_CONTINUE if this step
+is ok but at least one more step is needed.
+
+.PP
+.I conn
+is the SASL connection context
+.PP
+.I clientin
+is the data given by the client (decoded if the protocol encodes requests sent over the wire)
+.I clientinlen
+is the length of
+.I clientin
+.PP
+.I serverout
+and
+.I serveroutlen
+are set by the library and should be sent to the client.
+.PP
+.SH "RETURN VALUE"
+
+sasl_server_step returns an integer which corresponds to one of the
+SASL error codes. SASL_CONTINUE indicates success and that there are
+more steps needed in the authentication. SASL_OK indicates that the
+authentication is complete. All other return codes indicate errors and
+should either be handled or the authentication session should be quit.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_server_init(3), sasl_server_new(3), sasl_server_start(3)
diff --git a/man/sasl_server_userdb_checkpass_t.3 b/man/sasl_server_userdb_checkpass_t.3
new file mode 100644 (file)
index 0000000..4a376a3
--- /dev/null
@@ -0,0 +1,84 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_userdb_checkpass_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_userdb_checkpass_t \- Plaintext Password Verification Callback
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_server_userdb_checkpass_t(sasl_conn_t " *conn ","
+.BI "                                   void " *context ","
+.BI "                                  const char " *user ","
+.BI "                                   const char " *pass ","
+.BI "                                   unsigned " passlen ","
+.BI "                                   struct propctx " *propctx ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_server_userdb_checkpass_t
+is used to verify a plaintext password against the callback supplier's user
+database.  This is to allow additional ways to encode the userPassword
+property.
+
+.I context
+context from the callback record
+
+.I user
+NUL terminated user name with user@realm syntax
+
+.I pass
+password to check (may not be NUL terminated)
+
+.I passlen
+length of the password
+
+.I propctx
+property context to fill in with userPassword
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3), sasl_server_userdb_setpass_t(3)
\ No newline at end of file
diff --git a/man/sasl_server_userdb_setpass_t.3 b/man/sasl_server_userdb_setpass_t.3
new file mode 100644 (file)
index 0000000..70f3ede
--- /dev/null
@@ -0,0 +1,88 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_server_userdb_setpass_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_server_userdb_setpass_t \- UserDB Plaintext Password Setting Callback
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_server_userdb_setpass_t(sasl_conn_t " *conn ","
+.BI "                                 void " *context ","
+.BI "                                const char " *user ","
+.BI "                                 const char " *pass ","
+.BI "                                 unsigned " passlen ","
+.BI "                                 struct propctx " *propctx ","
+.BI "                                 unsigned " flags ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_server_userdb_setpass_t
+is used to store or change a plaintext password in the callback-supplier's
+user database.
+
+.I context
+context from the callback record
+
+.I user
+NUL terminated user name with user@realm syntax
+
+.I pass
+password to check (may not be NUL terminated)
+
+.I passlen
+length of the password
+
+.I propctx
+Auxilliary Properties (not stored)
+
+.I flags
+These are the same flags that are passed to sasl_setpass(3), and are documented
+on that man page.
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3), sasl_errors(3), sasl_server_userdb_checkpass_t(3), sasl_setpass(3)
\ No newline at end of file
diff --git a/man/sasl_setpass.3 b/man/sasl_setpass.3
new file mode 100644 (file)
index 0000000..df0d14c
--- /dev/null
@@ -0,0 +1,91 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_setpass "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_setpass \- Check a plaintext password
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.BI "int sasl_setpass(sasl_conn_t *" conn ", "
+.BI "                 const char *" user ", "
+.BI "                 const char *" pass ", unsigned " passlen ","
+.BI "                  const char *" oldpass ", unsigned " oldpasslen ","
+.BI "                  unsigned " flags ")"
+
+.SH DESCRIPTION
+
+.B sasl_setpass
+will set passwords in the sasldb, and trigger the setpass callbacks for all
+available mechanisms.
+
+.I user
+is the username to set the password for.
+
+.I pass
+and
+.I passlen
+are the password to set and its length
+
+.I oldpass
+and
+.I oldpasslen
+are the old password & its length (and are optional)
+
+.I flags
+Are flags including SASL_SET_CREATE and SASL_SET_DISABLE (to cause the
+creating of nonexistent accounts and the disabling of an account,
+respectively)
+
+.SH NOTES
+.I oldpass
+and
+.I oldpasslen
+are unused in the Cyrus SASL implementation, though are passed on to
+any mechanisms that may require them.
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. SASL error code on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3), sasl_checkpass(3)
\ No newline at end of file
diff --git a/man/sasl_setprop.3 b/man/sasl_setprop.3
new file mode 100644 (file)
index 0000000..cd4ab17
--- /dev/null
@@ -0,0 +1,83 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_setprop "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_setprop \- Set a SASL property
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_setprop(sasl_conn_t " *conn ", "
+.BI "                   int " propnum ", " 
+.BI "                   const void * " pvalue ")"  
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_setprop
+sets the value of a SASL property. For example an application should tell the SASL library about any external negotiated security layer (i.e. TLS).
+
+.I conn
+is the SASL connection object.
+.I propnum
+is the identifier for the property requested and
+.I pvalue
+contains a pointer to the data. It is the applications job to make sure this type is correct. This is an easy way to crash a program.
+
+.nf
+SASL_AUTH_EXTERNAL - external authentication ID (const char *)
+SASL_SSF_EXTERNAL -  external SSF active -- (sasl_ssf_t)
+SASL_DEFUSERREALM - user realm (const char *)
+SASL_SEC_PROPS  -    sasl_security_properties_t (may be freed after call)
+SASL_IPLOCALPORT -   string describing the local ip and port in the form
+                     "a.b.c.d;p", or "e:f:g:h:i:j:k:l;port"
+SASL_IPREMOTEPORT -  string describing the remote ip and port in the form
+                     "a.b.c.d;p", or "e:f:g:h:i:j:k:l;port"
+.fi
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. SASL error code on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3)
diff --git a/man/sasl_user_exists.3 b/man/sasl_user_exists.3
new file mode 100644 (file)
index 0000000..faa6fbc
--- /dev/null
@@ -0,0 +1,78 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_user_exists "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_user_exists \- Check if a user exists on server
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "int sasl_user_exists( sasl_conn_t " *conn ","
+.BI "                      const char " *service ", const char " *user_realm ","
+.BI "                      const char " *user ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_user_exists
+will check if a user exists on the server.
+
+.I conn
+a connection context
+
+.I service
+Service name or NULL (for service name of connection context)
+
+.I user_realm
+Realm to check in or NULL (for default realm)
+
+.I user
+User name to check for existence of.
+
+.SH "RETURN VALUE"
+Returns SASL_OK on success. SASL error code on failure.
+
+.SH "CONFORMING TO"
+RFC 2222
+.SH "SEE ALSO"
+sasl(3), sasl_errors(3)
diff --git a/man/sasl_verifyfile_t.3 b/man/sasl_verifyfile_t.3
new file mode 100644 (file)
index 0000000..6f81c51
--- /dev/null
@@ -0,0 +1,83 @@
+.\" -*- nroff -*-
+.\" 
+.\" Copyright (c) 2001 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.
+.\" 
+.TH sasl_verifyfile_t "10 July 2001" SASL "SASL man pages"
+.SH NAME
+sasl_verifyfile_t \- The SASL file verification
+
+
+.SH SYNOPSIS
+.nf
+.B #include <sasl/sasl.h>
+
+.sp
+.BI "typedef enum {"
+    SASL_VRFY_PLUGIN, /* a DLL/shared library plugin */
+    SASL_VRFY_CONF,   /* a configuration file */
+    SASL_VRFY_PASSWD, /* a password storage file */
+    SASL_VRFY_OTHER   /* some other file type */
+.BI "} sasl_verify_type_t"
+
+.BI "int sasl_verifyfile_t(void " *context ", "
+.BI "                     const char " *file ","
+.BI "                      sasl_verify_type_t " type ")"
+
+.fi
+.SH DESCRIPTION
+
+.B sasl_verifyfile_t
+is used to check whether a given file is okay for use by the SASL library.
+this is intended to allow applications to sanity check the environment to
+ensure that plugins or the config file cannot be written to, etc.
+
+.I context
+context from the callback record
+
+.I file
+full path of the file to verify
+
+.I type
+type of the file.
+
+.SH "RETURN VALUE"
+SASL callback functions should return SASL return codes. See sasl.h for a complete list. SASL_OK indicates success.
+
+.SH "SEE ALSO"
+sasl(3), sasl_callbacks(3)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644 (file)
index 0000000..ebb79d5
--- /dev/null
@@ -0,0 +1,174 @@
+# Makefile.am for the SASL plugins
+# Rob Siemborski
+# Rob Earhart
+# $Id: Makefile.am,v 1.78.2.1 2009/04/27 17:58:26 murch Exp $
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+# Library version info - here at the top, for sanity
+# CURRENT:REVISION:AGE
+anonymous_version = 2:23:0
+digestmd5_version = 2:23:0
+kerberos4_version = 2:23:0
+gssapiv2_version = 2:23:0
+crammd5_version = 2:23:0
+passdss_version = 2:23:0
+sasldb_version = 2:23:0
+login_version = 2:23:0
+plain_version = 2:23:0
+ntlm_version = 2:23:0
+otp_version = 2:23:0
+sql_version = 2:23:0
+ldapdb_version = 2:23:0
+srp_version = 2:23:0
+
+INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/sasldb -I$(top_builddir)/include
+AM_LDFLAGS = -module -export-dynamic -rpath $(plugindir)
+
+COMPAT_OBJS = @LTGETADDRINFOOBJS@ @LTGETNAMEINFOOBJS@ @LTSNPRINTFOBJS@
+
+EXTRA_DIST = makeinit.sh NTMakefile
+noinst_SCRIPTS = makeinit.sh
+
+LIB_MYSQL = @LIB_MYSQL@
+
+plugindir = @plugindir@
+
+common_sources = plugin_common.c plugin_common.h
+
+sasldir = $(prefix)/lib/sasl2
+sasl_LTLIBRARIES = @SASL_MECHS@
+EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
+       libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
+       libntlm.la libpassdss.la libsasldb.la libsql.la libldapdb.la
+
+libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
+libplain_la_LDFLAGS = -version-info $(plain_version)
+libplain_la_DEPENDENCIES = $(COMPAT_OBJS)
+libplain_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
+
+libanonymous_la_SOURCES = anonymous.c anonymous_init.c $(common_sources)
+libanonymous_la_LDFLAGS = -version-info $(anonymous_version)
+libanonymous_la_DEPENDENCIES = $(COMPAT_OBJS)
+libanonymous_la_LIBADD = $(COMPAT_OBJS)
+
+libkerberos4_la_SOURCES = kerberos4.c kerberos4_init.c $(common_sources)
+libkerberos4_la_LDFLAGS = -version-info $(kerberos4_version)
+libkerberos4_la_DEPENDENCIES = $(COMPAT_OBJS)
+libkerberos4_la_LIBADD = $(SASL_KRB_LIB) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+libgssapiv2_la_SOURCES = gssapi.c gssapiv2_init.c $(common_sources)
+libgssapiv2_la_LDFLAGS = -version-info $(gssapiv2_version)
+libgssapiv2_la_DEPENDENCIES = $(COMPAT_OBJS)
+libgssapiv2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+libcrammd5_la_SOURCES = cram.c crammd5_init.c $(common_sources)
+libcrammd5_la_LDFLAGS = -version-info $(crammd5_version)
+libcrammd5_la_DEPENDENCIES = $(COMPAT_OBJS)
+libcrammd5_la_LIBADD = $(COMPAT_OBJS)
+
+libdigestmd5_la_SOURCES = digestmd5.c digestmd5_init.c $(common_sources)
+libdigestmd5_la_LDFLAGS = -version-info $(digestmd5_version)
+libdigestmd5_la_DEPENDENCIES = $(COMPAT_OBJS)
+libdigestmd5_la_LIBADD = $(LIB_DES) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+liblogin_la_SOURCES = login.c login_init.c $(common_sources)
+liblogin_la_LDFLAGS = -version-info $(login_version)
+liblogin_la_DEPENDENCIES = $(COMPAT_OBJS)
+liblogin_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
+
+libsrp_la_SOURCES = srp.c srp_init.c $(common_sources)
+libsrp_la_LDFLAGS = -version-info $(srp_version)
+libsrp_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsrp_la_LIBADD = $(SRP_LIBS) $(COMPAT_OBJS)
+
+libotp_la_SOURCES = otp.c otp_init.c otp.h $(common_sources)
+libotp_la_LDFLAGS = -version-info $(otp_version)
+libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
+libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
+
+libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources)
+libntlm_la_LDFLAGS = -version-info $(ntlm_version)
+libntlm_la_DEPENDENCIES = $(COMPAT_OBJS)
+libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS)
+
+libpassdss_la_SOURCES = passdss.c passdss_init.c $(common_sources)
+libpassdss_la_LDFLAGS = -version-info $(passdss_version)
+libpassdss_la_DEPENDENCIES = $(COMPAT_OBJS)
+libpassdss_la_LIBADD = $(PASSDSS_LIBS) $(COMPAT_OBJS)
+
+# Auxprop Plugins
+libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
+libsasldb_la_LDFLAGS = -version-info $(sasldb_version)
+libsasldb_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsasldb_la_LIBADD = ../sasldb/libsasldb.la $(SASL_DB_LIB) $(COMPAT_OBJS)
+
+libldapdb_la_SOURCES = ldapdb.c ldapdb_init.c $(common_sources)
+libldapdb_la_LDFLAGS = $(LIB_LDAP) -version-info $(ldapdb_version)
+libldapdb_la_DEPENDENCIES = $(COMPAT_OBJS)
+libldapdb_la_LIBADD = $(COMPAT_OBJS)
+
+libsql_la_SOURCES = sql.c sql_init.c $(common_sources)
+libsql_la_LDFLAGS = $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) -version-info $(sql_version)
+libsql_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsql_la_LIBADD = $(COMPAT_OBJS)
+
+
+# Instructions for making the _init files
+
+init_src=anonymous_init.c crammd5_init.c digestmd5_init.c gssapiv2_init.c \
+kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
+passdss_init.c sasldb_init.c sql_init.c ldapdb_init.c
+
+
+CLEANFILES=$(init_src)
+
+${init_src}: $(srcdir)/makeinit.sh
+       $(SHELL) $(srcdir)/makeinit.sh
+
+# Compatibility function build rules (they build in lib/)
+$(COMPAT_OBJS):
+       rm -f $(COMPAT_OBJS)
+       cd ../lib; $(MAKE) $(COMPAT_OBJS)
+       for file in $(COMPAT_OBJS); do ln -s ../lib/$$file .; done
+
+
diff --git a/plugins/Makefile.in b/plugins/Makefile.in
new file mode 100644 (file)
index 0000000..cd52645
--- /dev/null
@@ -0,0 +1,768 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the SASL plugins
+# Rob Siemborski
+# Rob Earhart
+# $Id: Makefile.am,v 1.78.2.1 2009/04/27 17:58:26 murch Exp $
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+# Library version info - here at the top, for sanity
+# CURRENT:REVISION:AGE
+anonymous_version = 2:23:0
+digestmd5_version = 2:23:0
+kerberos4_version = 2:23:0
+gssapiv2_version = 2:23:0
+crammd5_version = 2:23:0
+passdss_version = 2:23:0
+sasldb_version = 2:23:0
+login_version = 2:23:0
+plain_version = 2:23:0
+ntlm_version = 2:23:0
+otp_version = 2:23:0
+sql_version = 2:23:0
+ldapdb_version = 2:23:0
+srp_version = 2:23:0
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/sasldb -I$(top_builddir)/include
+AM_LDFLAGS = -module -export-dynamic -rpath $(plugindir)
+
+COMPAT_OBJS = @LTGETADDRINFOOBJS@ @LTGETNAMEINFOOBJS@ @LTSNPRINTFOBJS@
+
+EXTRA_DIST = makeinit.sh NTMakefile
+noinst_SCRIPTS = makeinit.sh
+
+common_sources = plugin_common.c plugin_common.h
+
+sasldir = $(prefix)/lib/sasl2
+sasl_LTLIBRARIES = @SASL_MECHS@
+EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \
+       libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \
+       libntlm.la libpassdss.la libsasldb.la libsql.la libldapdb.la
+
+
+libplain_la_SOURCES = plain.c plain_init.c $(common_sources)
+libplain_la_LDFLAGS = -version-info $(plain_version)
+libplain_la_DEPENDENCIES = $(COMPAT_OBJS)
+libplain_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
+
+libanonymous_la_SOURCES = anonymous.c anonymous_init.c $(common_sources)
+libanonymous_la_LDFLAGS = -version-info $(anonymous_version)
+libanonymous_la_DEPENDENCIES = $(COMPAT_OBJS)
+libanonymous_la_LIBADD = $(COMPAT_OBJS)
+
+libkerberos4_la_SOURCES = kerberos4.c kerberos4_init.c $(common_sources)
+libkerberos4_la_LDFLAGS = -version-info $(kerberos4_version)
+libkerberos4_la_DEPENDENCIES = $(COMPAT_OBJS)
+libkerberos4_la_LIBADD = $(SASL_KRB_LIB) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+libgssapiv2_la_SOURCES = gssapi.c gssapiv2_init.c $(common_sources)
+libgssapiv2_la_LDFLAGS = -version-info $(gssapiv2_version)
+libgssapiv2_la_DEPENDENCIES = $(COMPAT_OBJS)
+libgssapiv2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+libcrammd5_la_SOURCES = cram.c crammd5_init.c $(common_sources)
+libcrammd5_la_LDFLAGS = -version-info $(crammd5_version)
+libcrammd5_la_DEPENDENCIES = $(COMPAT_OBJS)
+libcrammd5_la_LIBADD = $(COMPAT_OBJS)
+
+libdigestmd5_la_SOURCES = digestmd5.c digestmd5_init.c $(common_sources)
+libdigestmd5_la_LDFLAGS = -version-info $(digestmd5_version)
+libdigestmd5_la_DEPENDENCIES = $(COMPAT_OBJS)
+libdigestmd5_la_LIBADD = $(LIB_DES) $(LIB_SOCKET) $(COMPAT_OBJS)
+
+liblogin_la_SOURCES = login.c login_init.c $(common_sources)
+liblogin_la_LDFLAGS = -version-info $(login_version)
+liblogin_la_DEPENDENCIES = $(COMPAT_OBJS)
+liblogin_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS)
+
+libsrp_la_SOURCES = srp.c srp_init.c $(common_sources)
+libsrp_la_LDFLAGS = -version-info $(srp_version)
+libsrp_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsrp_la_LIBADD = $(SRP_LIBS) $(COMPAT_OBJS)
+
+libotp_la_SOURCES = otp.c otp_init.c otp.h $(common_sources)
+libotp_la_LDFLAGS = -version-info $(otp_version)
+libotp_la_DEPENDENCIES = $(COMPAT_OBJS)
+libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS)
+
+libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources)
+libntlm_la_LDFLAGS = -version-info $(ntlm_version)
+libntlm_la_DEPENDENCIES = $(COMPAT_OBJS)
+libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS)
+
+libpassdss_la_SOURCES = passdss.c passdss_init.c $(common_sources)
+libpassdss_la_LDFLAGS = -version-info $(passdss_version)
+libpassdss_la_DEPENDENCIES = $(COMPAT_OBJS)
+libpassdss_la_LIBADD = $(PASSDSS_LIBS) $(COMPAT_OBJS)
+
+# Auxprop Plugins
+libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources)
+libsasldb_la_LDFLAGS = -version-info $(sasldb_version)
+libsasldb_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsasldb_la_LIBADD = ../sasldb/libsasldb.la $(SASL_DB_LIB) $(COMPAT_OBJS)
+
+libldapdb_la_SOURCES = ldapdb.c ldapdb_init.c $(common_sources)
+libldapdb_la_LDFLAGS = $(LIB_LDAP) -version-info $(ldapdb_version)
+libldapdb_la_DEPENDENCIES = $(COMPAT_OBJS)
+libldapdb_la_LIBADD = $(COMPAT_OBJS)
+
+libsql_la_SOURCES = sql.c sql_init.c $(common_sources)
+libsql_la_LDFLAGS = $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) -version-info $(sql_version)
+libsql_la_DEPENDENCIES = $(COMPAT_OBJS)
+libsql_la_LIBADD = $(COMPAT_OBJS)
+
+
+# Instructions for making the _init files
+init_src = anonymous_init.c crammd5_init.c digestmd5_init.c gssapiv2_init.c \
+kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \
+passdss_init.c sasldb_init.c sql_init.c ldapdb_init.c
+
+
+CLEANFILES = $(init_src)
+subdir = plugins
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(sasl_LTLIBRARIES)
+
+am__objects_1 = plugin_common.lo
+am_libanonymous_la_OBJECTS = anonymous.lo anonymous_init.lo \
+       $(am__objects_1)
+libanonymous_la_OBJECTS = $(am_libanonymous_la_OBJECTS)
+am_libcrammd5_la_OBJECTS = cram.lo crammd5_init.lo $(am__objects_1)
+libcrammd5_la_OBJECTS = $(am_libcrammd5_la_OBJECTS)
+am_libdigestmd5_la_OBJECTS = digestmd5.lo digestmd5_init.lo \
+       $(am__objects_1)
+libdigestmd5_la_OBJECTS = $(am_libdigestmd5_la_OBJECTS)
+am_libgssapiv2_la_OBJECTS = gssapi.lo gssapiv2_init.lo $(am__objects_1)
+libgssapiv2_la_OBJECTS = $(am_libgssapiv2_la_OBJECTS)
+am_libkerberos4_la_OBJECTS = kerberos4.lo kerberos4_init.lo \
+       $(am__objects_1)
+libkerberos4_la_OBJECTS = $(am_libkerberos4_la_OBJECTS)
+am_libldapdb_la_OBJECTS = ldapdb.lo ldapdb_init.lo $(am__objects_1)
+libldapdb_la_OBJECTS = $(am_libldapdb_la_OBJECTS)
+am_liblogin_la_OBJECTS = login.lo login_init.lo $(am__objects_1)
+liblogin_la_OBJECTS = $(am_liblogin_la_OBJECTS)
+am_libntlm_la_OBJECTS = ntlm.lo ntlm_init.lo $(am__objects_1)
+libntlm_la_OBJECTS = $(am_libntlm_la_OBJECTS)
+am_libotp_la_OBJECTS = otp.lo otp_init.lo $(am__objects_1)
+libotp_la_OBJECTS = $(am_libotp_la_OBJECTS)
+am_libpassdss_la_OBJECTS = passdss.lo passdss_init.lo $(am__objects_1)
+libpassdss_la_OBJECTS = $(am_libpassdss_la_OBJECTS)
+am_libplain_la_OBJECTS = plain.lo plain_init.lo $(am__objects_1)
+libplain_la_OBJECTS = $(am_libplain_la_OBJECTS)
+am_libsasldb_la_OBJECTS = sasldb.lo sasldb_init.lo $(am__objects_1)
+libsasldb_la_OBJECTS = $(am_libsasldb_la_OBJECTS)
+am_libsql_la_OBJECTS = sql.lo sql_init.lo $(am__objects_1)
+libsql_la_OBJECTS = $(am_libsql_la_OBJECTS)
+am_libsrp_la_OBJECTS = srp.lo srp_init.lo $(am__objects_1)
+libsrp_la_OBJECTS = $(am_libsrp_la_OBJECTS)
+SCRIPTS = $(noinst_SCRIPTS)
+
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/anonymous.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/anonymous_init.Plo ./$(DEPDIR)/cram.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/crammd5_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/digestmd5.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/digestmd5_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/gssapi.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/gssapiv2_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/kerberos4.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/kerberos4_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/ldapdb.Plo ./$(DEPDIR)/ldapdb_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/login.Plo ./$(DEPDIR)/login_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/ntlm.Plo ./$(DEPDIR)/ntlm_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/otp.Plo ./$(DEPDIR)/otp_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/passdss.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/passdss_init.Plo ./$(DEPDIR)/plain.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/plain_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/plugin_common.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/sasldb.Plo ./$(DEPDIR)/sasldb_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/sql.Plo ./$(DEPDIR)/sql_init.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/srp.Plo ./$(DEPDIR)/srp_init.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libanonymous_la_SOURCES) $(libcrammd5_la_SOURCES) \
+       $(libdigestmd5_la_SOURCES) $(libgssapiv2_la_SOURCES) \
+       $(libkerberos4_la_SOURCES) $(libldapdb_la_SOURCES) \
+       $(liblogin_la_SOURCES) $(libntlm_la_SOURCES) \
+       $(libotp_la_SOURCES) $(libpassdss_la_SOURCES) \
+       $(libplain_la_SOURCES) $(libsasldb_la_SOURCES) \
+       $(libsql_la_SOURCES) $(libsrp_la_SOURCES)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(libanonymous_la_SOURCES) $(libcrammd5_la_SOURCES) $(libdigestmd5_la_SOURCES) $(libgssapiv2_la_SOURCES) $(libkerberos4_la_SOURCES) $(libldapdb_la_SOURCES) $(liblogin_la_SOURCES) $(libntlm_la_SOURCES) $(libotp_la_SOURCES) $(libpassdss_la_SOURCES) $(libplain_la_SOURCES) $(libsasldb_la_SOURCES) $(libsql_la_SOURCES) $(libsrp_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  plugins/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+saslLTLIBRARIES_INSTALL = $(INSTALL)
+install-saslLTLIBRARIES: $(sasl_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(sasldir)
+       @list='$(sasl_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f="`echo $$p | sed -e 's|^.*/||'`"; \
+           echo " $(LIBTOOL) --mode=install $(saslLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(sasldir)/$$f"; \
+           $(LIBTOOL) --mode=install $(saslLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(sasldir)/$$f; \
+         else :; fi; \
+       done
+
+uninstall-saslLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sasl_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(sasldir)/$$p"; \
+         $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(sasldir)/$$p; \
+       done
+
+clean-saslLTLIBRARIES:
+       -test -z "$(sasl_LTLIBRARIES)" || rm -f $(sasl_LTLIBRARIES)
+       @list='$(sasl_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libanonymous.la: $(libanonymous_la_OBJECTS) $(libanonymous_la_DEPENDENCIES) 
+       $(LINK)  $(libanonymous_la_LDFLAGS) $(libanonymous_la_OBJECTS) $(libanonymous_la_LIBADD) $(LIBS)
+libcrammd5.la: $(libcrammd5_la_OBJECTS) $(libcrammd5_la_DEPENDENCIES) 
+       $(LINK)  $(libcrammd5_la_LDFLAGS) $(libcrammd5_la_OBJECTS) $(libcrammd5_la_LIBADD) $(LIBS)
+libdigestmd5.la: $(libdigestmd5_la_OBJECTS) $(libdigestmd5_la_DEPENDENCIES) 
+       $(LINK)  $(libdigestmd5_la_LDFLAGS) $(libdigestmd5_la_OBJECTS) $(libdigestmd5_la_LIBADD) $(LIBS)
+libgssapiv2.la: $(libgssapiv2_la_OBJECTS) $(libgssapiv2_la_DEPENDENCIES) 
+       $(LINK)  $(libgssapiv2_la_LDFLAGS) $(libgssapiv2_la_OBJECTS) $(libgssapiv2_la_LIBADD) $(LIBS)
+libkerberos4.la: $(libkerberos4_la_OBJECTS) $(libkerberos4_la_DEPENDENCIES) 
+       $(LINK)  $(libkerberos4_la_LDFLAGS) $(libkerberos4_la_OBJECTS) $(libkerberos4_la_LIBADD) $(LIBS)
+libldapdb.la: $(libldapdb_la_OBJECTS) $(libldapdb_la_DEPENDENCIES) 
+       $(LINK)  $(libldapdb_la_LDFLAGS) $(libldapdb_la_OBJECTS) $(libldapdb_la_LIBADD) $(LIBS)
+liblogin.la: $(liblogin_la_OBJECTS) $(liblogin_la_DEPENDENCIES) 
+       $(LINK)  $(liblogin_la_LDFLAGS) $(liblogin_la_OBJECTS) $(liblogin_la_LIBADD) $(LIBS)
+libntlm.la: $(libntlm_la_OBJECTS) $(libntlm_la_DEPENDENCIES) 
+       $(LINK)  $(libntlm_la_LDFLAGS) $(libntlm_la_OBJECTS) $(libntlm_la_LIBADD) $(LIBS)
+libotp.la: $(libotp_la_OBJECTS) $(libotp_la_DEPENDENCIES) 
+       $(LINK)  $(libotp_la_LDFLAGS) $(libotp_la_OBJECTS) $(libotp_la_LIBADD) $(LIBS)
+libpassdss.la: $(libpassdss_la_OBJECTS) $(libpassdss_la_DEPENDENCIES) 
+       $(LINK)  $(libpassdss_la_LDFLAGS) $(libpassdss_la_OBJECTS) $(libpassdss_la_LIBADD) $(LIBS)
+libplain.la: $(libplain_la_OBJECTS) $(libplain_la_DEPENDENCIES) 
+       $(LINK)  $(libplain_la_LDFLAGS) $(libplain_la_OBJECTS) $(libplain_la_LIBADD) $(LIBS)
+libsasldb.la: $(libsasldb_la_OBJECTS) $(libsasldb_la_DEPENDENCIES) 
+       $(LINK)  $(libsasldb_la_LDFLAGS) $(libsasldb_la_OBJECTS) $(libsasldb_la_LIBADD) $(LIBS)
+libsql.la: $(libsql_la_OBJECTS) $(libsql_la_DEPENDENCIES) 
+       $(LINK)  $(libsql_la_LDFLAGS) $(libsql_la_OBJECTS) $(libsql_la_LIBADD) $(LIBS)
+libsrp.la: $(libsrp_la_OBJECTS) $(libsrp_la_DEPENDENCIES) 
+       $(LINK)  $(libsrp_la_LDFLAGS) $(libsrp_la_OBJECTS) $(libsrp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anonymous.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/anonymous_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cram.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crammd5_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digestmd5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/digestmd5_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gssapi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gssapiv2_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kerberos4.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kerberos4_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldapdb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldapdb_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/login_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntlm_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otp_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passdss.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passdss_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plain.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plain_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plugin_common.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sasldb.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sasldb_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sql_init.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/srp_init.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(SCRIPTS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(sasldir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-saslLTLIBRARIES \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-saslLTLIBRARIES
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-saslLTLIBRARIES
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-saslLTLIBRARIES ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-saslLTLIBRARIES install-strip installcheck \
+       installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-saslLTLIBRARIES
+
+
+${init_src}: $(srcdir)/makeinit.sh
+       $(SHELL) $(srcdir)/makeinit.sh
+
+# Compatibility function build rules (they build in lib/)
+$(COMPAT_OBJS):
+       rm -f $(COMPAT_OBJS)
+       cd ../lib; $(MAKE) $(COMPAT_OBJS)
+       for file in $(COMPAT_OBJS); do ln -s ../lib/$$file .; done
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/plugins/NTMakefile b/plugins/NTMakefile
new file mode 100755 (executable)
index 0000000..11f008e
--- /dev/null
@@ -0,0 +1,293 @@
+!INCLUDE ..\win32\common.mak
+
+!IF "$(NTLM)" == "1"
+PLUGINS_EXT=saslNTLM.dll
+!ELSE 
+PLUGINS_EXT=
+!ENDIF 
+
+!IF "$(GSSAPI)" == "CyberSafe"
+PLUGINS_EXT=$(PLUGINS_EXT) saslGSSAPI.dll
+!ENDIF 
+
+!IF "$(SRP)" == "1"
+PLUGINS_EXT=$(PLUGINS_EXT) saslSRP.dll
+!IF "$(DO_SRP_SETPASS)" == "1"
+SRP_FLAGS=/DDO_SRP_SETPASS=1
+!ENDIF 
+!ENDIF 
+
+!IF "$(OTP)" == "1"
+PLUGINS_EXT=$(PLUGINS_EXT) saslOTP.dll
+!ENDIF
+
+!IF "$(LDAP)" == "1"
+PLUGINS_EXT=$(PLUGINS_EXT) saslLDAPDB.dll
+
+# NB: linking to libsasl itself!!!
+LDAP_FLAGS = /I $(LDAP_INCLUDE)
+LDAP_LIBS = $(LDAP_LIB_BASE)\olber32.lib $(LDAP_LIB_BASE)\oldap32.lib ..\lib\libsasl.lib
+!ENDIF 
+
+!IF "$(SQL)" == "SQLITE"
+PLUGINS_EXT=$(PLUGINS_EXT) saslSQLITE.dll
+SQL_FLAGS= $(SQLITE_INCLUDES) /DHAVE_SQLITE=1
+SQLITE_LIBS = /libpath:$(SQLITE_LIBPATH) libsqlite.lib
+!ENDIF
+
+PLUGINS=saslANONYMOUS.dll \
+       saslPLAIN.dll \
+       saslCRAMMD5.dll \
+       saslDIGESTMD5.dll \
+       saslLOGIN.dll \
+       $(PLUGINS_EXT) \
+       saslSASLDB.dll
+
+generated_rc=saslANONYMOUS.rc saslPLAIN.rc saslCRAMMD5.rc saslDIGESTMD5.rc saslLOGIN.rc saslNTLM.rc saslGSSAPI.rc saslSRP.rc saslOTP.rc saslSASLDB.rc saslSQLITE.rc saslLDAPDB.rc
+
+# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ...
+# emulation on Windows, so there is no need to build getaddrinfo.c
+
+!IF "$(VCVER)" == "6"
+compat_sources = getaddrinfo.c getnameinfo.c
+compat_objs = getaddrinfo.obj getnameinfo.obj
+!ENDIF
+
+common_sources = plugin_common.c plugin_common.h
+common_objs = plugin_common.obj $(compat_objs)
+
+saslANONYMOUS_sources = anonymous.c anonymous_init.c $(common_sources)
+saslANONYMOUS_objs = anonymous.obj anonymous_init.obj $(common_objs)
+saslANONYMOUS_out = saslANONYMOUS.dll saslANONYMOUS.exp saslANONYMOUS.lib
+
+saslPLAIN_sources = plain.c plain_init.c $(common_sources)
+saslPLAIN_objs = plain.obj plain_init.obj $(common_objs)
+saslPLAIN_out = saslPLAIN.dll saslPLAIN.exp saslPLAIN.lib
+
+saslCRAMMD5_sources = cram.c crammd5_init.c $(common_sources)
+saslCRAMMD5_objs = cram.obj crammd5_init.obj $(common_objs)
+saslCRAMMD5_out = saslCRAMMD5.dll saslCRAMMD5.exp saslCRAMMD5.lib
+
+saslDIGESTMD5_sources = digestmd5.c digestmd5_init.c $(common_sources)
+saslDIGESTMD5_objs = digestmd5.obj digestmd5_init.obj $(common_objs)
+saslDIGESTMD5_out = saslDIGESTMD5.dll saslDIGESTMD5.exp saslDIGESTMD5.lib
+
+saslLOGIN_sources = login.c login_init.c $(common_sources)
+saslLOGIN_objs = login.obj login_init.obj $(common_objs)
+saslLOGIN_out = saslLOGIN.dll saslLOGIN.exp saslLOGIN.lib
+
+saslNTLM_sources = ntlm.c ntlm_init.c $(common_sources)
+saslNTLM_objs = ntlm.obj ntlm_init.obj $(common_objs)
+saslNTLM_out = saslNTLM.dll saslNTLM.exp saslNTLM.lib
+
+saslGSSAPI_sources = gssapi.c gssapiv2_init.c $(common_sources)
+saslGSSAPI_objs = gssapi.obj gssapiv2_init.obj $(common_objs)
+saslGSSAPI_out = saslGSSAPI.dll saslGSSAPI.exp saslGSSAPI.lib
+
+saslSRP_sources = srp.c srp_init.c $(common_sources)
+saslSRP_objs = srp.obj srp_init.obj $(common_objs)
+saslSRP_out = saslSRP.dll saslSRP.exp saslSRP.lib
+
+saslOTP_sources = otp.c otp_init.c $(common_sources)
+saslOTP_objs = otp.obj otp_init.obj $(common_objs)
+saslOTP_out = saslOTP.dll saslOTP.exp saslOTP.lib
+
+saslSQL_sources = sql.c sql_init.c $(common_sources)
+saslSQL_objs = sql.obj sql_init.obj $(common_objs)
+# saslSQL_out is an agregation of all generated files for all SQL plugins
+saslSQL_out = saslSQLITE.dll saslSQLITE.exp saslSQLITE.lib
+
+saslLDAPDB_sources = ldapdb.c $(common_sources)
+saslLDAPDB_objs = ldapdb.obj $(common_objs)
+saslLDAPDB_out = saslLDAPDB.dll saslLDAPDB.exp saslLDAPDB.lib
+
+!IF "$(NTLM)" == "1" || "$(SRP)" == "1" || "$(OTP)" == "1"
+OPENSSL_FLAGS= /I $(OPENSSL_INCLUDE)
+!ELSE 
+OPENSSL_FLAGS=
+!ENDIF 
+
+!IF "$(GSSAPI)" == "CyberSafe"
+GSS_FLAGS= /I $(GSSAPI_INCLUDE) /D "HAVE_GSS_C_NT_HOSTBASED_SERVICE" /D "HAVE_GSS_C_NT_USER_NAME"
+GSS_LIBS=/libpath:$(GSSAPI_LIBPATH) gssapi32.lib
+!ELSE 
+GSS_FLAGS=
+GSS_LIBS=
+!ENDIF 
+
+DIGEST_FLAGS=/D "WITH_RC4"
+
+# Auxprop Plugin
+libsasldb_sources = allockey.c db_berkeley.c
+libsasldb_objs = allockey.obj db_berkeley.obj
+
+saslSASLDB_sources = sasldb.c sasldb_init.c $(libsasldb_sources) $(common_sources)
+saslSASLDB_objs = sasldb.obj sasldb_init.obj $(libsasldb_objs) $(common_objs)
+saslSASLDB_out = saslSASLDB.dll saslSASLDB.exp saslSASLDB.lib
+
+all_objs = $(saslANONYMOUS_objs) $(saslPLAIN_objs) $(saslCRAMMD5_objs) $(saslDIGESTMD5_objs) $(saslLOGIN_objs) $(saslNTLM_objs) $(saslGSSAPI_objs) $(saslSRP_objs) $(saslOTP_objs) $(saslSASLDB_objs) $(saslSQL_objs) $(saslLDAPDB_objs)
+all_out = $(saslANONYMOUS_out) $(saslPLAIN_out) $(saslCRAMMD5_out) $(saslDIGESTMD5_out) $(saslLOGIN_out) $(saslNTLM_out) $(saslGSSAPI_out) $(saslSRP_out) $(saslOTP_out) $(saslSASLDB_out) $(saslSQL_out) $(saslLDAPDB_out)
+
+# LIBSASL_EXPORTS is required to export additional DB routines from sasldb
+DB_FLAGS = /I $(DB_INCLUDE) /I "..\sasldb" /D "LIBSASL_EXPORTS" /D "KEEP_DB_OPEN"
+
+!IF $(TARGET_WIN_SYSTEM) >= 51
+EXTRA_FLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(EXTRA_FLAGS)
+!ENDIF
+
+EXTRA_FLAGS=$(EXTRA_FLAGS) $(DB_FLAGS) $(OPENSSL_FLAGS) $(GSS_FLAGS) $(SRP_FLAGS) $(SQL_FLAGS) $(DIGEST_FLAGS) $(LDAP_FLAGS)
+CPPFLAGS = /I "..\win32\include" /I "." /I "..\include" $(EXTRA_FLAGS) /D "WIN32" /D "_WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL"
+
+DB_LIBS=/libpath:$(DB_LIBPATH) $(DB_LIB)
+OPENSSL_LIBS=/libpath:$(OPENSSL_LIBPATH) libeay32.lib ssleay32.lib
+
+# Where to install files from this directory
+libdir = $(prefix)\lib
+bindir = $(prefix)\bin\sasl2
+
+all : all-recursive
+
+#
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
+#
+# In order to force xcopy not to confirm if the second parameter is file or directory,
+# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
+# instead of libsasl.lib. Ugly, but works!
+#
+# Note, that we will copy all dlls here, not just $(PLUGINS). This is a bug, but it allows
+# us to copy GSSAPI plugin, which might not be in $(PLUGINS).
+#
+install: $(PLUGINS)
+       @xcopy *.dll $(bindir) /I /F /Y
+
+all-recursive : $(PLUGINS)
+
+getaddrinfo.c: ..\lib\getaddrinfo.c
+       copy ..\lib\getaddrinfo.c .
+
+getnameinfo.c: ..\lib\getnameinfo.c
+       copy ..\lib\getnameinfo.c .
+
+allockey.c: ..\sasldb\allockey.c
+       copy ..\sasldb\allockey.c .
+
+db_berkeley.c: ..\sasldb\db_berkeley.c
+       copy ..\sasldb\db_berkeley.c .
+
+#Add /pdb: option?
+
+saslANONYMOUS.dll: $(saslANONYMOUS_objs) saslANONYMOUS.res
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslANONYMOUS.dll" /implib:"saslANONYMOUS.lib" $(saslANONYMOUS_objs) saslANONYMOUS.res
+<<
+
+saslPLAIN.dll: $(saslPLAIN_objs) saslPLAIN.res
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslPLAIN.dll" /implib:"saslPLAIN.lib" $(saslPLAIN_objs) saslPLAIN.res
+<<
+
+saslCRAMMD5.dll: $(saslCRAMMD5_objs) saslCRAMMD5.res
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslCRAMMD5.dll" /implib:"saslCRAMMD5.lib" $(saslCRAMMD5_objs) saslCRAMMD5.res
+<<
+
+saslDIGESTMD5.dll: $(saslDIGESTMD5_objs) saslDIGESTMD5.res
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslDIGESTMD5.dll" /implib:"saslDIGESTMD5.lib" $(saslDIGESTMD5_objs) saslDIGESTMD5.res
+<<
+
+saslLOGIN.dll: $(saslLOGIN_objs) saslLOGIN.res
+       $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslLOGIN.dll" /implib:"saslLOGIN.lib" $(saslLOGIN_objs) saslLOGIN.res
+<<
+
+saslNTLM.dll: $(saslNTLM_objs) saslNTLM.res
+       $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslNTLM.dll" /implib:"saslNTLM.lib" $(saslNTLM_objs) saslNTLM.res
+<<
+
+saslGSSAPI.dll: $(saslGSSAPI_objs) saslGSSAPI.res
+       $(LINK32DLL) @<< $(GSS_LIBS) $(LINK32DLL_FLAGS) /out:"saslGSSAPI.dll" /implib:"saslGSSAPI.lib" $(saslGSSAPI_objs) saslGSSAPI.res
+<<
+
+saslSRP.dll: $(saslSRP_objs) saslSRP.res
+       $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslSRP.dll" /implib:"saslSRP.lib" $(saslSRP_objs) saslSRP.res
+<<
+
+saslOTP.dll: $(saslOTP_objs) saslOTP.res
+       $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslOTP.dll" /implib:"saslOTP.lib" $(saslOTP_objs) saslOTP.res
+<<
+
+saslSASLDB.dll: $(saslSASLDB_objs) saslSASLDB.res
+       $(LINK32DLL) @<< $(DB_LIBS) $(LINK32DLL_FLAGS) /out:"saslSASLDB.dll" /implib:"saslSASLDB.lib" $(saslSASLDB_objs) saslSASLDB.res
+<<
+
+saslSQLITE.dll: $(saslSQL_objs) saslSQLITE.res
+       $(LINK32DLL) @<< $(SQLITE_LIBS) $(LINK32DLL_FLAGS) /out:"saslSQLITE.dll" /implib:"saslSQLITE.lib" $(saslSQL_objs) saslSQLITE.res
+<<
+
+saslLDAPDB.dll: $(saslLDAPDB_objs) saslLDAPDB.res
+       $(LINK32DLL) @<< $(LDAP_LIBS) $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslLDAPDB.dll" /implib:"saslLDAPDB.lib" $(saslLDAPDB_objs) saslLDAPDB.res
+<<
+
+CLEAN :
+       -@erase $(all_objs)
+       -@erase "*.idb"
+       -@erase "*.pdb"
+       -@erase getaddrinfo.c
+       -@erase allockey.c
+       -@erase db_berkeley.c
+       -@erase getnameinfo.c
+       -@erase $(generated_rc)
+       -@erase "*.res"
+       -@erase $(all_out)
+
+.c.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.rc.res:
+       rc $<
+
+$(generated_rc):
+       copy <<temp.rc $@
+#include "afxres.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
+ PRODUCTVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "CompanyName", "Carnegie Mellon University\0"
+            VALUE "FileDescription", "CMU SASL $(@B) plugin\0"
+            VALUE "FileVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP).0\0"
+            VALUE "InternalName", "$(@B)\0"
+            VALUE "LegalCopyright", "Copyright (c) Carnegie Mellon University 2005\0"
+            VALUE "OriginalFilename", "$(@B).dll\0"
+            VALUE "ProductName", "Carnegie Mellon University SASL\0"
+            VALUE "ProductVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP)-0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
+<<
diff --git a/plugins/anonymous.c b/plugins/anonymous.c
new file mode 100644 (file)
index 0000000..7583f06
--- /dev/null
@@ -0,0 +1,389 @@
+/* Anonymous SASL plugin
+ * Rob Siemborski
+ * Tim Martin 
+ * $Id: anonymous.c,v 1.51 2004/09/08 11:10:52 mel 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h> 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <sasl.h>
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh 
+#include <sasl_anonymous_plugin_decl.h> 
+#endif 
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: anonymous.c,v 1.51 2004/09/08 11:10:52 mel Exp $";
+
+static const char anonymous_id[] = "anonymous";
+
+/*****************************  Server Section  *****************************/
+
+static int
+anonymous_server_mech_new(void *glob_context __attribute__((unused)),
+                         sasl_server_params_t *sparams,
+                         const char *challenge __attribute__((unused)),
+                         unsigned challen __attribute__((unused)),
+                         void **conn_context)
+{
+    /* holds state are in */
+    if (!conn_context) {
+       PARAMERROR( sparams->utils );
+       return SASL_BADPARAM;
+    }
+    
+    *conn_context = NULL;
+    
+    return SASL_OK;
+}
+
+static int
+anonymous_server_mech_step(void *conn_context __attribute__((unused)),
+                          sasl_server_params_t *sparams,
+                          const char *clientin,
+                          unsigned clientinlen,
+                          const char **serverout,
+                          unsigned *serveroutlen,
+                          sasl_out_params_t *oparams)
+{
+    char *clientdata;
+    int result;
+    
+    if (!sparams
+       || !serverout
+       || !serveroutlen
+       || !oparams) {
+       PARAMERROR( sparams->utils );
+       return SASL_BADPARAM;
+    }
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    if (!clientin) {
+       return SASL_CONTINUE;
+    }
+    
+    /* We force a truncation 255 characters (specified by RFC 2245) */
+    if (clientinlen > 255) clientinlen = 255;
+    
+    /* NULL-terminate the clientin... */
+    clientdata = sparams->utils->malloc(clientinlen + 1);
+    if (!clientdata) {
+       MEMERROR(sparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    strncpy(clientdata, clientin, clientinlen);
+    clientdata[clientinlen] = '\0';
+    
+    sparams->utils->log(sparams->utils->conn,
+                       SASL_LOG_NOTE,
+                       "ANONYMOUS login: \"%s\"",
+                       clientdata);
+    
+    if (clientdata != clientin) 
+       sparams->utils->free(clientdata);
+    
+    result = sparams->canon_user(sparams->utils->conn,
+                                anonymous_id, 0,
+                                SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+
+    if (result != SASL_OK) return result;
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t anonymous_server_plugins[] = 
+{
+    {
+       "ANONYMOUS",                    /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT,           /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST,    /* features */
+       NULL,                           /* glob_context */
+       &anonymous_server_mech_new,     /* mech_new */
+       &anonymous_server_mech_step,    /* mech_step */
+       NULL,                           /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int anonymous_server_plug_init(const sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_server_plug_t **pluglist,
+                              int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR( utils, "ANONYMOUS version mismatch" );
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = anonymous_server_plugins;
+    *plugcount = 1;  
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    char *out_buf;
+    unsigned out_buf_len;
+} client_context_t;
+
+static int
+anonymous_client_mech_new(void *glob_context __attribute__((unused)),
+                         sasl_client_params_t *cparams,
+                         void **conn_context)
+{
+    client_context_t *text;
+    
+    if (!conn_context) {
+       PARAMERROR(cparams->utils);
+       return SASL_BADPARAM;
+    }
+    
+    /* holds state are in */
+    text = cparams->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR(cparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int
+anonymous_client_mech_step(void *conn_context,
+                          sasl_client_params_t *cparams,
+                          const char *serverin __attribute__((unused)),
+                          unsigned serverinlen,
+                          sasl_interact_t **prompt_need,
+                          const char **clientout,
+                          unsigned *clientoutlen,
+                          sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    size_t userlen;
+    char hostname[256];
+    const char *user = NULL;
+    int user_result = SASL_OK;
+    int result;
+    
+    if (!cparams
+       || !clientout
+       || !clientoutlen
+       || !oparams) {
+       PARAMERROR( cparams->utils );
+       return SASL_BADPARAM;
+    }
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    if (serverinlen != 0) {
+       SETERROR( cparams->utils,
+                 "Nonzero serverinlen in ANONYMOUS continue_step" );
+       return SASL_BADPROT;
+    }
+    
+    /* check if sec layer strong enough */
+    if (cparams->props.min_ssf > cparams->external_ssf) {
+       SETERROR( cparams->utils, "SSF requested of ANONYMOUS plugin");
+       return SASL_TOOWEAK;
+    }
+    
+    /* try to get the trace info */
+    if (user == NULL) {
+       user_result = _plug_get_userid(cparams->utils, &user, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) {
+           return user_result;
+       }
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       cparams->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if (user_result == SASL_INTERACT) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(cparams->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter anonymous identification" : NULL,
+                              "",
+                              NULL, NULL,
+                              NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) return result;
+       
+       return SASL_INTERACT;
+    }
+    
+    if (!user || !*user) {
+       user = anonymous_id;
+    }
+    userlen = strlen(user);
+    
+    result = cparams->canon_user(cparams->utils->conn,
+                                anonymous_id, 0,
+                                SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) return result;
+    
+    memset(hostname, 0, sizeof(hostname));
+    gethostname(hostname, sizeof(hostname));
+    hostname[sizeof(hostname)-1] = '\0';
+    
+    *clientoutlen = (unsigned) (userlen + strlen(hostname) + 1);
+    
+    result = _plug_buf_alloc(cparams->utils, &text->out_buf,
+                            &text->out_buf_len, *clientoutlen);
+    
+    if (result != SASL_OK) return result;
+    
+    strcpy(text->out_buf, user);
+    text->out_buf[userlen] = '@';
+    /* use memcpy() instead of strcpy() so we don't add the NUL */
+    memcpy(text->out_buf + userlen + 1, hostname, strlen(hostname));
+    
+    *clientout = text->out_buf;
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return SASL_OK;
+}
+
+static void anonymous_client_dispose(void *conn_context,
+                                    const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if(!text) return;
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static const long anonymous_required_prompts[] = {
+    SASL_CB_LIST_END
+};
+
+static sasl_client_plug_t anonymous_client_plugins[] = 
+{
+    {
+       "ANONYMOUS",                    /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT,           /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST,    /* features */
+       anonymous_required_prompts,     /* required_prompts */
+       NULL,                           /* glob_context */
+       &anonymous_client_mech_new,     /* mech_new */
+       &anonymous_client_mech_step,    /* mech_step */
+       &anonymous_client_dispose,      /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int anonymous_client_plug_init(const sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_client_plug_t **pluglist,
+                              int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR( utils, "ANONYMOUS version mismatch" );
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = anonymous_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/anonymous_init.c b/plugins/anonymous_init.c
new file mode 100644 (file)
index 0000000..215cc20
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_anonymous_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( anonymous )
+SASL_SERVER_PLUG_INIT( anonymous )
+
diff --git a/plugins/cram.c b/plugins/cram.c
new file mode 100644 (file)
index 0000000..20f6e84
--- /dev/null
@@ -0,0 +1,678 @@
+/* CRAM-MD5 SASL plugin
+ * Rob Siemborski
+ * Tim Martin 
+ * $Id: cram.c,v 1.85 2004/09/08 10:57:56 mel 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.
+ */
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_cram_plugin_decl.h>
+#endif
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: cram.c,v 1.85 2004/09/08 10:57:56 mel Exp $";
+
+/* convert a string of 8bit chars to it's representation in hex
+ * using lowercase letters
+ */
+static char *convert16(unsigned char *in, int inlen, const sasl_utils_t *utils)
+{
+    static char hex[]="0123456789abcdef";
+    int lup;
+    char *out;
+
+    out = utils->malloc(inlen*2+1);
+    if (out == NULL) return NULL;
+    
+    for (lup=0; lup < inlen; lup++) {
+       out[lup*2] = hex[in[lup] >> 4];
+       out[lup*2+1] = hex[in[lup] & 15];
+    }
+
+    out[lup*2] = 0;
+    return out;
+}
+
+
+/*****************************  Server Section  *****************************/
+
+typedef struct server_context {
+    int state;
+
+    char *challenge;
+} server_context_t;
+
+static int
+crammd5_server_mech_new(void *glob_context __attribute__((unused)),
+                       sasl_server_params_t *sparams,
+                       const char *challenge __attribute__((unused)),
+                       unsigned challen __attribute__((unused)),
+                       void **conn_context)
+{
+    server_context_t *text;
+    
+    /* holds state are in */
+    text = sparams->utils->malloc(sizeof(server_context_t));
+    if (text == NULL) {
+       MEMERROR( sparams->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(server_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+/*
+ * Returns the current time (or part of it) in string form
+ *  maximum length=15
+ */
+static char *gettime(sasl_server_params_t *sparams)
+{
+    char *ret;
+    time_t t;
+    
+    t=time(NULL);
+    ret= sparams->utils->malloc(15);
+    if (ret==NULL) return NULL;
+    
+    /* the bottom bits are really the only random ones so if
+       we overflow we don't want to loose them */
+    snprintf(ret,15,"%lu",t%(0xFFFFFF));
+    
+    return ret;
+}
+
+static char *randomdigits(sasl_server_params_t *sparams)
+{
+    unsigned int num;
+    char *ret;
+    unsigned char temp[5]; /* random 32-bit number */
+    
+    sparams->utils->rand(sparams->utils->rpool,(char *) temp,4);
+    num=(temp[0] * 256 * 256 * 256) +
+       (temp[1] * 256 * 256) +
+       (temp[2] * 256) +
+       (temp[3] );
+    
+    ret = sparams->utils->malloc(15); /* there's no way an unsigned can be longer than this right? */
+    if (ret == NULL) return NULL;
+    sprintf(ret, "%u", num);
+    
+    return ret;
+}
+
+static int
+crammd5_server_mech_step1(server_context_t *text,
+                         sasl_server_params_t *sparams,
+                         const char *clientin __attribute__((unused)),
+                         unsigned clientinlen,
+                         const char **serverout,
+                         unsigned *serveroutlen,
+                         sasl_out_params_t *oparams __attribute__((unused)))
+{
+    char *time, *randdigits;
+           
+    /* we shouldn't have received anything */
+    if (clientinlen != 0) {
+       SETERROR(sparams->utils, "CRAM-MD5 does not accpet inital data");
+       return SASL_BADPROT;
+    }
+    
+    /* get time and a random number for the nonce */
+    time = gettime(sparams);
+    randdigits = randomdigits(sparams);
+    if ((time == NULL) || (randdigits == NULL)) {
+       MEMERROR( sparams->utils );
+       return SASL_NOMEM;
+    }
+    
+    /* allocate some space for the challenge */
+    text->challenge = sparams->utils->malloc(200 + 1);
+    if (text->challenge == NULL) {
+       MEMERROR(sparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    /* create the challenge */
+    snprintf(text->challenge, 200, "<%s.%s@%s>", randdigits, time,
+            sparams->serverFQDN);
+    
+    *serverout = text->challenge;
+    *serveroutlen = (unsigned) strlen(text->challenge);
+    
+    /* free stuff */
+    sparams->utils->free(time);    
+    sparams->utils->free(randdigits);    
+    
+    text->state = 2;
+    
+    return SASL_CONTINUE;
+}
+    
+static int
+crammd5_server_mech_step2(server_context_t *text,
+                         sasl_server_params_t *sparams,
+                         const char *clientin,
+                         unsigned clientinlen,
+                         const char **serverout __attribute__((unused)),
+                         unsigned *serveroutlen __attribute__((unused)),
+                         sasl_out_params_t *oparams)
+{
+    char *userid = NULL;
+    sasl_secret_t *sec = NULL;
+    int pos;
+    size_t len;
+    int result = SASL_FAIL;
+    const char *password_request[] = { SASL_AUX_PASSWORD,
+                                      "*cmusaslsecretCRAM-MD5",
+                                      NULL };
+    struct propval auxprop_values[3];
+    HMAC_MD5_CTX tmphmac;
+    HMAC_MD5_STATE md5state;
+    int clear_md5state = 0;
+    char *digest_str = NULL;
+    UINT4 digest[4];
+    
+    /* extract userid; everything before last space */
+    pos = clientinlen-1;
+    while ((pos > 0) && (clientin[pos] != ' ')) pos--;
+    
+    if (pos <= 0) {
+       SETERROR( sparams->utils,"need authentication name");
+       return SASL_BADPROT;
+    }
+    
+    userid = (char *) sparams->utils->malloc(pos+1);
+    if (userid == NULL) {
+       MEMERROR( sparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    /* copy authstr out */
+    memcpy(userid, clientin, pos);
+    userid[pos] = '\0';
+    
+    result = sparams->utils->prop_request(sparams->propctx, password_request);
+    if (result != SASL_OK) goto done;
+    
+    /* this will trigger the getting of the aux properties */
+    result = sparams->canon_user(sparams->utils->conn,
+                                userid, 0, SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                                oparams);
+    if (result != SASL_OK) goto done;
+    
+    result = sparams->utils->prop_getnames(sparams->propctx,
+                                          password_request,
+                                          auxprop_values);
+    if (result < 0 ||
+       ((!auxprop_values[0].name || !auxprop_values[0].values) &&
+        (!auxprop_values[1].name || !auxprop_values[1].values))) {
+       /* We didn't find this username */
+       sparams->utils->seterror(sparams->utils->conn,0,
+                                "no secret in database");
+       result = sparams->transition ? SASL_TRANS : SASL_NOUSER;
+       goto done;
+    }
+    
+    if (auxprop_values[0].name && auxprop_values[0].values) {
+       len = strlen(auxprop_values[0].values[0]);
+       if (len == 0) {
+           sparams->utils->seterror(sparams->utils->conn,0,
+                                    "empty secret");
+           result = SASL_FAIL;
+           goto done;
+       }
+       
+       sec = sparams->utils->malloc(sizeof(sasl_secret_t) + len);
+       if (!sec) goto done;
+       
+       sec->len = (unsigned) len;
+       strncpy((char *)sec->data, auxprop_values[0].values[0], len + 1);   
+       
+       clear_md5state = 1;
+       /* Do precalculation on plaintext secret */
+       sparams->utils->hmac_md5_precalc(&md5state, /* OUT */
+                                        sec->data,
+                                        sec->len);
+    } else if (auxprop_values[1].name && auxprop_values[1].values) {
+       /* We have a precomputed secret */
+       memcpy(&md5state, auxprop_values[1].values[0],
+              sizeof(HMAC_MD5_STATE));
+    } else {
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "Have neither type of secret");
+       return SASL_FAIL;
+    }
+    
+    /* erase the plaintext password */
+    sparams->utils->prop_erase(sparams->propctx, password_request[0]);
+
+    /* ok this is annoying:
+       so we have this half-way hmac transform instead of the plaintext
+       that means we half to:
+       -import it back into a md5 context
+       -do an md5update with the nonce 
+       -finalize it
+    */
+    sparams->utils->hmac_md5_import(&tmphmac, (HMAC_MD5_STATE *) &md5state);
+    sparams->utils->MD5Update(&(tmphmac.ictx),
+                             (const unsigned char *) text->challenge,
+                             (unsigned) strlen(text->challenge));
+    sparams->utils->hmac_md5_final((unsigned char *) &digest, &tmphmac);
+    
+    /* convert to base 16 with lower case letters */
+    digest_str = convert16((unsigned char *) digest, 16, sparams->utils);
+    
+    /* if same then verified 
+     *  - we know digest_str is null terminated but clientin might not be
+     *  - verify the length of clientin anyway!
+     */
+    len = strlen(digest_str);
+    if (clientinlen-pos-1 < len ||
+       strncmp(digest_str, clientin+pos+1, len) != 0) {
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "incorrect digest response");
+       result = SASL_BADAUTH;
+       goto done;
+    }
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    result = SASL_OK;
+    
+  done:
+    if (userid) sparams->utils->free(userid);
+    if (sec) _plug_free_secret(sparams->utils, &sec);
+
+    if (digest_str) sparams->utils->free(digest_str);
+    if (clear_md5state) memset(&md5state, 0, sizeof(md5state));
+    
+    return result;
+}
+
+static int crammd5_server_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)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    /* this should be well more than is ever needed */
+    if (clientinlen > 1024) {
+       SETERROR(sparams->utils, "CRAM-MD5 input longer than 1024 bytes");
+       return SASL_BADPROT;
+    }
+    
+    switch (text->state) {
+
+    case 1:
+       return crammd5_server_mech_step1(text, sparams,
+                                        clientin, clientinlen,
+                                        serverout, serveroutlen,
+                                        oparams);
+
+    case 2:
+       return crammd5_server_mech_step2(text, sparams,
+                                        clientin, clientinlen,
+                                        serverout, serveroutlen,
+                                        oparams);
+
+    default: /* should never get here */
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid CRAM-MD5 server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void crammd5_server_mech_dispose(void *conn_context,
+                                       const sasl_utils_t *utils)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->challenge) _plug_free_string(utils,&(text->challenge));
+    
+    utils->free(text);
+}
+
+static sasl_server_plug_t crammd5_server_plugins[] = 
+{
+    {
+       "CRAM-MD5",                     /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS,         /* security_flags */
+       SASL_FEAT_SERVER_FIRST,         /* features */
+       NULL,                           /* glob_context */
+       &crammd5_server_mech_new,       /* mech_new */
+       &crammd5_server_mech_step,      /* mech_step */
+       &crammd5_server_mech_dispose,   /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech avail */
+       NULL                            /* spare */
+    }
+};
+
+int crammd5_server_plug_init(const sasl_utils_t *utils,
+                            int maxversion,
+                            int *out_version,
+                            sasl_server_plug_t **pluglist,
+                            int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR( utils, "CRAM version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = crammd5_server_plugins;
+    *plugcount = 1;  
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    char *out_buf;
+    unsigned out_buf_len;
+} client_context_t;
+
+static int crammd5_client_mech_new(void *glob_context __attribute__((unused)), 
+                                  sasl_client_params_t *params,
+                                  void **conn_context)
+{
+    client_context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static char *make_hashed(sasl_secret_t *sec, char *nonce, int noncelen, 
+                        const sasl_utils_t *utils)
+{
+    unsigned char digest[24];  
+    char *in16;
+    
+    if (sec == NULL) return NULL;
+    
+    /* do the hmac md5 hash output 128 bits */
+    utils->hmac_md5((unsigned char *) nonce, noncelen,
+                   sec->data, sec->len, digest);
+    
+    /* convert that to hex form */
+    in16 = convert16(digest, 16, utils);
+    if (in16 == NULL) return NULL;
+    
+    return in16;
+}
+
+static int crammd5_client_mech_step(void *conn_context,
+                                   sasl_client_params_t *params,
+                                   const char *serverin,
+                                   unsigned serverinlen,
+                                   sasl_interact_t **prompt_need,
+                                   const char **clientout,
+                                   unsigned *clientoutlen,
+                                   sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    const char *authid = NULL;
+    sasl_secret_t *password = NULL;
+    unsigned int free_password = 0; /* set if we need to free password */
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    int result;
+    size_t maxsize;
+    char *in16 = NULL;
+
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    /* First check for absurd lengths */
+    if (serverinlen > 1024) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "CRAM-MD5 input longer than 1024 bytes");
+       return SASL_BADPROT;
+    }
+    
+    /* check if sec layer strong enough */
+    if (params->props.min_ssf > params->external_ssf) {
+       SETERROR( params->utils, "SSF requested of CRAM-MD5 plugin");
+       return SASL_TOOWEAK;
+    }
+    
+    /* try to get the userid */
+    if (oparams->authid == NULL) {
+       auth_result=_plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }
+    
+    /* try to get the password */
+    if (password == NULL) {
+       pass_result=_plug_get_password(params->utils, &password,
+                                      &free_password, prompt_need);
+       
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              NULL, NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) goto cleanup;
+       
+       return SASL_INTERACT;
+    }
+    
+    if (!password) {
+       PARAMERROR(params->utils);
+       return SASL_BADPARAM;
+    }
+    
+    result = params->canon_user(params->utils->conn, authid, 0,
+                               SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) goto cleanup;
+    
+    /*
+     * username SP digest (keyed md5 where key is passwd)
+     */
+    
+    in16 = make_hashed(password, (char *) serverin, serverinlen,
+                      params->utils);
+    
+    if (in16 == NULL) {
+       SETERROR(params->utils, "whoops, make_hashed failed us this time");
+       result = SASL_FAIL;
+       goto cleanup;
+    }
+    
+    maxsize = 32+1+strlen(oparams->authid)+30;
+    result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                            &(text->out_buf_len), (unsigned) maxsize);
+    if (result != SASL_OK) goto cleanup;
+    
+    snprintf(text->out_buf, maxsize, "%s %s", oparams->authid, in16);
+    
+    *clientout = text->out_buf;
+    *clientoutlen = (unsigned) strlen(*clientout);
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    result = SASL_OK;
+
+  cleanup:
+    /* get rid of private information */
+    if (in16) _plug_free_string(params->utils, &in16);
+    
+    /* get rid of all sensitive info */
+    if (free_password) _plug_free_secret(params-> utils, &password);
+
+    return result;
+}
+
+static void crammd5_client_mech_dispose(void *conn_context,
+                                       const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static sasl_client_plug_t crammd5_client_plugins[] = 
+{
+    {
+       "CRAM-MD5",                     /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS,         /* security_flags */
+       SASL_FEAT_SERVER_FIRST,         /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &crammd5_client_mech_new,       /* mech_new */
+       &crammd5_client_mech_step,      /* mech_step */
+       &crammd5_client_mech_dispose,   /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int crammd5_client_plug_init(const sasl_utils_t *utils,
+                            int maxversion,
+                            int *out_version,
+                            sasl_client_plug_t **pluglist,
+                            int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR( utils, "CRAM version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = crammd5_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/crammd5_init.c b/plugins/crammd5_init.c
new file mode 100644 (file)
index 0000000..c5382f8
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_crammd5_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( crammd5 )
+SASL_SERVER_PLUG_INIT( crammd5 )
+
diff --git a/plugins/digestmd5.c b/plugins/digestmd5.c
new file mode 100644 (file)
index 0000000..b6d0abd
--- /dev/null
@@ -0,0 +1,4097 @@
+/* DIGEST-MD5 SASL plugin
+ * Ken Murchison
+ * Rob Siemborski
+ * Tim Martin
+ * Alexey Melnikov 
+ * $Id: digestmd5.c,v 1.180 2006/04/26 17:39:26 mel 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.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#ifndef macintosh
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <ctype.h>
+
+/* DES support */
+#ifdef WITH_DES
+# ifdef WITH_SSL_DES
+#  include <openssl/des.h>
+#  include <openssl/opensslv.h>
+#  if (OPENSSL_VERSION_NUMBER >= 0x0090700f) && \
+      !defined(OPENSSL_ENABLE_OLD_DES_SUPPORT)
+#   define des_cblock DES_cblock
+#   define des_key_schedule DES_key_schedule
+#   define des_key_sched(k,ks) \
+           DES_key_sched((k),&(ks))
+#   define des_cbc_encrypt(i,o,l,k,iv,e) \
+           DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#   define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+           DES_ede2_cbc_encrypt((i),(o),(l),&(k1),&(k2),(iv),(e))
+#  endif /* OpenSSL 0.9.7+ w/o old DES support */
+# else /* system DES library */
+#ifdef HAVE_DES_H
+#  include <des.h>
+#endif
+# endif
+#endif /* WITH_DES */
+
+#ifdef WIN32
+# include <winsock2.h>
+#else /* Unix */
+# include <netinet/in.h>
+#endif /* WIN32 */
+
+#include <sasl.h>
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifndef WIN32
+extern int strcasecmp(const char *s1, const char *s2);
+#endif /* end WIN32 */
+
+#ifdef macintosh
+#include <sasl_md5_plugin_decl.h>
+#endif
+
+/* external definitions */
+
+#ifdef sun
+/* gotta define gethostname ourselves on suns */
+extern int      gethostname(char *, int);
+#endif
+
+#define bool int
+
+#ifndef TRUE
+#define TRUE  (1)
+#define FALSE (0)
+#endif
+
+/* MAX_UIN32_DIV_10 * 10 + MAX_UIN32_MOD_10 == 2^32-1 == 4294967295 */
+#define MAX_UIN32_DIV_10    429496729
+#define MAX_UIN32_MOD_10    5
+
+#define DEFAULT_BUFSIZE            0xFFFF
+#define MAX_SASL_BUFSIZE    0xFFFFFF
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: digestmd5.c,v 1.180 2006/04/26 17:39:26 mel Exp $";
+
+/* Definitions */
+#define NONCE_SIZE (32)                /* arbitrary */
+
+/* Layer Flags */
+#define DIGEST_NOLAYER    (1)
+#define DIGEST_INTEGRITY  (2)
+#define DIGEST_PRIVACY    (4)
+
+/* defines */
+#define HASHLEN 16
+typedef unsigned char HASH[HASHLEN + 1];
+#define HASHHEXLEN 32
+typedef unsigned char HASHHEX[HASHHEXLEN + 1];
+
+#define MAC_SIZE 10
+#define MAC_OFFS 2
+
+const char *SEALING_CLIENT_SERVER="Digest H(A1) to client-to-server sealing key magic constant";
+const char *SEALING_SERVER_CLIENT="Digest H(A1) to server-to-client sealing key magic constant";
+
+const char *SIGNING_CLIENT_SERVER="Digest session key to client-to-server signing key magic constant";
+const char *SIGNING_SERVER_CLIENT="Digest session key to server-to-client signing key magic constant";
+
+#define HT     (9)
+#define CR     (13)
+#define LF     (10)
+#define SP     (32)
+#define DEL    (127)
+
+#define NEED_ESCAPING  "\"\\"
+
+#define REALM_CHAL_PREFIX      "Available realms:"
+
+static char *quote (char *str);
+
+struct context;
+
+/* function definitions for cipher encode/decode */
+typedef int cipher_function_t(struct context *,
+                             const char *,
+                             unsigned,
+                             unsigned char[],
+                             char *,
+                             unsigned *);
+
+typedef int cipher_init_t(struct context *, unsigned char [16], 
+                                            unsigned char [16]);
+typedef void cipher_free_t(struct context *);
+
+enum Context_type { SERVER = 0, CLIENT = 1 };
+
+typedef struct cipher_context cipher_context_t;
+
+/* cached auth info used for fast reauth */
+typedef struct reauth_entry {
+    char *authid;
+    char *realm;
+    unsigned char *nonce;
+    unsigned int nonce_count;
+    unsigned char *cnonce;
+
+    union {
+       struct {
+           time_t timestamp;
+       } s; /* server stuff */
+
+       struct {
+           char *serverFQDN;
+           int protection;
+           struct digest_cipher *cipher;
+           unsigned long server_maxbuf;
+       } c; /* client stuff */
+    } u;
+} reauth_entry_t;
+
+typedef struct reauth_cache {
+    /* static stuff */
+    enum Context_type i_am;    /* are we the client or server? */
+    time_t timeout;
+    void *mutex;
+    size_t size;
+
+    reauth_entry_t *e;         /* fixed-size hash table of entries */
+} reauth_cache_t;
+
+/* global context for reauth use */
+typedef struct digest_glob_context { 
+   reauth_cache_t *reauth; 
+} digest_glob_context_t;
+
+/* context that stores info */
+typedef struct context {
+    int state;                 /* state in the authentication we are in */
+    enum Context_type i_am;    /* are we the client or server? */
+    
+    reauth_cache_t *reauth;
+
+    char *authid;
+    char *realm;
+    unsigned char *nonce;
+    unsigned int nonce_count;
+    unsigned char *cnonce;
+
+    /* only used by the client */
+    char ** realms;
+    int realm_cnt;
+
+    char *response_value;
+    
+    unsigned int seqnum;
+    unsigned int rec_seqnum;   /* for checking integrity */
+    
+    HASH Ki_send;
+    HASH Ki_receive;
+    
+    HASH HA1;          /* Kcc or Kcs */
+    
+    /* copy of utils from the params structures */
+    const sasl_utils_t *utils;
+    
+    /* For general use */
+    char *out_buf;
+    unsigned out_buf_len;
+    
+    /* for encoding/decoding */
+    buffer_info_t *enc_in_buf;
+    char *encode_buf, *decode_buf, *decode_packet_buf;
+    unsigned encode_buf_len, decode_buf_len, decode_packet_buf_len;
+
+    decode_context_t decode_context;
+
+    /* if privacy mode is used use these functions for encode and decode */
+    cipher_function_t *cipher_enc;
+    cipher_function_t *cipher_dec;
+    cipher_init_t *cipher_init;
+    cipher_free_t *cipher_free;
+    struct cipher_context *cipher_enc_context;
+    struct cipher_context *cipher_dec_context;
+} context_t;
+
+struct digest_cipher {
+    char *name;
+    sasl_ssf_t ssf;
+    int n; /* bits to make privacy key */
+    int flag; /* a bitmask to make things easier for us */
+    
+    cipher_function_t *cipher_enc;
+    cipher_function_t *cipher_dec;
+    cipher_init_t *cipher_init;
+    cipher_free_t *cipher_free;
+};
+
+static const unsigned char *COLON = ":";
+
+/* Hashes a string to produce an unsigned short */
+static unsigned hash(const char *str)
+{
+    unsigned val = 0;
+    int i;
+
+    while (str && *str) {
+       i = (int) *str;
+       val ^= i;
+       val <<= 1;
+       str++;
+    }
+
+    return val;
+}
+
+static void CvtHex(HASH Bin, HASHHEX Hex)
+{
+    unsigned short  i;
+    unsigned char   j;
+    
+    for (i = 0; i < HASHLEN; i++) {
+       j = (Bin[i] >> 4) & 0xf;
+       if (j <= 9)
+           Hex[i * 2] = (j + '0');
+       else
+           Hex[i * 2] = (j + 'a' - 10);
+       j = Bin[i] & 0xf;
+       if (j <= 9)
+           Hex[i * 2 + 1] = (j + '0');
+       else
+           Hex[i * 2 + 1] = (j + 'a' - 10);
+    }
+    Hex[HASHHEXLEN] = '\0';
+}
+
+/*
+ * calculate request-digest/response-digest as per HTTP Digest spec
+ */
+void
+DigestCalcResponse(const sasl_utils_t * utils,
+                  HASHHEX HA1, /* HEX(H(A1)) */
+                  unsigned char *pszNonce,     /* nonce from server */
+                  unsigned int pszNonceCount,  /* 8 hex digits */
+                  unsigned char *pszCNonce,    /* client nonce */
+                  unsigned char *pszQop,       /* qop-value: "", "auth",
+                                                * "auth-int" */
+                  unsigned char *pszDigestUri, /* requested URL */
+                  unsigned char *pszMethod,
+                  HASHHEX HEntity,     /* H(entity body) if qop="auth-int" */
+                  HASHHEX Response     /* request-digest or response-digest */
+    )
+{
+    MD5_CTX         Md5Ctx;
+    HASH            HA2;
+    HASH            RespHash;
+    HASHHEX         HA2Hex;
+    char ncvalue[10];
+    
+    /* calculate H(A2) */
+    utils->MD5Init(&Md5Ctx);
+    
+    if (pszMethod != NULL) {
+       utils->MD5Update(&Md5Ctx, pszMethod, strlen((char *) pszMethod));
+    }
+    utils->MD5Update(&Md5Ctx, (unsigned char *) COLON, 1);
+    
+    /* utils->MD5Update(&Md5Ctx, (unsigned char *) "AUTHENTICATE:", 13); */
+    utils->MD5Update(&Md5Ctx, pszDigestUri, strlen((char *) pszDigestUri));
+    if (strcasecmp((char *) pszQop, "auth") != 0) {
+       /* append ":00000000000000000000000000000000" */
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+       utils->MD5Update(&Md5Ctx, HEntity, HASHHEXLEN);
+    }
+    utils->MD5Final(HA2, &Md5Ctx);
+    CvtHex(HA2, HA2Hex);
+    
+    /* calculate response */
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, HA1, HASHHEXLEN);
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    utils->MD5Update(&Md5Ctx, pszNonce, strlen((char *) pszNonce));
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    if (*pszQop) {
+       sprintf(ncvalue, "%08x", pszNonceCount);
+       utils->MD5Update(&Md5Ctx, ncvalue, strlen(ncvalue));
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+       utils->MD5Update(&Md5Ctx, pszCNonce, strlen((char *) pszCNonce));
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+       utils->MD5Update(&Md5Ctx, pszQop, strlen((char *) pszQop));
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+    }
+    utils->MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN);
+    utils->MD5Final(RespHash, &Md5Ctx);
+    CvtHex(RespHash, Response);
+}
+
+static bool UTF8_In_8859_1(const unsigned char *base, int len)
+{
+    const unsigned char *scan, *end;
+    
+    end = base + len;
+    for (scan = base; scan < end; ++scan) {
+       if (*scan > 0xC3)
+           break;                      /* abort if outside 8859-1 */
+       if (*scan >= 0xC0 && *scan <= 0xC3) {
+           if (++scan == end || *scan < 0x80 || *scan > 0xBF)
+               break;
+       }
+    }
+    
+    /* if scan >= end, then this is a 8859-1 string. */
+    return (scan >= end);
+}
+
+/*
+ * if the string is entirely in the 8859-1 subset of UTF-8, then translate to
+ * 8859-1 prior to MD5
+ */
+static void MD5_UTF8_8859_1(const sasl_utils_t * utils,
+                           MD5_CTX * ctx,
+                           bool In_ISO_8859_1,
+                           const unsigned char *base,
+                           int len)
+{
+    const unsigned char *scan, *end;
+    unsigned char   cbuf;
+    
+    end = base + len;
+    
+    /* if we found a character outside 8859-1, don't alter string */
+    if (!In_ISO_8859_1) {
+       utils->MD5Update(ctx, base, len);
+       return;
+    }
+    /* convert to 8859-1 prior to applying hash */
+    do {
+       for (scan = base; scan < end && *scan < 0xC0; ++scan);
+       if (scan != base)
+           utils->MD5Update(ctx, base, scan - base);
+       if (scan + 1 >= end)
+           break;
+       cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f);
+       utils->MD5Update(ctx, &cbuf, 1);
+       base = scan + 2;
+    }
+    while (base < end);
+}
+
+static void DigestCalcSecret(const sasl_utils_t * utils,
+                            unsigned char *pszUserName,
+                            unsigned char *pszRealm,
+                            unsigned char *Password,
+                            int PasswordLen,
+                            HASH HA1)
+{
+    bool            In_8859_1;
+    
+    MD5_CTX         Md5Ctx;
+    
+    /* Chris Newman clarified that the following text in DIGEST-MD5 spec
+       is bogus: "if name and password are both in ISO 8859-1 charset"
+       We shoud use code example instead */
+    
+    utils->MD5Init(&Md5Ctx);
+    
+    /* We have to convert UTF-8 to ISO-8859-1 if possible */
+    In_8859_1 = UTF8_In_8859_1(pszUserName, strlen((char *) pszUserName));
+    MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1,
+                   pszUserName, strlen((char *) pszUserName));
+    
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    
+    /* a NULL realm is equivalent to the empty string */
+    if (pszRealm != NULL && pszRealm[0] != '\0') {
+       /* We have to convert UTF-8 to ISO-8859-1 if possible */
+       In_8859_1 = UTF8_In_8859_1(pszRealm, strlen((char *) pszRealm));
+       MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1,
+                               pszRealm, strlen((char *) pszRealm));
+    }      
+    
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    
+    /* We have to convert UTF-8 to ISO-8859-1 if possible */
+    In_8859_1 = UTF8_In_8859_1(Password, PasswordLen);
+    MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1,
+                   Password, PasswordLen);
+    
+    utils->MD5Final(HA1, &Md5Ctx);
+}
+
+static unsigned char *create_nonce(const sasl_utils_t * utils)
+{
+    unsigned char  *base64buf;
+    int             base64len;
+    
+    char           *ret = (char *) utils->malloc(NONCE_SIZE);
+    if (ret == NULL)
+       return NULL;
+    
+    utils->rand(utils->rpool, (char *) ret, NONCE_SIZE);
+    
+    /* base 64 encode it so it has valid chars */
+    base64len = (NONCE_SIZE * 4 / 3) + (NONCE_SIZE % 3 ? 4 : 0);
+    
+    base64buf = (unsigned char *) utils->malloc(base64len + 1);
+    if (base64buf == NULL) {
+       utils->seterror(utils->conn, 0, "Unable to allocate final buffer");
+       return NULL;
+    }
+    
+    /*
+     * Returns SASL_OK on success, SASL_BUFOVER if result won't fit
+     */
+    if (utils->encode64(ret, NONCE_SIZE,
+                       (char *) base64buf, base64len, NULL) != SASL_OK) {
+       utils->free(ret);
+       return NULL;
+    }
+    utils->free(ret);
+    
+    return base64buf;
+}
+
+static int add_to_challenge(const sasl_utils_t *utils,
+                           char **str, unsigned *buflen, unsigned *curlen,
+                           char *name,
+                           unsigned char *value,
+                           bool need_quotes)
+{
+    int             namesize = strlen(name);
+    int             valuesize = strlen((char *) value);
+    int             ret;
+    
+    ret = _plug_buf_alloc(utils, str, buflen,
+                         *curlen + 1 + namesize + 2 + valuesize + 2);
+    if(ret != SASL_OK) return ret;
+
+    if (*curlen > 0) {
+       strcat(*str, ",");
+       strcat(*str, name);
+    } else {
+       strcpy(*str, name);
+    }
+    
+    if (need_quotes) {
+       strcat(*str, "=\"");
+
+       /* Check if the value needs quoting */
+       if (strpbrk ((char *)value, NEED_ESCAPING) != NULL) {
+           char * quoted = quote ((char *) value);
+           valuesize = strlen(quoted);
+           /* As the quoted string is bigger, make sure we have enough
+              space now */
+           ret = _plug_buf_alloc(utils, str, buflen,
+                         *curlen + 1 + namesize + 2 + valuesize + 2);
+           if (ret == SASL_OK) {
+               strcat(*str, quoted);
+               free (quoted);
+           } else {
+               free (quoted);
+               return ret;
+           }
+       } else {
+           strcat(*str, (char *) value);
+       }
+       strcat(*str, "\"");
+    } else {
+       strcat(*str, "=");
+       strcat(*str, (char *) value);
+    }
+    
+    *curlen = *curlen + 1 + namesize + 2 + valuesize + 2;
+    return SASL_OK;
+}
+
+static char *skip_lws (char *s)
+{
+    if (!s) return NULL;
+    
+    /* skipping spaces: */
+    while (s[0] == ' ' || s[0] == HT || s[0] == CR || s[0] == LF) {
+       if (s[0] == '\0') break;
+       s++;
+    }  
+    
+    return s;
+}
+
+/* Same as skip_lws, but do this right to left */
+/* skip LWSP at the end of the value (if any), skip_r_lws returns pointer to
+   the first LWSP character, NUL (if there were none) or NULL if the value
+   is entirely from LWSP characters */
+static char *skip_r_lws (char *s)
+{
+    char *end;
+    size_t len;
+
+    if (!s) return NULL;
+    
+    len = strlen(s);
+    if (len == 0) return NULL;
+
+    /* the last character before terminating NUL */
+    end = s + len - 1;
+
+    /* skipping spaces: */
+    while (end > s && (end[0] == ' ' || end[0] == HT || end[0] == CR || end[0] == LF)) {
+       end--;
+    }  
+
+    /* If all string from spaces, return NULL */
+    if (end == s && (end[0] == ' ' || end[0] == HT || end[0] == CR || end[0] == LF)) {
+       return NULL;
+    } else {
+       return (end + 1);
+    }
+}
+
+static char *skip_token (char *s, int caseinsensitive)
+{
+    if(!s) return NULL;
+    
+    while (s[0]>SP) {
+       if (s[0]==DEL || s[0]=='(' || s[0]==')' || s[0]=='<' || s[0]=='>' ||
+           s[0]=='@' || s[0]==',' || s[0]==';' || s[0]==':' || s[0]=='\\' ||
+           s[0]=='\'' || s[0]=='/' || s[0]=='[' || s[0]==']' || s[0]== '?' ||
+           s[0]=='=' || s[0]== '{' || s[0]== '}') {
+           if (caseinsensitive == 1) {
+               if (!isupper((unsigned char) s[0]))
+                   break;
+           } else {
+               break;
+           }
+       }
+       s++;
+    }  
+    return s;
+}
+
+/* Convert a string to 32 bit unsigned integer.
+   Any number of trailing spaces is allowed, but not a string
+   entirely comprised of spaces */
+static bool str2ul32 (char *str, unsigned long * value)
+{
+    unsigned int n;
+    char c;
+
+    if (str == NULL) {
+       return (FALSE);
+    }
+    
+    *value = 0;
+
+    str = skip_lws (str);
+    if (str[0] == '\0') {
+       return (FALSE);
+    }
+
+    n = 0;
+    while (str[0] != '\0') {
+       c = str[0];
+       if (!isdigit((int)c)) {
+           return (FALSE);
+       }
+
+/* Will overflow after adding additional digit */
+       if (n > MAX_UIN32_DIV_10) {
+           return (FALSE);
+       } else if (n == MAX_UIN32_DIV_10 && ((unsigned) (c - '0') > MAX_UIN32_MOD_10)) {
+           return (FALSE);
+       }
+
+       n = n * 10 + (unsigned) (c - '0');
+       str++;
+    }
+
+    *value = n;
+    return (TRUE);
+}
+
+/* NULL - error (unbalanced quotes), 
+   otherwise pointer to the first character after the value.
+   The function performs work in place. */
+static char *unquote (char *qstr)
+{
+    char *endvalue;
+    int   escaped = 0;
+    char *outptr;
+    
+    if(!qstr) return NULL;
+    
+    if (qstr[0] == '"') {
+       qstr++;
+       outptr = qstr;
+       
+       for (endvalue = qstr; endvalue[0] != '\0'; endvalue++, outptr++) {
+           if (escaped) {
+               outptr[0] = endvalue[0];
+               escaped = 0;
+           }
+           else if (endvalue[0] == '\\') {
+               escaped = 1;
+               outptr--; /* Will be incremented at the end of the loop */
+           }
+           else if (endvalue[0] == '"') {
+               break;
+           }      
+           else {
+               outptr[0] = endvalue[0];      
+           }
+       }
+       
+       if (endvalue[0] != '"') {
+           return NULL;
+       }
+       
+       while (outptr <= endvalue) {
+           outptr[0] = '\0';
+           outptr++;
+       }
+       endvalue++;
+    }
+    else { /* not qouted value (token) */
+       /* qstr already contains output */
+       endvalue = skip_token(qstr,0);
+    };
+    
+    return endvalue;  
+}
+
+/* Unlike unquote, this function returns an allocated quoted copy */
+static char *quote (char *str)
+{
+    char *p;
+    char *outp;
+    char *result;
+    int num_to_escape;         /* How many characters need escaping */
+    
+    if (!str) return NULL;
+
+    num_to_escape = 0;
+    p = strpbrk (str, NEED_ESCAPING);
+    while (p != NULL) {
+       num_to_escape++;
+       p = strpbrk (p + 1, NEED_ESCAPING);
+    }
+
+    if (num_to_escape == 0) {
+       return (strdup (str));
+    }
+
+    result = malloc (strlen(str) + num_to_escape + 1);
+    for (p = str, outp = result; *p; p++) {
+       if (*p == '"' || *p == '\\') {
+           *outp = '\\';
+           outp++;
+       }
+       *outp = *p;
+       outp++;
+    }
+
+    *outp = '\0';
+    
+    return (result);
+}
+
+static void get_pair(char **in, char **name, char **value)
+{
+    char  *endpair;
+    /* int    inQuotes; */
+    char  *curp = *in;
+    *name = NULL;
+    *value = NULL;
+    
+    if (curp == NULL) return;
+    if (curp[0] == '\0') return;
+    
+    /* skipping spaces: */
+    curp = skip_lws(curp);
+    
+    *name = curp;
+    
+    curp = skip_token(curp,1);
+    
+    /* strip wierd chars */
+    if (curp[0] != '=' && curp[0] != '\0') {
+       *curp++ = '\0';
+    };
+    
+    curp = skip_lws(curp);
+    
+    if (curp[0] != '=') { /* No '=' sign */ 
+       *name = NULL;
+       return;
+    }
+    
+    curp[0] = '\0';
+    curp++;
+    
+    curp = skip_lws(curp);  
+    
+    *value = (curp[0] == '"') ? curp+1 : curp;
+    
+    endpair = unquote (curp);
+    if (endpair == NULL) { /* Unbalanced quotes */ 
+       *name = NULL;
+       return;
+    }
+    if (endpair[0] != ',') {
+       if (endpair[0]!='\0') {
+           *endpair++ = '\0'; 
+       }
+    }
+    
+    endpair = skip_lws(endpair);
+    
+    /* syntax check: MUST be '\0' or ',' */  
+    if (endpair[0] == ',') {
+       endpair[0] = '\0';
+       endpair++; /* skipping <,> */
+    } else if (endpair[0] != '\0') { 
+       *name = NULL;
+       return;
+    }
+    
+    *in = endpair;
+}
+
+#ifdef WITH_DES
+struct des_context_s {
+    des_key_schedule keysched;  /* key schedule for des initialization */
+    des_cblock ivec;            /* initial vector for encoding */
+    des_key_schedule keysched2; /* key schedule for 3des initialization */
+};
+
+typedef struct des_context_s des_context_t;
+
+/* slide the first 7 bytes of 'inbuf' into the high seven bits of the
+   first 8 bytes of 'keybuf'. 'keybuf' better be 8 bytes long or longer. */
+static void slidebits(unsigned char *keybuf, unsigned char *inbuf)
+{
+    keybuf[0] = inbuf[0];
+    keybuf[1] = (inbuf[0]<<7) | (inbuf[1]>>1);
+    keybuf[2] = (inbuf[1]<<6) | (inbuf[2]>>2);
+    keybuf[3] = (inbuf[2]<<5) | (inbuf[3]>>3);
+    keybuf[4] = (inbuf[3]<<4) | (inbuf[4]>>4);
+    keybuf[5] = (inbuf[4]<<3) | (inbuf[5]>>5);
+    keybuf[6] = (inbuf[5]<<2) | (inbuf[6]>>6);
+    keybuf[7] = (inbuf[6]<<1);
+}
+
+/******************************
+ *
+ * 3DES functions
+ *
+ *****************************/
+
+static int dec_3des(context_t *text,
+                   const char *input,
+                   unsigned inputlen,
+                   unsigned char digest[16] __attribute__((unused)),
+                   char *output,
+                   unsigned *outputlen)
+{
+    des_context_t *c = (des_context_t *) text->cipher_dec_context;
+    int padding, p;
+    
+    des_ede2_cbc_encrypt((void *) input,
+                        (void *) output,
+                        inputlen,
+                        c->keysched,
+                        c->keysched2,
+                        &c->ivec,
+                        DES_DECRYPT);
+    
+    /* now chop off the padding */
+    padding = output[inputlen - 11];
+    if (padding < 1 || padding > 8) {
+       /* invalid padding length */
+       return SASL_FAIL;
+    }
+    /* verify all padding is correct */
+    for (p = 1; p <= padding; p++) {
+       if (output[inputlen - 10 - p] != padding) {
+           return SASL_FAIL;
+       }
+    }
+    
+    /* chop off the padding */
+    *outputlen = inputlen - padding - 10;
+
+    return SASL_OK;
+}
+
+static int enc_3des(context_t *text,
+                   const char *input,
+                   unsigned inputlen,
+                   unsigned char digest[16],
+                   char *output,
+                   unsigned *outputlen)
+{
+    des_context_t *c = (des_context_t *) text->cipher_enc_context;
+    int len;
+    int paddinglen;
+    
+    /* determine padding length */
+    paddinglen = 8 - ((inputlen + 10) % 8);
+    
+    /* now construct the full stuff to be ciphered */
+    memcpy(output, input, inputlen);                /* text */
+    memset(output+inputlen, paddinglen, paddinglen);/* pad  */
+    memcpy(output+inputlen+paddinglen, digest, 10); /* hmac */
+    
+    len=inputlen+paddinglen+10;
+    
+    des_ede2_cbc_encrypt((void *) output,
+                        (void *) output,
+                        len,
+                        c->keysched,
+                        c->keysched2,
+                        &c->ivec,
+                        DES_ENCRYPT);
+    
+    *outputlen=len;
+    
+    return SASL_OK;
+}
+
+static int init_3des(context_t *text, 
+                    unsigned char enckey[16],
+                    unsigned char deckey[16])
+{
+    des_context_t *c;
+    unsigned char keybuf[8];
+
+    /* allocate enc & dec context */
+    c = (des_context_t *) text->utils->malloc(2 * sizeof(des_context_t));
+    if (c == NULL) return SASL_NOMEM;
+
+    /* setup enc context */
+    slidebits(keybuf, enckey);
+    if (des_key_sched((des_cblock *) keybuf, c->keysched) < 0)
+       return SASL_FAIL;
+
+    slidebits(keybuf, enckey + 7);
+    if (des_key_sched((des_cblock *) keybuf, c->keysched2) < 0)
+       return SASL_FAIL;
+    memcpy(c->ivec, ((char *) enckey) + 8, 8);
+
+    text->cipher_enc_context = (cipher_context_t *) c;
+
+    /* setup dec context */
+    c++;
+    slidebits(keybuf, deckey);
+    if (des_key_sched((des_cblock *) keybuf, c->keysched) < 0)
+       return SASL_FAIL;
+    
+    slidebits(keybuf, deckey + 7);
+    if (des_key_sched((des_cblock *) keybuf, c->keysched2) < 0)
+       return SASL_FAIL;
+    
+    memcpy(c->ivec, ((char *) deckey) + 8, 8);
+
+    text->cipher_dec_context = (cipher_context_t *) c;
+    
+    return SASL_OK;
+}
+
+
+/******************************
+ *
+ * DES functions
+ *
+ *****************************/
+
+static int dec_des(context_t *text, 
+                  const char *input,
+                  unsigned inputlen,
+                  unsigned char digest[16] __attribute__((unused)),
+                  char *output,
+                  unsigned *outputlen)
+{
+    des_context_t *c = (des_context_t *) text->cipher_dec_context;
+    int p, padding = 0;
+    
+    des_cbc_encrypt((void *) input,
+                   (void *) output,
+                   inputlen,
+                   c->keysched,
+                   &c->ivec,
+                   DES_DECRYPT);
+
+    /* Update the ivec (des_cbc_encrypt implementations tend to be broken in
+       this way) */
+    memcpy(c->ivec, input + (inputlen - 8), 8);
+    
+    /* now chop off the padding */
+    padding = output[inputlen - 11];
+    if (padding < 1 || padding > 8) {
+       /* invalid padding length */
+       return SASL_FAIL;
+    }
+    /* verify all padding is correct */
+    for (p = 1; p <= padding; p++) {
+       if (output[inputlen - 10 - p] != padding) {
+           return SASL_FAIL;
+       }
+    }
+    
+    /* chop off the padding */
+    *outputlen = inputlen - padding - 10;
+
+    return SASL_OK;
+}
+
+static int enc_des(context_t *text,
+                  const char *input,
+                  unsigned inputlen,
+                  unsigned char digest[16],
+                  char *output,
+                  unsigned *outputlen)
+{
+    des_context_t *c = (des_context_t *) text->cipher_enc_context;
+    int len;
+    int paddinglen;
+  
+    /* determine padding length */
+    paddinglen = 8 - ((inputlen+10) % 8);
+
+    /* now construct the full stuff to be ciphered */
+    memcpy(output, input, inputlen);                /* text */
+    memset(output+inputlen, paddinglen, paddinglen);/* pad  */
+    memcpy(output+inputlen+paddinglen, digest, 10); /* hmac */
+    
+    len = inputlen + paddinglen + 10;
+    
+    des_cbc_encrypt((void *) output,
+                    (void *) output,
+                    len,
+                    c->keysched,
+                    &c->ivec,
+                    DES_ENCRYPT);
+    
+    /* Update the ivec (des_cbc_encrypt implementations tend to be broken in
+       this way) */
+    memcpy(c->ivec, output + (len - 8), 8);
+    
+    *outputlen = len;
+    
+    return SASL_OK;
+}
+
+static int init_des(context_t *text,
+                   unsigned char enckey[16],
+                   unsigned char deckey[16])
+{
+    des_context_t *c;
+    unsigned char keybuf[8];
+
+    /* allocate enc context */
+    c = (des_context_t *) text->utils->malloc(2 * sizeof(des_context_t));
+    if (c == NULL) return SASL_NOMEM;
+    
+    /* setup enc context */
+    slidebits(keybuf, enckey);
+    des_key_sched((des_cblock *) keybuf, c->keysched);
+
+    memcpy(c->ivec, ((char *) enckey) + 8, 8);
+    
+    text->cipher_enc_context = (cipher_context_t *) c;
+
+    /* setup dec context */
+    c++;
+    slidebits(keybuf, deckey);
+    des_key_sched((des_cblock *) keybuf, c->keysched);
+
+    memcpy(c->ivec, ((char *) deckey) + 8, 8);
+    
+    text->cipher_dec_context = (cipher_context_t *) c;
+
+    return SASL_OK;
+}
+
+static void free_des(context_t *text)
+{
+    /* free des contextss. only cipher_enc_context needs to be free'd,
+       since cipher_dec_context was allocated at the same time. */
+    if (text->cipher_enc_context) text->utils->free(text->cipher_enc_context);
+}
+
+#endif /* WITH_DES */
+
+#ifdef WITH_RC4
+/* quick generic implementation of RC4 */
+struct rc4_context_s {
+    unsigned char sbox[256];
+    int i, j;
+};
+
+typedef struct rc4_context_s rc4_context_t;
+
+static void rc4_init(rc4_context_t *text,
+                    const unsigned char *key,
+                    unsigned keylen)
+{
+    int i, j;
+    
+    /* fill in linearly s0=0 s1=1... */
+    for (i=0;i<256;i++)
+       text->sbox[i]=i;
+    
+    j=0;
+    for (i = 0; i < 256; i++) {
+       unsigned char tmp;
+       /* j = (j + Si + Ki) mod 256 */
+       j = (j + text->sbox[i] + key[i % keylen]) % 256;
+       
+       /* swap Si and Sj */
+       tmp = text->sbox[i];
+       text->sbox[i] = text->sbox[j];
+       text->sbox[j] = tmp;
+    }
+    
+    /* counters initialized to 0 */
+    text->i = 0;
+    text->j = 0;
+}
+
+static void rc4_encrypt(rc4_context_t *text,
+                       const char *input,
+                       char *output,
+                       unsigned len)
+{
+    int tmp;
+    int i = text->i;
+    int j = text->j;
+    int t;
+    int K;
+    const char *input_end = input + len;
+    
+    while (input < input_end) {
+       i = (i + 1) % 256;
+       
+       j = (j + text->sbox[i]) % 256;
+       
+       /* swap Si and Sj */
+       tmp = text->sbox[i];
+       text->sbox[i] = text->sbox[j];
+       text->sbox[j] = tmp;
+       
+       t = (text->sbox[i] + text->sbox[j]) % 256;
+       
+       K = text->sbox[t];
+       
+       /* byte K is Xor'ed with plaintext */
+       *output++ = *input++ ^ K;
+    }
+    
+    text->i = i;
+    text->j = j;
+}
+
+static void rc4_decrypt(rc4_context_t *text,
+                       const char *input,
+                       char *output,
+                       unsigned len)
+{
+    int tmp;
+    int i = text->i;
+    int j = text->j;
+    int t;
+    int K;
+    const char *input_end = input + len;
+    
+    while (input < input_end) {
+       i = (i + 1) % 256;
+       
+       j = (j + text->sbox[i]) % 256;
+       
+       /* swap Si and Sj */
+       tmp = text->sbox[i];
+       text->sbox[i] = text->sbox[j];
+       text->sbox[j] = tmp;
+       
+       t = (text->sbox[i] + text->sbox[j]) % 256;
+       
+       K = text->sbox[t];
+       
+       /* byte K is Xor'ed with plaintext */
+       *output++ = *input++ ^ K;
+    }
+    
+    text->i = i;
+    text->j = j;
+}
+
+static void free_rc4(context_t *text)
+{
+    /* free rc4 context structures */
+
+    if(text->cipher_enc_context) text->utils->free(text->cipher_enc_context);
+    if(text->cipher_dec_context) text->utils->free(text->cipher_dec_context);
+}
+
+static int init_rc4(context_t *text, 
+                   unsigned char enckey[16],
+                   unsigned char deckey[16])
+{
+    /* allocate rc4 context structures */
+    text->cipher_enc_context=
+       (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
+    if (text->cipher_enc_context == NULL) return SASL_NOMEM;
+    
+    text->cipher_dec_context=
+       (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t));
+    if (text->cipher_dec_context == NULL) return SASL_NOMEM;
+    
+    /* initialize them */
+    rc4_init((rc4_context_t *) text->cipher_enc_context,
+             (const unsigned char *) enckey, 16);
+    rc4_init((rc4_context_t *) text->cipher_dec_context,
+             (const unsigned char *) deckey, 16);
+    
+    return SASL_OK;
+}
+
+static int dec_rc4(context_t *text,
+                  const char *input,
+                  unsigned inputlen,
+                  unsigned char digest[16] __attribute__((unused)),
+                  char *output,
+                  unsigned *outputlen)
+{
+    /* decrypt the text part & HMAC */
+    rc4_decrypt((rc4_context_t *) text->cipher_dec_context, 
+                input, output, inputlen);
+
+    /* no padding so we just subtract the HMAC to get the text length */
+    *outputlen = inputlen - 10;
+    
+    return SASL_OK;
+}
+
+static int enc_rc4(context_t *text,
+                  const char *input,
+                  unsigned inputlen,
+                  unsigned char digest[16],
+                  char *output,
+                  unsigned *outputlen)
+{
+    /* pad is zero */
+    *outputlen = inputlen+10;
+    
+    /* encrypt the text part */
+    rc4_encrypt((rc4_context_t *) text->cipher_enc_context,
+                input,
+                output,
+                inputlen);
+    
+    /* encrypt the HMAC part */
+    rc4_encrypt((rc4_context_t *) text->cipher_enc_context, 
+                (const char *) digest, 
+               (output)+inputlen, 10);
+    
+    return SASL_OK;
+}
+
+#endif /* WITH_RC4 */
+
+struct digest_cipher available_ciphers[] =
+{
+#ifdef WITH_RC4
+    { "rc4-40", 40, 5, 0x01, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
+    { "rc4-56", 56, 7, 0x02, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
+    { "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 },
+#endif
+#ifdef WITH_DES
+    { "des", 55, 16, 0x08, &enc_des, &dec_des, &init_des, &free_des },
+    { "3des", 112, 16, 0x10, &enc_3des, &dec_3des, &init_3des, &free_des },
+#endif
+    { NULL, 0, 0, 0, NULL, NULL, NULL, NULL }
+};
+
+static int create_layer_keys(context_t *text,
+                            const sasl_utils_t *utils,
+                            HASH key, int keylen,
+                            char enckey[16], char deckey[16])
+{
+    MD5_CTX Md5Ctx;
+    
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, key, keylen);
+    if (text->i_am == SERVER) {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_SERVER_CLIENT, 
+                        strlen(SEALING_SERVER_CLIENT));
+    } else {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_CLIENT_SERVER,
+                        strlen(SEALING_CLIENT_SERVER));
+    }
+    utils->MD5Final((unsigned char *) enckey, &Md5Ctx);
+    
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, key, keylen);
+    if (text->i_am != SERVER) {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SEALING_SERVER_CLIENT, 
+                        strlen(SEALING_SERVER_CLIENT));
+    } else {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SEALING_CLIENT_SERVER,
+                        strlen(SEALING_CLIENT_SERVER));
+    }
+    utils->MD5Final((unsigned char *) deckey, &Md5Ctx);
+    
+    /* create integrity keys */
+    /* sending */
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, text->HA1, HASHLEN);
+    if (text->i_am == SERVER) {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_SERVER_CLIENT, 
+                        strlen(SIGNING_SERVER_CLIENT));
+    } else {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_CLIENT_SERVER,
+                        strlen(SIGNING_CLIENT_SERVER));
+    }
+    utils->MD5Final(text->Ki_send, &Md5Ctx);
+    
+    /* receiving */
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, text->HA1, HASHLEN);
+    if (text->i_am != SERVER) {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_SERVER_CLIENT, 
+                        strlen(SIGNING_SERVER_CLIENT));
+    } else {
+       utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_CLIENT_SERVER,
+                        strlen(SIGNING_CLIENT_SERVER));
+    }
+    utils->MD5Final(text->Ki_receive, &Md5Ctx);
+    
+    return SASL_OK;
+}
+
+static const unsigned short version = 1;
+
+/*
+ * privacy:
+ * len, CIPHER(Kc, {msg, pag, HMAC(ki, {SeqNum, msg})[0..9]}), x0001, SeqNum
+ *
+ * integrity:
+ * len, HMAC(ki, {SeqNum, msg})[0..9], x0001, SeqNum
+ */
+static int digestmd5_encode(void *context,
+                           const struct iovec *invec,
+                           unsigned numiov,
+                           const char **output,
+                           unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int tmp;
+    unsigned int tmpnum;
+    unsigned short int tmpshort;
+    int ret;
+    char *out;
+    struct buffer_info *inblob, bufinfo;
+    
+    if(!context || !invec || !numiov || !output || !outputlen) {
+       PARAMERROR(text->utils);
+       return SASL_BADPARAM;
+    }
+    
+    if (numiov > 1) {
+       ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf);
+       if (ret != SASL_OK) return ret;
+       inblob = text->enc_in_buf;
+    } else {
+       /* avoid the data copy */
+       bufinfo.data = invec[0].iov_base;
+       bufinfo.curlen = invec[0].iov_len;
+       inblob = &bufinfo;
+    }
+    
+    /* make sure the output buffer is big enough for this blob */
+    ret = _plug_buf_alloc(text->utils, &(text->encode_buf),
+                         &(text->encode_buf_len),
+                         (4 +                  /* for length */
+                          inblob->curlen +     /* for content */
+                          10 +                 /* for MAC */
+                          8 +                  /* maximum pad */
+                          6));                 /* for ver and seqnum */
+    if(ret != SASL_OK) return ret;
+    
+    /* skip by the length for now */
+    out = (text->encode_buf)+4;
+    
+    /* construct (seqnum, msg)
+     *
+     * Use the output buffer so that the message text is already in place
+     * for an integrity-only layer.
+     */
+    tmpnum = htonl(text->seqnum);
+    memcpy(text->encode_buf, &tmpnum, 4);
+    memcpy(text->encode_buf + 4, inblob->data, inblob->curlen);
+    
+    if (text->cipher_enc) {
+       unsigned char digest[16];
+
+       /* HMAC(ki, (seqnum, msg) ) */
+       text->utils->hmac_md5((const unsigned char *) text->encode_buf,
+                             inblob->curlen + 4, 
+                             text->Ki_send, HASHLEN, digest);
+
+       /* calculate the encrypted part */
+       text->cipher_enc(text, inblob->data, inblob->curlen,
+                        digest, out, outputlen);
+       out+=(*outputlen);
+    }
+    else {
+       /* HMAC(ki, (seqnum, msg) ) -- put directly into output buffer */
+       text->utils->hmac_md5((const unsigned char *) text->encode_buf,
+                             inblob->curlen + 4, 
+                             text->Ki_send, HASHLEN,
+                             text->encode_buf + inblob->curlen + 4);
+
+       *outputlen = inblob->curlen + 10; /* for message + CMAC */
+       out+=inblob->curlen + 10;
+    }
+    
+    /* copy in version */
+    tmpshort = htons(version);
+    memcpy(out, &tmpshort, 2); /* 2 bytes = version */
+    
+    out+=2;
+    (*outputlen)+=2; /* for version */
+    
+    /* put in seqnum */
+    tmpnum = htonl(text->seqnum);
+    memcpy(out, &tmpnum, 4);   /* 4 bytes = seq # */  
+    
+    (*outputlen)+=4; /* for seqnum */
+    
+    /* put the 1st 4 bytes in */
+    tmp=htonl(*outputlen);  
+    memcpy(text->encode_buf, &tmp, 4);
+    
+    (*outputlen)+=4;
+    
+    *output = text->encode_buf;
+    text->seqnum++;
+    
+    return SASL_OK;
+}
+
+static int digestmd5_decode_packet(void *context,
+                                          const char *input,
+                                          unsigned inputlen,
+                                          char **output,
+                                          unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int result;
+    unsigned char *digest;
+    int tmpnum;
+    int lup;
+    unsigned short ver;
+    unsigned int seqnum;
+    unsigned char checkdigest[16];
+       
+    if (inputlen < 16) {
+       text->utils->seterror(text->utils->conn, 0, "DIGEST-MD5 SASL packets must be at least 16 bytes long");
+       return SASL_FAIL;
+    }
+
+    /* check the version number */
+    memcpy(&ver, input+inputlen-6, 2);
+    ver = ntohs(ver);
+    if (ver != version) {
+       text->utils->seterror(text->utils->conn, 0, "Wrong Version");
+       return SASL_FAIL;
+    }
+       
+    /* check the sequence number */
+    memcpy(&seqnum, input+inputlen-4, 4);
+    seqnum = ntohl(seqnum);
+       
+    if (seqnum != text->rec_seqnum) {
+       text->utils->seterror(text->utils->conn, 0,
+                             "Incorrect Sequence Number");
+       return SASL_FAIL;
+    }
+
+    /* allocate a buffer large enough for the output */
+    result = _plug_buf_alloc(text->utils, &text->decode_packet_buf,
+                            &text->decode_packet_buf_len,
+                            inputlen   /* length of message */
+                            - 6        /* skip ver and seqnum */
+                            + 4);      /* prepend seqnum */
+    if (result != SASL_OK) return result;
+       
+    /* construct (seqnum, msg) */
+    tmpnum = htonl(text->rec_seqnum);
+    memcpy(text->decode_packet_buf, &tmpnum, 4);
+
+    text->rec_seqnum++; /* now increment it */
+
+    *output = text->decode_packet_buf + 4; /* skip seqnum */
+
+    if (text->cipher_dec) {
+       /* decrypt message & HMAC into output buffer */
+       result = text->cipher_dec(text, input, inputlen-6, NULL,
+                                 *output, outputlen);
+       if (result != SASL_OK) return result;
+    }
+    else {
+       /* copy message & HMAC into output buffer */
+       memcpy(*output, input, inputlen - 6);
+       *outputlen = inputlen - 16; /* -16 to skip HMAC, ver and seqnum */
+    }
+    digest = *output + (inputlen - 16);
+
+    /* check the CMAC */
+
+    /* HMAC(ki, (seqnum, msg) ) */
+    text->utils->hmac_md5((const unsigned char *) text->decode_packet_buf,
+                         (*outputlen) + 4, 
+                         text->Ki_receive, HASHLEN, checkdigest);
+       
+    /* now check it */
+    for (lup = 0; lup < 10; lup++)
+       if (checkdigest[lup] != digest[lup]) {
+           text->utils->seterror(text->utils->conn, 0,
+                                 "CMAC doesn't match at byte %d!", lup);
+           return SASL_FAIL;
+       }
+       
+    return SASL_OK;
+}
+
+static int digestmd5_decode(void *context,
+                                   const char *input, unsigned inputlen,
+                                   const char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+    
+    ret = _plug_decode(&text->decode_context, input, inputlen,
+                      &text->decode_buf, &text->decode_buf_len, outputlen,
+                      digestmd5_decode_packet, text);
+    
+    *output = text->decode_buf;
+    
+    return ret;
+}
+
+static void digestmd5_common_mech_dispose(void *conn_context,
+                                         const sasl_utils_t *utils)
+{
+    context_t *text = (context_t *) conn_context;
+    int lup;
+    
+    if (!text || !utils) return;
+    
+    if (text->authid) utils->free(text->authid);
+    if (text->realm) utils->free(text->realm);
+
+    if (text->realms) {
+       /* need to free all the realms */
+       for (lup = 0; lup < text->realm_cnt; lup++)
+           utils->free (text->realms[lup]);
+       
+       utils->free(text->realms);
+    }
+
+    if (text->nonce) utils->free(text->nonce);
+    if (text->cnonce) utils->free(text->cnonce);
+
+    if (text->cipher_free) text->cipher_free(text);
+    
+    /* free the stuff in the context */
+    if (text->response_value) utils->free(text->response_value);
+    
+    _plug_decode_free(&text->decode_context);
+    if (text->encode_buf) utils->free(text->encode_buf);
+    if (text->decode_buf) utils->free(text->decode_buf);
+    if (text->decode_packet_buf) utils->free(text->decode_packet_buf);
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    if (text->enc_in_buf) {
+       if (text->enc_in_buf->data) utils->free(text->enc_in_buf->data);
+       utils->free(text->enc_in_buf);
+    }
+    
+    utils->free(conn_context);
+}
+
+static void clear_reauth_entry(reauth_entry_t *reauth, enum Context_type type,
+                              const sasl_utils_t *utils)
+{
+    if (!reauth) return;
+
+    if (reauth->authid) utils->free(reauth->authid);
+    if (reauth->realm) utils->free(reauth->realm);
+    if (reauth->nonce) utils->free(reauth->nonce);
+    if (reauth->cnonce) utils->free(reauth->cnonce);
+
+    if (type == CLIENT) {
+       if (reauth->u.c.serverFQDN) utils->free(reauth->u.c.serverFQDN);
+    }
+
+    memset(reauth, 0, sizeof(reauth_entry_t));
+}
+
+static void digestmd5_common_mech_free(void *glob_context,
+                                      const sasl_utils_t *utils)
+{
+    digest_glob_context_t *my_glob_context =
+       (digest_glob_context_t *) glob_context;
+    reauth_cache_t *reauth_cache = my_glob_context->reauth;
+    size_t n;
+    
+    if (!reauth_cache) return;
+
+    for (n = 0; n < reauth_cache->size; n++)
+       clear_reauth_entry(&reauth_cache->e[n], reauth_cache->i_am, utils);
+    if (reauth_cache->e) utils->free(reauth_cache->e);
+
+    if (reauth_cache->mutex) utils->mutex_free(reauth_cache->mutex);
+
+    utils->free(reauth_cache);
+    my_glob_context->reauth = NULL;
+}
+
+/*****************************  Server Section  *****************************/
+
+typedef struct server_context {
+    context_t common;
+
+    time_t timestamp;
+    int stale;                         /* last nonce is stale */
+    sasl_ssf_t limitssf, requiressf;   /* application defined bounds */
+} server_context_t;
+
+static digest_glob_context_t server_glob_context;
+
+static void DigestCalcHA1FromSecret(context_t * text,
+                                   const sasl_utils_t * utils,
+                                   HASH HA1,
+                                   unsigned char *authorization_id,
+                                   unsigned char *pszNonce,
+                                   unsigned char *pszCNonce,
+                                   HASHHEX SessionKey)
+{
+    MD5_CTX Md5Ctx;
+    
+    /* calculate session key */
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, HA1, HASHLEN);
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    utils->MD5Update(&Md5Ctx, pszNonce, strlen((char *) pszNonce));
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    utils->MD5Update(&Md5Ctx, pszCNonce, strlen((char *) pszCNonce));
+    if (authorization_id != NULL) {
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+       utils->MD5Update(&Md5Ctx, authorization_id, strlen((char *) authorization_id));
+    }
+    utils->MD5Final(HA1, &Md5Ctx);
+    
+    CvtHex(HA1, SessionKey);
+    
+    
+    /* save HA1 because we need it to make the privacy and integrity keys */
+    memcpy(text->HA1, HA1, sizeof(HASH));
+}
+
+static char *create_response(context_t * text,
+                            const sasl_utils_t * utils,
+                            unsigned char *nonce,
+                            unsigned int ncvalue,
+                            unsigned char *cnonce,
+                            char *qop,
+                            char *digesturi,
+                            HASH Secret,
+                            char *authorization_id,
+                            char **response_value)
+{
+    HASHHEX         SessionKey;
+    HASHHEX         HEntity = "00000000000000000000000000000000";
+    HASHHEX         Response;
+    char           *result;
+    
+    if (qop == NULL)
+       qop = "auth";
+    
+    DigestCalcHA1FromSecret(text,
+                           utils,
+                           Secret,
+                           (unsigned char *) authorization_id,
+                           nonce,
+                           cnonce,
+                           SessionKey);
+    
+    DigestCalcResponse(utils,
+                      SessionKey,/* HEX(H(A1)) */
+                      nonce,   /* nonce from server */
+                      ncvalue, /* 8 hex digits */
+                      cnonce,  /* client nonce */
+                      (unsigned char *) qop,   /* qop-value: "", "auth",
+                                                * "auth-int" */
+                      (unsigned char *) digesturi,     /* requested URL */
+                      (unsigned char *) "AUTHENTICATE",
+                      HEntity, /* H(entity body) if qop="auth-int" */
+                      Response /* request-digest or response-digest */
+       );
+    
+    result = utils->malloc(HASHHEXLEN + 1);
+    memcpy(result, Response, HASHHEXLEN);
+    result[HASHHEXLEN] = 0;
+    
+    /* response_value (used for reauth i think */
+    if (response_value != NULL) {
+       DigestCalcResponse(utils,
+                          SessionKey,  /* HEX(H(A1)) */
+                          nonce,       /* nonce from server */
+                          ncvalue,     /* 8 hex digits */
+                          cnonce,      /* client nonce */
+                          (unsigned char *) qop,       /* qop-value: "", "auth",
+                                                        * "auth-int" */
+                          (unsigned char *) digesturi, /* requested URL */
+                          NULL,
+                          HEntity,     /* H(entity body) if qop="auth-int" */
+                          Response     /* request-digest or response-digest */
+           );
+       
+       *response_value = utils->malloc(HASHHEXLEN + 1);
+       if (*response_value == NULL)
+           return NULL;
+       memcpy(*response_value, Response, HASHHEXLEN);
+       (*response_value)[HASHHEXLEN] = 0;
+    }
+    return result;
+}
+
+static int get_server_realm(sasl_server_params_t * params, char **realm)
+{
+    /* look at user realm first */
+    if (params->user_realm != NULL) {
+       if(params->user_realm[0] != '\0') {
+           *realm = (char *) params->user_realm;
+       } else {
+           /* Catch improperly converted apps */
+           params->utils->seterror(params->utils->conn, 0,
+                                   "user_realm is an empty string!");
+           return SASL_BADPARAM;
+       }
+    } else if (params->serverFQDN != NULL) {
+       *realm = (char *) params->serverFQDN;
+    } else {
+       params->utils->seterror(params->utils->conn, 0,
+                               "no way to obtain domain");
+       return SASL_FAIL;
+    }
+    
+    return SASL_OK;
+}
+
+/*
+ * Convert hex string to int
+ */
+static int htoi(unsigned char *hexin, unsigned int *res)
+{
+    int             lup, inlen;
+    inlen = strlen((char *) hexin);
+    
+    *res = 0;
+    for (lup = 0; lup < inlen; lup++) {
+       switch (hexin[lup]) {
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+           *res = (*res << 4) + (hexin[lup] - '0');
+           break;
+           
+       case 'a':
+       case 'b':
+       case 'c':
+       case 'd':
+       case 'e':
+       case 'f':
+           *res = (*res << 4) + (hexin[lup] - 'a' + 10);
+           break;
+           
+       case 'A':
+       case 'B':
+       case 'C':
+       case 'D':
+       case 'E':
+       case 'F':
+           *res = (*res << 4) + (hexin[lup] - 'A' + 10);
+           break;
+           
+       default:
+           return SASL_BADPARAM;
+       }
+       
+    }
+    
+    return SASL_OK;
+}
+
+static int digestmd5_server_mech_new(void *glob_context,
+                                    sasl_server_params_t * sparams,
+                                    const char *challenge __attribute__((unused)),
+                                    unsigned challen __attribute__((unused)),
+                                    void **conn_context)
+{
+    context_t *text;
+    
+    /* holds state are in -- allocate server size */
+    text = sparams->utils->malloc(sizeof(server_context_t));
+    if (text == NULL)
+       return SASL_NOMEM;
+    memset(text, 0, sizeof(server_context_t));
+    
+    text->state = 1;
+    text->i_am = SERVER;
+    text->reauth = ((digest_glob_context_t *) glob_context)->reauth;
+    
+    *conn_context = text;
+    return SASL_OK;
+}
+
+static int
+digestmd5_server_mech_step1(server_context_t *stext,
+                           sasl_server_params_t *sparams,
+                           const char *clientin __attribute__((unused)),
+                           unsigned clientinlen __attribute__((unused)),
+                           const char **serverout,
+                           unsigned *serveroutlen,
+                           sasl_out_params_t * oparams __attribute__((unused)))
+{
+    context_t *text = (context_t *) stext;
+    int             result;
+    char           *realm;
+    unsigned char  *nonce;
+    char           *charset = "utf-8";
+    char qop[1024], cipheropts[1024];
+    struct digest_cipher *cipher;
+    unsigned       resplen;
+    int added_conf = 0;
+    char maxbufstr[64];
+    
+    sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG,
+                       "DIGEST-MD5 server step 1");
+
+    /* get realm */
+    result = get_server_realm(sparams, &realm);
+    if(result != SASL_OK) return result;
+    
+    /* what options should we offer the client? */
+    qop[0] = '\0';
+    cipheropts[0] = '\0';
+    if (stext->requiressf == 0) {
+       if (*qop) strcat(qop, ",");
+       strcat(qop, "auth");
+    }
+    if (stext->requiressf <= 1 && stext->limitssf >= 1) {
+       if (*qop) strcat(qop, ",");
+       strcat(qop, "auth-int");
+    }
+    
+    cipher = available_ciphers;
+    while (cipher->name) {
+       /* do we allow this particular cipher? */
+       if (stext->requiressf <= cipher->ssf &&
+           stext->limitssf >= cipher->ssf) {
+           if (!added_conf) {
+               if (*qop) strcat(qop, ",");
+               strcat(qop, "auth-conf");
+               added_conf = 1;
+           }
+           if (*cipheropts) strcat(cipheropts, ",");
+           strcat(cipheropts, cipher->name);
+       }
+       cipher++;
+    }
+    
+    if (*qop == '\0') {
+       /* we didn't allow anything?!? we'll return SASL_TOOWEAK, since
+          that's close enough */
+       return SASL_TOOWEAK;
+    }
+    
+    /*
+     * digest-challenge  = 1#( realm | nonce | qop-options | stale | maxbuf |
+     * charset | cipher-opts | auth-param )
+     */
+    
+    /* FIXME: get nonce XXX have to clean up after self if fail */
+    nonce = create_nonce(sparams->utils);
+    if (nonce == NULL) {
+       SETERROR(sparams->utils, "internal erorr: failed creating a nonce");
+       return SASL_FAIL;
+    }
+    
+    resplen = 0;
+    text->out_buf = NULL;
+    text->out_buf_len = 0;
+    if (add_to_challenge(sparams->utils,
+                                 &text->out_buf, &text->out_buf_len, &resplen,
+                                 "nonce", (unsigned char *) nonce,
+                                 TRUE) != SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge failed");
+       return SASL_FAIL;
+    }
+
+    /* add to challenge; if we chose not to specify a realm, we won't
+     * send one to the client */
+    if (realm && add_to_challenge(sparams->utils,
+                                 &text->out_buf, &text->out_buf_len, &resplen,
+                                 "realm", (unsigned char *) realm,
+                                 TRUE) != SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge failed");
+       return SASL_FAIL;
+    }
+    /*
+     * qop-options A quoted string of one or more tokens indicating the
+     * "quality of protection" values supported by the server.  The value
+     * "auth" indicates authentication; the value "auth-int" indicates
+     * authentication with integrity protection; the value "auth-conf"
+     * indicates authentication with integrity protection and encryption.
+     */
+    
+    /* add qop to challenge */
+    if (add_to_challenge(sparams->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "qop", 
+                        (unsigned char *) qop, TRUE) != SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge 3 failed");
+       return SASL_FAIL;
+    }
+    
+    /*
+     *  Cipheropts - list of ciphers server supports
+     */
+    /* add cipher-opts to challenge; only add if there are some */
+    if (strcmp(cipheropts,"")!=0)
+       {
+           if (add_to_challenge(sparams->utils,
+                                &text->out_buf, &text->out_buf_len, &resplen,
+                                "cipher", (unsigned char *) cipheropts, 
+                                TRUE) != SASL_OK) {
+               SETERROR(sparams->utils,
+                        "internal error: add_to_challenge 4 failed");
+               return SASL_FAIL;
+           }
+       }
+    
+    /* "stale" is true if a reauth failed because of a nonce timeout */
+    if (stext->stale &&
+       add_to_challenge(sparams->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "stale", "true", FALSE) != SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge failed");
+       return SASL_FAIL;
+    }
+    
+    /*
+     * maxbuf A number indicating the size of the largest buffer the server
+     * is able to receive when using "auth-int". If this directive is
+     * missing, the default value is 65536. This directive may appear at most
+     * once; if multiple instances are present, the client should abort the
+     * authentication exchange.
+     */
+    if(sparams->props.maxbufsize) {
+       snprintf(maxbufstr, sizeof(maxbufstr), "%u",
+                sparams->props.maxbufsize);
+       if (add_to_challenge(sparams->utils,
+                            &text->out_buf, &text->out_buf_len, &resplen,
+                            "maxbuf", 
+                            (unsigned char *) maxbufstr, FALSE) != SASL_OK) {
+           SETERROR(sparams->utils,
+                    "internal error: add_to_challenge 5 failed");
+           return SASL_FAIL;
+       }
+    }
+    
+
+    if (add_to_challenge(sparams->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "charset", 
+                        (unsigned char *) charset, FALSE) != SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge 6 failed");
+       return SASL_FAIL;
+    }
+    
+    
+    /*
+     * algorithm 
+     *  This directive is required for backwards compatibility with HTTP 
+     *  Digest., which supports other algorithms. . This directive is 
+     *  required and MUST appear exactly once; if not present, or if multiple 
+     *  instances are present, the client should abort the authentication 
+     *  exchange. 
+     *
+     * algorithm         = "algorithm" "=" "md5-sess" 
+     */
+    
+    if (add_to_challenge(sparams->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "algorithm",
+                        (unsigned char *) "md5-sess", FALSE)!=SASL_OK) {
+       SETERROR(sparams->utils, "internal error: add_to_challenge 7 failed");
+       return SASL_FAIL;
+    }
+    
+    /*
+     * The size of a digest-challenge MUST be less than 2048 bytes!!!
+     */
+    if (*serveroutlen > 2048) {
+       SETERROR(sparams->utils,
+                "internal error: challenge larger than 2048 bytes");
+       return SASL_FAIL;
+    }
+
+    text->authid = NULL;
+    _plug_strdup(sparams->utils, realm, &text->realm, NULL);
+    text->nonce = nonce;
+    text->nonce_count = 1;
+    text->cnonce = NULL;
+    stext->timestamp = time(0);
+    
+    *serveroutlen = strlen(text->out_buf);
+    *serverout = text->out_buf;
+    
+    text->state = 2;
+    
+    return SASL_CONTINUE;
+}
+
+static int digestmd5_server_mech_step2(server_context_t *stext,
+                                      sasl_server_params_t *sparams,
+                                      const char *clientin,
+                                      unsigned clientinlen,
+                                      const char **serverout,
+                                      unsigned *serveroutlen,
+                                      sasl_out_params_t * oparams)
+{
+    context_t *text = (context_t *) stext;
+    /* verify digest */
+    sasl_secret_t  *sec = NULL;
+    int             result;
+    char           *serverresponse = NULL;
+    char           *username = NULL;
+    char           *authorization_id = NULL;
+    char           *realm = NULL;
+    unsigned char  *nonce = NULL, *cnonce = NULL;
+    unsigned int   noncecount = 0;
+    char           *qop = NULL;
+    char           *digesturi = NULL;
+    char           *response = NULL;
+    
+    /* setting the default value (65536) */
+    unsigned long  client_maxbuf = 65536;
+    int            maxbuf_count = 0;  /* How many maxbuf instaces was found */
+    
+    char           *charset = NULL;
+    char           *cipher = NULL;
+    unsigned int   n=0;
+    
+    HASH            Secret;
+    
+    /* password prop_request */
+    const char *password_request[] = { SASL_AUX_PASSWORD,
+                                      "*cmusaslsecretDIGEST-MD5",
+                                      NULL };
+    unsigned len;
+    struct propval auxprop_values[2];
+    
+    /* can we mess with clientin? copy it to be safe */
+    char           *in_start = NULL;
+    char           *in = NULL; 
+    
+    sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG,
+                       "DIGEST-MD5 server step 2");
+
+    in = sparams->utils->malloc(clientinlen + 1);
+    
+    memcpy(in, clientin, clientinlen);
+    in[clientinlen] = 0;
+    
+    in_start = in;
+    
+    
+    /* parse what we got */
+    while (in[0] != '\0') {
+       char           *name = NULL, *value = NULL;
+       get_pair(&in, &name, &value);
+       
+       if (name == NULL)
+           break;
+       
+       /* Extracting parameters */
+       
+       /*
+        * digest-response  = 1#( username | realm | nonce | cnonce |
+        * nonce-count | qop | digest-uri | response | maxbuf | charset |
+        * cipher | auth-param )
+        */
+       
+       if (strcasecmp(name, "username") == 0) {
+           _plug_strdup(sparams->utils, value, &username, NULL);
+       } else if (strcasecmp(name, "authzid") == 0) {
+           _plug_strdup(sparams->utils, value, &authorization_id, NULL);
+       } else if (strcasecmp(name, "cnonce") == 0) {
+           _plug_strdup(sparams->utils, value, (char **) &cnonce, NULL);
+       } else if (strcasecmp(name, "nc") == 0) {
+           if (htoi((unsigned char *) value, &noncecount) != SASL_OK) {
+               SETERROR(sparams->utils,
+                        "error converting hex to int");
+               result = SASL_BADAUTH;
+               goto FreeAllMem;
+           }
+       } else if (strcasecmp(name, "realm") == 0) {
+           if (realm) {
+               SETERROR(sparams->utils,
+                        "duplicate realm: authentication aborted");
+               result = SASL_FAIL;
+               goto FreeAllMem;
+           }
+           _plug_strdup(sparams->utils, value, &realm, NULL);
+       } else if (strcasecmp(name, "nonce") == 0) {
+           _plug_strdup(sparams->utils, value, (char **) &nonce, NULL);
+       } else if (strcasecmp(name, "qop") == 0) {
+           _plug_strdup(sparams->utils, value, &qop, NULL);
+       } else if (strcasecmp(name, "digest-uri") == 0) {
+            size_t service_len;
+
+           if (digesturi) {
+               SETERROR(sparams->utils,
+                        "duplicate digest-uri: authentication aborted");
+               result = SASL_FAIL;
+               goto FreeAllMem;
+           }
+
+           _plug_strdup(sparams->utils, value, &digesturi, NULL);
+
+           /* Verify digest-uri format:
+            *
+            * digest-uri-value  = serv-type "/" host [ "/" serv-name ]
+            */
+
+            /* make sure it's the service that we're expecting */
+            service_len = strlen(sparams->service);
+            if (strncasecmp(digesturi, sparams->service, service_len) ||
+                digesturi[service_len] != '/') {
+                result = SASL_BADAUTH;
+                SETERROR(sparams->utils, 
+                         "bad digest-uri: doesn't match service");
+                goto FreeAllMem;
+            }
+
+            /* xxx we don't verify the hostname component */
+            
+       } else if (strcasecmp(name, "response") == 0) {
+           _plug_strdup(sparams->utils, value, &response, NULL);
+       } else if (strcasecmp(name, "cipher") == 0) {
+           _plug_strdup(sparams->utils, value, &cipher, NULL);
+       } else if (strcasecmp(name, "maxbuf") == 0) {
+           maxbuf_count++;
+           if (maxbuf_count != 1) {
+               result = SASL_BADAUTH;
+               SETERROR(sparams->utils,
+                        "duplicate maxbuf: authentication aborted");
+               goto FreeAllMem;
+           } else if (str2ul32 (value, &client_maxbuf) == FALSE) {
+               result = SASL_BADAUTH;
+               SETERROR(sparams->utils, "invalid maxbuf parameter");
+               goto FreeAllMem;
+           } else {
+               if (client_maxbuf <= 16) {
+                   result = SASL_BADAUTH;
+                   SETERROR(sparams->utils,
+                            "maxbuf parameter too small");
+                   goto FreeAllMem;
+               }
+
+               if (client_maxbuf > MAX_SASL_BUFSIZE) {
+                   result = SASL_BADAUTH;
+                   SETERROR(sparams->utils,
+                            "maxbuf parameter too big");
+                   goto FreeAllMem;
+               }
+           }
+       } else if (strcasecmp(name, "charset") == 0) {
+           if (strcasecmp(value, "utf-8") != 0) {
+               SETERROR(sparams->utils, "client doesn't support UTF-8");
+               result = SASL_FAIL;
+               goto FreeAllMem;
+           }
+           _plug_strdup(sparams->utils, value, &charset, NULL);
+       } else {
+           sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG,
+                               "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
+                               name, value);
+       }
+    }
+    
+    /*
+     * username         = "username" "=" <"> username-value <">
+     * username-value   = qdstr-val
+     * cnonce           = "cnonce" "=" <"> cnonce-value <"> 
+     * cnonce-value     = qdstr-val
+     * nonce-count      = "nc" "=" nc-value
+     * nc-value         = 8LHEX
+     * qop              = "qop" "=" qop-value
+     * digest-uri       = "digest-uri" "=" digest-uri-value
+     * digest-uri-value = serv-type "/" host [ "/" serv-name ]
+     * serv-type        = 1*ALPHA
+     * host             = 1*( ALPHA | DIGIT | "-" | "." )
+     * service          = host
+     * response         = "response" "=" <"> response-value <">
+     * response-value   = 32LHEX
+     * LHEX             = "0" | "1" | "2" | "3" | "4" | "5" |
+     * "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f"
+     * cipher           = "cipher" "=" cipher-value
+     */
+    /* Verifing that all parameters was defined */
+    if ((username == NULL) ||
+       (nonce == NULL) ||
+       (noncecount == 0) ||
+       (cnonce == NULL) ||
+       (digesturi == NULL) ||
+       (response == NULL)) {
+       SETERROR(sparams->utils, "required parameters missing");
+       result = SASL_BADAUTH;
+       goto FreeAllMem;
+    }
+
+    if (text->state == 1) {
+       unsigned val = hash(username) % text->reauth->size;
+
+       /* reauth attempt, see if we have any info for this user */
+       if (sparams->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+           if (text->reauth->e[val].authid &&
+               !strcmp(username, text->reauth->e[val].authid)) {
+
+               _plug_strdup(sparams->utils, text->reauth->e[val].realm,
+                            &text->realm, NULL);
+               _plug_strdup(sparams->utils, text->reauth->e[val].nonce,
+                            (char **) &text->nonce, NULL);
+               text->nonce_count = ++text->reauth->e[val].nonce_count;
+               _plug_strdup(sparams->utils, text->reauth->e[val].cnonce,
+                            (char **) &text->cnonce, NULL);
+               stext->timestamp = text->reauth->e[val].u.s.timestamp;
+           }
+           sparams->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+       }
+
+       if (!text->nonce) {
+           /* we don't have any reauth info, so bail */
+           result = SASL_FAIL;
+           goto FreeAllMem;
+       }
+    }
+
+    /* Sanity check the parameters */
+    if (realm == NULL) {
+        /* From 2821bis:
+           If the directive is missing, "realm-value" will set to
+           the empty string when computing A1. */
+       _plug_strdup(sparams->utils, "", &realm, NULL);
+       sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG,
+                       "The client didn't send a realm, assuming empty string.");
+        if (text->realm[0] != '\0') {
+            SETERROR(sparams->utils,
+                "realm changed: authentication aborted");
+            result = SASL_BADAUTH;
+            goto FreeAllMem;
+        }
+
+    /* CLAIM: realm is not NULL below */
+    } else if ((strcmp(realm, text->realm) != 0) &&
+       (text->realm[0] != 0)) {
+       SETERROR(sparams->utils,
+                "realm changed: authentication aborted");
+       result = SASL_BADAUTH;
+       goto FreeAllMem;
+    }
+    if (strcmp(nonce, (char *) text->nonce) != 0) {
+       SETERROR(sparams->utils,
+                "nonce changed: authentication aborted");
+       result = SASL_BADAUTH;
+       goto FreeAllMem;
+    }
+    if (noncecount != text->nonce_count) {
+       SETERROR(sparams->utils,
+                "incorrect nonce-count: authentication aborted");
+       result = SASL_BADAUTH;
+       goto FreeAllMem;
+    }
+    if (text->cnonce && strcmp(cnonce, text->cnonce) != 0) {
+       SETERROR(sparams->utils,
+                "cnonce changed: authentication aborted");
+       result = SASL_BADAUTH;
+       goto FreeAllMem;
+    }
+           
+    result = sparams->utils->prop_request(sparams->propctx, password_request);
+    if(result != SASL_OK) {
+       SETERROR(sparams->utils, "unable to obtain user password");
+       goto FreeAllMem;
+    }
+    
+    /* this will trigger the getting of the aux properties */
+    /* Note that if we don't have an authorization id, we don't use it... */
+    result = sparams->canon_user(sparams->utils->conn,
+                                username, 0, SASL_CU_AUTHID, oparams);
+    if (result != SASL_OK) {
+       SETERROR(sparams->utils, "unable canonify user and get auxprops");
+       goto FreeAllMem;
+    }
+    
+    if (!authorization_id || !*authorization_id) {
+       result = sparams->canon_user(sparams->utils->conn,
+                                    username, 0, SASL_CU_AUTHZID, oparams);
+    } else {
+       result = sparams->canon_user(sparams->utils->conn,
+                                    authorization_id, 0, SASL_CU_AUTHZID,
+                                    oparams);
+    }
+    
+    if (result != SASL_OK) {
+       SETERROR(sparams->utils, "unable authorization ID");
+       goto FreeAllMem;
+    }
+    
+    result = sparams->utils->prop_getnames(sparams->propctx, password_request,
+                                          auxprop_values);
+    if (result < 0 ||
+       ((!auxprop_values[0].name || !auxprop_values[0].values) &&
+       (!auxprop_values[1].name || !auxprop_values[1].values))) {
+       /* We didn't find this username */
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "no secret in database");
+       result = sparams->transition ? SASL_TRANS : SASL_NOUSER;
+       goto FreeAllMem;
+    }
+    
+    if (auxprop_values[0].name && auxprop_values[0].values) {
+       len = strlen(auxprop_values[0].values[0]);
+       if (len == 0) {
+           sparams->utils->seterror(sparams->utils->conn,0,
+                                    "empty secret");
+           result = SASL_FAIL;
+           goto FreeAllMem;
+       }
+       
+       sec = sparams->utils->malloc(sizeof(sasl_secret_t) + len);
+       if (!sec) {
+           SETERROR(sparams->utils, "unable to allocate secret");
+           result = SASL_FAIL;
+           goto FreeAllMem;
+       }
+       
+       sec->len = len;
+       strncpy(sec->data, auxprop_values[0].values[0], len + 1); 
+       
+       /*
+        * Verifying response obtained from client
+        * 
+        * H_URP = H({ username-value,":",realm-value,":",passwd}) sec->data
+        * contains H_URP
+        */
+       
+       /* Calculate the secret from the plaintext password */
+       {
+           /*
+            * Secret = { H( { username-value, ":", realm-value, ":", passwd } ) }
+            *
+            * (used to build A1)
+            */
+           
+           DigestCalcSecret(sparams->utils, username,
+                            text->realm, sec->data, sec->len, Secret);
+           Secret[HASHLEN] = '\0';
+       }
+       
+       /* We're done with sec now. Let's get rid of it */
+       _plug_free_secret(sparams->utils, &sec);
+    } else if (auxprop_values[1].name && auxprop_values[1].values) {
+       memcpy(Secret, auxprop_values[1].values[0], HASHLEN);
+       Secret[HASHLEN] = '\0';
+    } else {
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "Have neither type of secret");
+       return SASL_FAIL;
+    } 
+    
+    /* erase the plaintext password */
+    sparams->utils->prop_erase(sparams->propctx, password_request[0]);
+
+    /* defaulting qop to "auth" if not specified */
+    if (qop == NULL) {
+       _plug_strdup(sparams->utils, "auth", &qop, NULL);      
+    }
+    
+    /* check which layer/cipher to use */
+    if ((!strcasecmp(qop, "auth-conf")) && (cipher != NULL)) {
+       /* see what cipher was requested */
+       struct digest_cipher *cptr;
+       
+       cptr = available_ciphers;
+       while (cptr->name) {
+           /* find the cipher requested & make sure it's one we're happy
+              with by policy */
+           if (!strcasecmp(cipher, cptr->name) && 
+               stext->requiressf <= cptr->ssf &&
+               stext->limitssf >= cptr->ssf) {
+               /* found it! */
+               break;
+           }
+           cptr++;
+       }
+       
+       if (cptr->name) {
+           text->cipher_enc = cptr->cipher_enc;
+           text->cipher_dec = cptr->cipher_dec;
+           text->cipher_init = cptr->cipher_init;
+           text->cipher_free = cptr->cipher_free;
+           oparams->mech_ssf = cptr->ssf;
+           n = cptr->n;
+       } else {
+           /* erg? client requested something we didn't advertise! */
+           sparams->utils->log(sparams->utils->conn, SASL_LOG_WARN,
+                               "protocol violation: client requested invalid cipher");
+           SETERROR(sparams->utils, "client requested invalid cipher");
+           /* Mark that we attempted security layer negotiation */
+           oparams->mech_ssf = 2;
+           result = SASL_FAIL;
+           goto FreeAllMem;
+       }
+       
+       oparams->encode=&digestmd5_encode;
+       oparams->decode=&digestmd5_decode;
+    } else if (!strcasecmp(qop, "auth-int") &&
+              stext->requiressf <= 1 && stext->limitssf >= 1) {
+       oparams->encode = &digestmd5_encode;
+       oparams->decode = &digestmd5_decode;
+       oparams->mech_ssf = 1;
+    } else if (!strcasecmp(qop, "auth") && stext->requiressf == 0) {
+       oparams->encode = NULL;
+       oparams->decode = NULL;
+       oparams->mech_ssf = 0;
+    } else {
+       SETERROR(sparams->utils,
+                "protocol violation: client requested invalid qop");
+       result = SASL_FAIL;
+       goto FreeAllMem;
+    }
+    
+    serverresponse = create_response(text,
+                                    sparams->utils,
+                                    text->nonce,
+                                    text->nonce_count,
+                                    cnonce,
+                                    qop,
+                                    digesturi,
+                                    Secret,
+                                    authorization_id,
+                                    &text->response_value);
+    
+    if (serverresponse == NULL) {
+       SETERROR(sparams->utils, "internal error: unable to create response");
+       result = SASL_NOMEM;
+       goto FreeAllMem;
+    }
+    
+    /* if ok verified */
+    if (strcmp(serverresponse, response) != 0) {
+       SETERROR(sparams->utils,
+                "client response doesn't match what we generated");
+       result = SASL_BADAUTH;
+       
+       goto FreeAllMem;
+    }
+
+    /* see if our nonce expired */
+    if (text->reauth->timeout &&
+       time(0) - stext->timestamp > text->reauth->timeout) {
+       SETERROR(sparams->utils, "server nonce expired");
+       stext->stale = 1;
+       result = SASL_BADAUTH;
+
+       goto FreeAllMem;
+     }
+
+    /*
+     * nothing more to do; authenticated set oparams information
+     */
+    oparams->doneflag = 1;
+    oparams->maxoutbuf = client_maxbuf - 4;
+    if (oparams->mech_ssf > 1) {
+       /* MAC block (privacy) */
+       oparams->maxoutbuf -= 25;
+    } else if(oparams->mech_ssf == 1) {
+       /* MAC block (integrity) */
+       oparams->maxoutbuf -= 16;
+    }
+    
+    oparams->param_version = 0;
+    
+    text->seqnum = 0;          /* for integrity/privacy */
+    text->rec_seqnum = 0;      /* for integrity/privacy */
+    text->utils = sparams->utils;
+
+    /* used by layers */
+    _plug_decode_init(&text->decode_context, text->utils,
+                     sparams->props.maxbufsize ? sparams->props.maxbufsize :
+                     DEFAULT_BUFSIZE);
+
+    if (oparams->mech_ssf > 0) {
+       char enckey[16];
+       char deckey[16];
+       
+       create_layer_keys(text, sparams->utils,text->HA1,n,enckey,deckey);
+       
+       /* initialize cipher if need be */
+       if (text->cipher_init)
+           if (text->cipher_init(text, enckey, deckey) != SASL_OK) {
+               sparams->utils->seterror(sparams->utils->conn, 0,
+                                        "couldn't init cipher");
+           }
+    }
+    
+    /*
+     * The server receives and validates the "digest-response". The server
+     * checks that the nonce-count is "00000001". If it supports subsequent
+     * authentication, it saves the value of the nonce and the nonce-count.
+     */
+    
+    /*
+     * The "username-value", "realm-value" and "passwd" are encoded according
+     * to the value of the "charset" directive. If "charset=UTF-8" is
+     * present, and all the characters of either "username-value" or "passwd"
+     * are in the ISO 8859-1 character set, then it must be converted to
+     * UTF-8 before being hashed. A sample implementation of this conversion
+     * is in section 8.
+     */
+    
+    /* add to challenge */
+    {
+       unsigned resplen =
+           strlen(text->response_value) + strlen("rspauth") + 3;
+       
+       result = _plug_buf_alloc(sparams->utils, &(text->out_buf),
+                                &(text->out_buf_len), resplen);
+       if(result != SASL_OK) {
+           goto FreeAllMem;
+       }
+       
+       sprintf(text->out_buf, "rspauth=%s", text->response_value);
+       
+       /* self check */
+       if (strlen(text->out_buf) > 2048) {
+           result = SASL_FAIL;
+           goto FreeAllMem;
+       }
+    }
+    
+    *serveroutlen = strlen(text->out_buf);
+    *serverout = text->out_buf;
+       
+    result = SASL_OK;
+
+  FreeAllMem:
+    if (text->reauth->timeout &&
+       sparams->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+       unsigned val = hash(username) % text->reauth->size;
+
+       switch (result) {
+       case SASL_OK:
+           /* successful auth, setup for future reauth */
+           if (text->nonce_count == 1) {
+               /* successful initial auth, create new entry */
+               clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils);
+               text->reauth->e[val].authid = username; username = NULL;
+               text->reauth->e[val].realm = text->realm; text->realm = NULL;
+               text->reauth->e[val].nonce = text->nonce; text->nonce = NULL;
+               text->reauth->e[val].cnonce = cnonce; cnonce = NULL;
+           }
+           if (text->nonce_count <= text->reauth->e[val].nonce_count) {
+               /* paranoia.  prevent replay attacks */
+               clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils);
+           }
+           else {
+               text->reauth->e[val].nonce_count = text->nonce_count;
+               text->reauth->e[val].u.s.timestamp = time(0);
+           }
+           break;
+       default:
+           if (text->nonce_count > 1) {
+               /* failed reauth, clear entry */
+               clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils);
+           }
+           else {
+               /* failed initial auth, leave existing cache */
+           }
+       }
+       sparams->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+    }
+
+    /* free everything */
+    if (in_start) sparams->utils->free (in_start);
+    
+    if (username != NULL)
+       sparams->utils->free (username);
+    if (authorization_id != NULL)
+       sparams->utils->free (authorization_id);
+    if (realm != NULL)
+       sparams->utils->free (realm);
+    if (nonce != NULL)
+       sparams->utils->free (nonce);
+    if (cnonce != NULL)
+       sparams->utils->free (cnonce);
+    if (response != NULL)
+       sparams->utils->free (response);
+    if (cipher != NULL)
+       sparams->utils->free (cipher);
+    if (serverresponse != NULL)
+       sparams->utils->free(serverresponse);
+    if (charset != NULL)
+       sparams->utils->free (charset);
+    if (digesturi != NULL)
+       sparams->utils->free (digesturi);
+    if (qop!=NULL)
+       sparams->utils->free (qop);  
+    if (sec)
+       _plug_free_secret(sparams->utils, &sec);
+    
+    return result;
+}
+
+static int digestmd5_server_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)
+{
+    context_t *text = (context_t *) conn_context;
+    server_context_t *stext = (server_context_t *) conn_context;
+    
+    if (clientinlen > 4096) return SASL_BADPROT;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    switch (text->state) {
+       
+    case 1:
+       /* setup SSF limits */
+       if (!sparams->props.maxbufsize) {
+           stext->limitssf = 0;
+           stext->requiressf = 0;
+       } else {
+           if (sparams->props.max_ssf < sparams->external_ssf) {
+               stext->limitssf = 0;
+           } else {
+               stext->limitssf =
+                   sparams->props.max_ssf - sparams->external_ssf;
+           }
+           if (sparams->props.min_ssf < sparams->external_ssf) {
+               stext->requiressf = 0;
+           } else {
+               stext->requiressf =
+                   sparams->props.min_ssf - sparams->external_ssf;
+           }
+       }
+
+        if (clientin && text->reauth->timeout) {
+           /* here's where we attempt fast reauth if possible */
+           if (digestmd5_server_mech_step2(stext, sparams,
+                                           clientin, clientinlen,
+                                           serverout, serveroutlen,
+                                           oparams) == SASL_OK) {
+               return SASL_OK;
+           }
+
+           sparams->utils->log(NULL, SASL_LOG_WARN,
+                               "DIGEST-MD5 reauth failed\n");
+
+           /* re-initialize everything for a fresh start */
+           memset(oparams, 0, sizeof(sasl_out_params_t));
+
+           /* fall through and issue challenge */
+       }
+
+       return digestmd5_server_mech_step1(stext, sparams,
+                                          clientin, clientinlen,
+                                          serverout, serveroutlen, oparams);
+       
+    case 2:
+       return digestmd5_server_mech_step2(stext, sparams,
+                                          clientin, clientinlen,
+                                          serverout, serveroutlen, oparams);
+       
+    default:
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "Invalid DIGEST-MD5 server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void digestmd5_server_mech_dispose(void *conn_context,
+                                         const sasl_utils_t *utils)
+{
+    server_context_t *stext = (server_context_t *) conn_context;
+    
+    if (!stext || !utils) return;
+    
+    digestmd5_common_mech_dispose(conn_context, utils);
+}
+
+static sasl_server_plug_t digestmd5_server_plugins[] =
+{
+    {
+       "DIGEST-MD5",                   /* mech_name */
+#ifdef WITH_RC4
+       128,                            /* max_ssf */
+#elif WITH_DES
+       112,
+#else 
+       1,
+#endif
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_ALLOWS_PROXY,         /* features */
+       &server_glob_context,           /* glob_context */
+       &digestmd5_server_mech_new,     /* mech_new */
+       &digestmd5_server_mech_step,    /* mech_step */
+       &digestmd5_server_mech_dispose, /* mech_dispose */
+       &digestmd5_common_mech_free,    /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech avail */
+       NULL                            /* spare */
+    }
+};
+
+int digestmd5_server_plug_init(sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_server_plug_t **pluglist,
+                              int *plugcount) 
+{
+    reauth_cache_t *reauth_cache;
+    const char *timeout = NULL;
+    unsigned int len;
+
+    if (maxversion < SASL_SERVER_PLUG_VERSION)
+       return SASL_BADVERS;
+
+    /* reauth cache */
+    reauth_cache = utils->malloc(sizeof(reauth_cache_t));
+    if (reauth_cache == NULL)
+       return SASL_NOMEM;
+    memset(reauth_cache, 0, sizeof(reauth_cache_t));
+    reauth_cache->i_am = SERVER;
+
+    /* fetch and canonify the reauth_timeout */
+    utils->getopt(utils->getopt_context, "DIGEST-MD5", "reauth_timeout",
+                 &timeout, &len);
+    if (timeout)
+       reauth_cache->timeout = (time_t) 60 * strtol(timeout, NULL, 10);
+    if (reauth_cache->timeout < 0)
+       reauth_cache->timeout = 0;
+
+    if (reauth_cache->timeout) {
+       /* mutex */
+       reauth_cache->mutex = utils->mutex_alloc();
+       if (!reauth_cache->mutex)
+           return SASL_FAIL;
+
+       /* entries */
+       reauth_cache->size = 100;
+       reauth_cache->e = utils->malloc(reauth_cache->size *
+                                       sizeof(reauth_entry_t));
+       if (reauth_cache->e == NULL)
+           return SASL_NOMEM;
+       memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t));
+    }
+
+    ((digest_glob_context_t *) digestmd5_server_plugins[0].glob_context)->reauth = reauth_cache;
+
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = digestmd5_server_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    context_t common;
+
+    sasl_secret_t *password;   /* user password */
+    unsigned int free_password; /* set if we need to free password */
+
+    int protection;
+    struct digest_cipher *cipher;
+    unsigned long server_maxbuf;
+} client_context_t;
+
+static digest_glob_context_t client_glob_context;
+
+/* calculate H(A1) as per spec */
+static void DigestCalcHA1(context_t * text,
+                         const sasl_utils_t * utils,
+                         unsigned char *pszUserName,
+                         unsigned char *pszRealm,
+                         sasl_secret_t * pszPassword,
+                         unsigned char *pszAuthorization_id,
+                         unsigned char *pszNonce,
+                         unsigned char *pszCNonce,
+                         HASHHEX SessionKey)
+{
+    MD5_CTX         Md5Ctx;
+    HASH            HA1;
+    
+    DigestCalcSecret(utils,
+                    pszUserName,
+                    pszRealm,
+                    (unsigned char *) pszPassword->data,
+                    pszPassword->len,
+                    HA1);
+    
+    /* calculate the session key */
+    utils->MD5Init(&Md5Ctx);
+    utils->MD5Update(&Md5Ctx, HA1, HASHLEN);
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    utils->MD5Update(&Md5Ctx, pszNonce, strlen((char *) pszNonce));
+    utils->MD5Update(&Md5Ctx, COLON, 1);
+    utils->MD5Update(&Md5Ctx, pszCNonce, strlen((char *) pszCNonce));
+    if (pszAuthorization_id != NULL) {
+       utils->MD5Update(&Md5Ctx, COLON, 1);
+       utils->MD5Update(&Md5Ctx, pszAuthorization_id, 
+                        strlen((char *) pszAuthorization_id));
+    }
+    utils->MD5Final(HA1, &Md5Ctx);
+    
+    CvtHex(HA1, SessionKey);
+    
+    /* xxx rc-* use different n */
+    
+    /* save HA1 because we'll need it for the privacy and integrity keys */
+    memcpy(text->HA1, HA1, sizeof(HASH));
+    
+}
+
+static char *calculate_response(context_t * text,
+                               const sasl_utils_t * utils,
+                               unsigned char *username,
+                               unsigned char *realm,
+                               unsigned char *nonce,
+                               unsigned int ncvalue,
+                               unsigned char *cnonce,
+                               char *qop,
+                               unsigned char *digesturi,
+                               sasl_secret_t * passwd,
+                               unsigned char *authorization_id,
+                               char **response_value)
+{
+    HASHHEX         SessionKey;
+    HASHHEX         HEntity = "00000000000000000000000000000000";
+    HASHHEX         Response;
+    char           *result;
+    
+    /* Verifing that all parameters was defined */
+    if(!username || !cnonce || !nonce || !ncvalue || !digesturi || !passwd) {
+       PARAMERROR( utils );
+       return NULL;
+    }
+    
+    if (realm == NULL) {
+       /* a NULL realm is equivalent to the empty string */
+       realm = (unsigned char *) "";
+    }
+    
+    if (qop == NULL) {
+       /* default to a qop of just authentication */
+       qop = "auth";
+    }
+    
+    DigestCalcHA1(text,
+                 utils,
+                 username,
+                 realm,
+                 passwd,
+                 authorization_id,
+                 nonce,
+                 cnonce,
+                 SessionKey);
+    
+    DigestCalcResponse(utils,
+                      SessionKey,/* HEX(H(A1)) */
+                      nonce,   /* nonce from server */
+                      ncvalue, /* 8 hex digits */
+                      cnonce,  /* client nonce */
+                      (unsigned char *) qop,   /* qop-value: "", "auth",
+                                                * "auth-int" */
+                      digesturi,       /* requested URL */
+                      (unsigned char *) "AUTHENTICATE",
+                      HEntity, /* H(entity body) if qop="auth-int" */
+                      Response /* request-digest or response-digest */
+       );
+    
+    result = utils->malloc(HASHHEXLEN + 1);
+    memcpy(result, Response, HASHHEXLEN);
+    result[HASHHEXLEN] = 0;
+    
+    if (response_value != NULL) {
+       DigestCalcResponse(utils,
+                          SessionKey,  /* HEX(H(A1)) */
+                          nonce,       /* nonce from server */
+                          ncvalue,     /* 8 hex digits */
+                          cnonce,      /* client nonce */
+                          (unsigned char *) qop,       /* qop-value: "", "auth",
+                                                        * "auth-int" */
+                          (unsigned char *) digesturi, /* requested URL */
+                          NULL,
+                          HEntity,     /* H(entity body) if qop="auth-int" */
+                          Response     /* request-digest or response-digest */
+           );
+       
+       *response_value = utils->malloc(HASHHEXLEN + 1);
+       if (*response_value == NULL)
+           return NULL;
+       
+       memcpy(*response_value, Response, HASHHEXLEN);
+       (*response_value)[HASHHEXLEN] = 0;
+       
+    }
+    
+    return result;
+}
+
+static int make_client_response(context_t *text,
+                               sasl_client_params_t *params,
+                               sasl_out_params_t *oparams)
+{
+    client_context_t *ctext = (client_context_t *) text;
+    char *qop = NULL;
+    unsigned nbits = 0;
+    unsigned char  *digesturi = NULL;
+    bool            IsUTF8 = FALSE;
+    char           ncvalue[10];
+    char           maxbufstr[64];
+    char           *response = NULL;
+    unsigned        resplen = 0;
+    int result = SASL_OK;
+
+    switch (ctext->protection) {
+    case DIGEST_PRIVACY:
+       qop = "auth-conf";
+       oparams->encode = &digestmd5_encode; 
+       oparams->decode = &digestmd5_decode;
+       oparams->mech_ssf = ctext->cipher->ssf;
+
+       nbits = ctext->cipher->n;
+       text->cipher_enc = ctext->cipher->cipher_enc;
+       text->cipher_dec = ctext->cipher->cipher_dec;
+       text->cipher_free = ctext->cipher->cipher_free;
+       text->cipher_init = ctext->cipher->cipher_init;
+       break;
+    case DIGEST_INTEGRITY:
+       qop = "auth-int";
+       oparams->encode = &digestmd5_encode;
+       oparams->decode = &digestmd5_decode;
+       oparams->mech_ssf = 1;
+       break;
+    case DIGEST_NOLAYER:
+    default:
+       qop = "auth";
+       oparams->encode = NULL;
+       oparams->decode = NULL;
+       oparams->mech_ssf = 0;
+    }
+
+    digesturi = params->utils->malloc(strlen(params->service) + 1 +
+                                     strlen(params->serverFQDN) + 1 +
+                                     1);
+    if (digesturi == NULL) {
+       result = SASL_NOMEM;
+       goto FreeAllocatedMem;
+    };
+    
+    /* allocated exactly this. safe */
+    strcpy((char *) digesturi, params->service);
+    strcat((char *) digesturi, "/");
+    strcat((char *) digesturi, params->serverFQDN);
+    /*
+     * strcat (digesturi, "/"); strcat (digesturi, params->serverFQDN);
+     */
+
+    /* response */
+    response =
+       calculate_response(text,
+                          params->utils,
+                          (char *) oparams->authid,
+                          (unsigned char *) text->realm,
+                          text->nonce,
+                          text->nonce_count,
+                          text->cnonce,
+                          qop,
+                          digesturi,
+                          ctext->password,
+                          strcmp(oparams->user, oparams->authid) ?
+                          (char *) oparams->user : NULL,
+                          &text->response_value);
+    
+    
+    resplen = 0;
+    text->out_buf = NULL;
+    text->out_buf_len = 0;
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "username", (unsigned char *) oparams->authid,
+                        TRUE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "realm", (unsigned char *) text->realm,
+                        TRUE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    if (strcmp(oparams->user, oparams->authid)) {
+       if (add_to_challenge(params->utils,
+                            &text->out_buf, &text->out_buf_len, &resplen,
+                            "authzid", (char *) oparams->user, TRUE) != SASL_OK) {
+           result = SASL_FAIL;
+           goto FreeAllocatedMem;
+       }
+    }
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "nonce", text->nonce, TRUE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "cnonce", text->cnonce, TRUE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    snprintf(ncvalue, sizeof(ncvalue), "%08x", text->nonce_count);
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "nc", (unsigned char *) ncvalue, FALSE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "qop", (unsigned char *) qop, FALSE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    if (ctext->cipher != NULL) {
+       if (add_to_challenge(params->utils,
+                            &text->out_buf, &text->out_buf_len, &resplen,
+                            "cipher", 
+                            (unsigned char *) ctext->cipher->name,
+                            FALSE) != SASL_OK) {
+           result = SASL_FAIL;
+           goto FreeAllocatedMem;
+       }
+    }
+
+    if (params->props.maxbufsize) {
+       snprintf(maxbufstr, sizeof(maxbufstr), "%d", params->props.maxbufsize);
+       if (add_to_challenge(params->utils,
+                            &text->out_buf, &text->out_buf_len, &resplen,
+                            "maxbuf", (unsigned char *) maxbufstr, 
+                            FALSE) != SASL_OK) {
+           SETERROR(params->utils,
+                    "internal error: add_to_challenge maxbuf failed");
+           goto FreeAllocatedMem;
+       }
+    }
+    
+    if (IsUTF8) {
+       if (add_to_challenge(params->utils,
+                            &text->out_buf, &text->out_buf_len, &resplen,
+                            "charset", (unsigned char *) "utf-8",
+                            FALSE) != SASL_OK) {
+           result = SASL_FAIL;
+           goto FreeAllocatedMem;
+       }
+    }
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "digest-uri", digesturi, TRUE) != SASL_OK) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    if (add_to_challenge(params->utils,
+                        &text->out_buf, &text->out_buf_len, &resplen,
+                        "response", (unsigned char *) response,
+                        FALSE) != SASL_OK) {
+       
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+    
+    /* self check */
+    if (strlen(text->out_buf) > 2048) {
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+
+    /* set oparams */
+    oparams->maxoutbuf = ctext->server_maxbuf;
+    if(oparams->mech_ssf > 1) {
+       /* MAC block (privacy) */
+       oparams->maxoutbuf -= 25;
+    } else if(oparams->mech_ssf == 1) {
+       /* MAC block (integrity) */
+       oparams->maxoutbuf -= 16;
+    }
+    
+    text->seqnum = 0;  /* for integrity/privacy */
+    text->rec_seqnum = 0;      /* for integrity/privacy */
+    text->utils = params->utils;
+
+    /* used by layers */
+    _plug_decode_init(&text->decode_context, text->utils,
+                     params->props.maxbufsize ? params->props.maxbufsize :
+                     DEFAULT_BUFSIZE);
+    
+    if (oparams->mech_ssf > 0) {
+       char enckey[16];
+       char deckey[16];
+       
+       create_layer_keys(text, params->utils, text->HA1, nbits,
+                         enckey, deckey);
+       
+       /* initialize cipher if need be */
+       if (text->cipher_init)
+           text->cipher_init(text, enckey, deckey);                   
+    }
+    
+    result = SASL_OK;
+
+  FreeAllocatedMem:
+    if (digesturi) params->utils->free(digesturi);
+    if (response) params->utils->free(response);
+
+    return result;
+}
+
+static int parse_server_challenge(client_context_t *ctext,
+                                 sasl_client_params_t *params,
+                                 const char *serverin, unsigned serverinlen,
+                                 char ***outrealms, int *noutrealm)
+{
+    context_t *text = (context_t *) ctext;
+    int result = SASL_OK;
+    char *in_start = NULL;
+    char *in = NULL;
+    char **realms = NULL;
+    int nrealm = 0;
+    sasl_ssf_t limit, musthave = 0;
+    sasl_ssf_t external;
+    int protection = 0;
+    int ciphers = 0;
+    int maxbuf_count = 0;
+    bool IsUTF8 = FALSE;
+    int algorithm_count = 0;
+
+    if (!serverin || !serverinlen) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "no server challenge");
+       return SASL_FAIL;
+    }
+
+    in_start = in = params->utils->malloc(serverinlen + 1);
+    if (in == NULL) return SASL_NOMEM;
+    
+    memcpy(in, serverin, serverinlen);
+    in[serverinlen] = 0;
+    
+    ctext->server_maxbuf = 65536; /* Default value for maxbuf */
+
+    /* create a new cnonce */
+    text->cnonce = create_nonce(params->utils);
+    if (text->cnonce == NULL) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "failed to create cnonce");
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+
+    /* parse the challenge */
+    while (in[0] != '\0') {
+       char *name, *value;
+       
+       get_pair(&in, &name, &value);
+       
+       /* if parse error */
+       if (name == NULL) {
+           params->utils->seterror(params->utils->conn, 0, "Parse error");
+           result = SASL_FAIL;
+           goto FreeAllocatedMem;
+       }
+       
+       if (strcasecmp(name, "realm") == 0) {
+           nrealm++;
+           
+           if(!realms)
+               realms = params->utils->malloc(sizeof(char *) * (nrealm + 1));
+           else
+               realms = params->utils->realloc(realms, 
+                                               sizeof(char *) * (nrealm + 1));
+           
+           if (realms == NULL) {
+               result = SASL_NOMEM;
+               goto FreeAllocatedMem;
+           }
+           
+           _plug_strdup(params->utils, value, &realms[nrealm-1], NULL);
+           realms[nrealm] = NULL;
+       } else if (strcasecmp(name, "nonce") == 0) {
+           _plug_strdup(params->utils, value, (char **) &text->nonce,
+                        NULL);
+           text->nonce_count = 1;
+       } else if (strcasecmp(name, "qop") == 0) {
+           while (value && *value) {
+               char *comma;
+               char *end_val;
+
+SKIP_SPACES_IN_QOP:
+               /* skipping spaces: */
+               value = skip_lws(value);
+               if (*value == '\0') {
+                   break;
+               }
+
+               /* check for an extreme case when there is no data: LWSP ',' */
+               if (*value == ',') {
+                   value++;
+                   goto SKIP_SPACES_IN_QOP;
+               }
+
+               comma = strchr(value, ',');
+
+               if (comma != NULL) {
+                   *comma++ = '\0';
+               }
+
+               /* skip LWSP at the end of the value (if any), skip_r_lws returns pointer to
+                  the first LWSP character, NUL (if there were none) or NULL if the value
+                  is entirely from LWSP characters */
+               end_val = skip_r_lws (value);
+               if (end_val == NULL) {
+                   value = comma;
+                   continue;
+               } else {
+                   /* strip LWSP */
+                   *end_val = '\0';
+               }
+
+               if (strcasecmp(value, "auth-conf") == 0) {
+                   protection |= DIGEST_PRIVACY;
+               } else if (strcasecmp(value, "auth-int") == 0) {
+                   protection |= DIGEST_INTEGRITY;
+               } else if (strcasecmp(value, "auth") == 0) {
+                   protection |= DIGEST_NOLAYER;
+               } else {
+                   params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                                      "Server supports unknown layer: %s\n",
+                                      value);
+               }
+               
+               value = comma;
+           }
+           
+           if (protection == 0) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "Server doesn't support any known qop level");
+               goto FreeAllocatedMem;
+           }
+       } else if (strcasecmp(name, "cipher") == 0) {
+           while (value && *value) {
+               struct digest_cipher *cipher = available_ciphers;
+               char *comma;
+               char *end_val;
+
+SKIP_SPACES_IN_CIPHER:
+               /* skipping spaces: */
+               value = skip_lws(value);
+               if (*value == '\0') {
+                   break;
+               }
+
+               /* check for an extreme case when there is no data: LWSP ',' */
+               if (*value == ',') {
+                   value++;
+                   goto SKIP_SPACES_IN_CIPHER;
+               }
+
+               comma = strchr(value, ',');
+
+               if (comma != NULL) {
+                   *comma++ = '\0';
+               }
+
+               /* skip LWSP at the end of the value, skip_r_lws returns pointer to
+                  the first LWSP character or NULL */
+               end_val = skip_r_lws (value);
+               if (end_val == NULL) {
+                   value = comma;
+                   continue;
+               } else {
+                   /* strip LWSP */
+                   *end_val = '\0';
+               }
+
+               /* do we support this cipher? */
+               while (cipher->name) {
+                   if (!strcasecmp(value, cipher->name)) break;
+                   cipher++;
+               }
+               if (cipher->name) {
+                   ciphers |= cipher->flag;
+               } else {
+                   params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                                      "Server supports unknown cipher: %s\n",
+                                      value);
+               }
+               
+               value = comma;
+           }
+       } else if (strcasecmp(name, "stale") == 0 && ctext->password) {
+           /* clear any cached password */
+           if (ctext->free_password)
+               _plug_free_secret(params->utils, &ctext->password);
+           ctext->password = NULL;
+       } else if (strcasecmp(name, "maxbuf") == 0) {
+           /* maxbuf A number indicating the size of the largest
+            * buffer the server is able to receive when using
+            * "auth-int". If this directive is missing, the default
+            * value is 65536. This directive may appear at most once;
+            * if multiple instances are present, the client should
+            * abort the authentication exchange.  
+            */
+           maxbuf_count++;
+           
+           if (maxbuf_count != 1) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "At least two maxbuf directives found. Authentication aborted");
+               goto FreeAllocatedMem;
+           } 
+
+           if (str2ul32 (value, &ctext->server_maxbuf) == FALSE) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "Invalid maxbuf parameter received from server (%s)", value);
+               goto FreeAllocatedMem;
+           }
+           
+           if (ctext->server_maxbuf <= 16) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "Invalid maxbuf parameter received from server (too small: %s)", value);
+               goto FreeAllocatedMem;
+           }
+
+           if (ctext->server_maxbuf > MAX_SASL_BUFSIZE) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "Invalid maxbuf parameter received from server (too big: %s)", value);
+               goto FreeAllocatedMem;
+           }
+       } else if (strcasecmp(name, "charset") == 0) {
+           if (strcasecmp(value, "utf-8") != 0) {
+               result = SASL_BADAUTH;
+               params->utils->seterror(params->utils->conn, 0,
+                                       "Charset must be UTF-8");
+               goto FreeAllocatedMem;
+           } else {
+               IsUTF8 = TRUE;
+           }
+       } else if (strcasecmp(name,"algorithm")==0) {
+           if (strcasecmp(value, "md5-sess") != 0)
+               {
+                   params->utils->seterror(params->utils->conn, 0,
+                                           "'algorithm' isn't 'md5-sess'");
+                   result = SASL_FAIL;
+                   goto FreeAllocatedMem;
+               }
+           
+           algorithm_count++;
+           if (algorithm_count > 1)
+               {
+                   params->utils->seterror(params->utils->conn, 0,
+                                           "Must see 'algorithm' only once");
+                   result = SASL_FAIL;
+                   goto FreeAllocatedMem;
+               }
+       } else {
+           params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                              "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
+                              name, value);
+       }
+    }
+    
+    if (algorithm_count != 1) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Must see 'algorithm' once. Didn't see at all");
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+
+    /* make sure we have everything we require */
+    if (text->nonce == NULL) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Don't have nonce.");
+       result = SASL_FAIL;
+       goto FreeAllocatedMem;
+    }
+
+    /* get requested ssf */
+    external = params->external_ssf;
+    
+    /* what do we _need_?  how much is too much? */
+    if (params->props.maxbufsize == 0) {
+       musthave = 0;
+       limit = 0;
+    } else {
+       if (params->props.max_ssf > external) {
+           limit = params->props.max_ssf - external;
+       } else {
+           limit = 0;
+       }
+       if (params->props.min_ssf > external) {
+           musthave = params->props.min_ssf - external;
+       } else {
+           musthave = 0;
+       }
+    }
+    
+    /* we now go searching for an option that gives us at least "musthave"
+       and at most "limit" bits of ssf. */
+    if ((limit > 1) && (protection & DIGEST_PRIVACY)) {
+       struct digest_cipher *cipher;
+       
+       /* let's find an encryption scheme that we like */
+       cipher = available_ciphers;
+       while (cipher->name) {
+           /* examine each cipher we support, see if it meets our security
+              requirements, and see if the server supports it.
+              choose the best one of these */
+           if ((limit >= cipher->ssf) && (musthave <= cipher->ssf) &&
+               (ciphers & cipher->flag) &&
+               (!ctext->cipher || (cipher->ssf > ctext->cipher->ssf))) {
+               ctext->cipher = cipher;
+           }
+           cipher++;
+       }
+       
+       if (ctext->cipher) {
+           /* we found a cipher we like */
+           ctext->protection = DIGEST_PRIVACY;
+       } else {
+           /* we didn't find any ciphers we like */
+           params->utils->seterror(params->utils->conn, 0,
+                                   "No good privacy layers");
+       }
+    }
+    
+    if (ctext->cipher == NULL) {
+       /* we failed to find an encryption layer we liked;
+          can we use integrity or nothing? */
+       
+       if ((limit >= 1) && (musthave <= 1) 
+           && (protection & DIGEST_INTEGRITY)) {
+           /* integrity */
+           ctext->protection = DIGEST_INTEGRITY;
+       } else if (musthave <= 0) {
+           /* no layer */
+           ctext->protection = DIGEST_NOLAYER;
+
+           /* See if server supports not having a layer */
+           if ((protection & DIGEST_NOLAYER) != DIGEST_NOLAYER) {
+               params->utils->seterror(params->utils->conn, 0, 
+                                       "Server doesn't support \"no layer\"");
+               result = SASL_FAIL;
+               goto FreeAllocatedMem;
+           }
+       } else {
+           params->utils->seterror(params->utils->conn, 0,
+                                   "Can't find an acceptable layer");
+           result = SASL_TOOWEAK;
+           goto FreeAllocatedMem;
+       }
+    }
+
+    *outrealms = realms;
+    *noutrealm = nrealm;
+
+  FreeAllocatedMem:
+    if (in_start) params->utils->free(in_start);
+
+    if (result != SASL_OK && realms) {
+       int lup;
+       
+       /* need to free all the realms */
+       for (lup = 0;lup < nrealm; lup++)
+           params->utils->free(realms[lup]);
+       
+       params->utils->free(realms);
+    }
+
+    return result;
+}
+
+static int ask_user_info(client_context_t *ctext,
+                        sasl_client_params_t *params,
+                        char **realms, int nrealm,
+                        sasl_interact_t **prompt_need,
+                        sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) ctext;
+    int result = SASL_OK;
+    const char *authid = NULL, *userid = NULL, *realm = NULL;
+    char *realm_chal = NULL;
+    int user_result = SASL_OK;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    int realm_result = SASL_FAIL;
+    int i;
+    size_t len;
+
+    /* try to get the authid */
+    if (oparams->authid == NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) {
+           return auth_result;
+       }
+    }
+    
+    /* try to get the userid */
+    if (oparams->user == NULL) {
+       user_result = _plug_get_userid(params->utils, &userid, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) {
+           return user_result;
+       }
+    }
+    
+    /* try to get the password */
+    if (ctext->password == NULL) {
+       pass_result = _plug_get_password(params->utils, &ctext->password,
+                                        &ctext->free_password, prompt_need);
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) {
+           return pass_result;
+       }
+    }
+
+    /* try to get the realm */
+    if (text->realm == NULL) {
+       if (realms) {
+           if(nrealm == 1) {
+               /* only one choice */
+               realm = realms[0];
+               realm_result = SASL_OK;
+           } else {
+               /* ask the user */
+               realm_result = _plug_get_realm(params->utils,
+                                              (const char **) realms,
+                                              (const char **) &realm,
+                                              prompt_need);
+           }
+       }
+
+       /* fake the realm if we must */
+       if ((realm_result != SASL_OK) && (realm_result != SASL_INTERACT)) {
+           if (params->serverFQDN) {
+               realm = params->serverFQDN;
+           } else {
+               return realm_result;
+           }
+       }    
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) ||
+       (pass_result == SASL_INTERACT) || (realm_result == SASL_INTERACT)) {
+
+       /* make our default realm */
+       if (realm_result == SASL_INTERACT) {
+           if (realms) {
+               len = strlen(REALM_CHAL_PREFIX);
+               for (i = 0; i < nrealm; i++) {
+                   len += strlen(realms[i]) + 4 /* " {}," */;
+               }
+               realm_chal = params->utils->malloc(len + 1);
+               strcpy (realm_chal, REALM_CHAL_PREFIX);
+               for (i = 0; i < nrealm; i++) {
+                   strcat (realm_chal, " {");
+                   strcat (realm_chal, realms[i]);
+                   strcat (realm_chal, "},");
+               }
+               /* Replace the terminating comma with dot */
+               realm_chal[len-1] = '.';
+
+           } else if (params->serverFQDN) {
+               realm_chal = params->utils->malloc(3+strlen(params->serverFQDN));
+               if (realm_chal) {
+                   sprintf(realm_chal, "{%s}", params->serverFQDN);
+               } else {
+                   return SASL_NOMEM;
+               }
+           }
+       }
+
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              realm_chal ? realm_chal : "{}",
+                              realm_result == SASL_INTERACT ?
+                              "Please enter your realm" : NULL,
+                              params->serverFQDN ? params->serverFQDN : NULL);
+       
+       if (result == SASL_OK) return SASL_INTERACT;
+
+       return result;
+    }
+    
+    if (oparams->authid == NULL) {
+       if (!userid || !*userid) {
+           result = params->canon_user(params->utils->conn, authid, 0,
+                                       SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                                       oparams);
+       }
+       else {
+           result = params->canon_user(params->utils->conn,
+                                       authid, 0, SASL_CU_AUTHID, oparams);
+           if (result != SASL_OK) return result;
+
+           result = params->canon_user(params->utils->conn,
+                                       userid, 0, SASL_CU_AUTHZID, oparams);
+       }
+       if (result != SASL_OK) return result;
+    }
+
+    /* Get an allocated version of the realm into the structure */
+    if (realm && text->realm == NULL) {
+       _plug_strdup(params->utils, realm, (char **) &text->realm, NULL);
+    }
+
+    return result;
+}
+
+static int digestmd5_client_mech_new(void *glob_context,
+                                    sasl_client_params_t * params,
+                                    void **conn_context)
+{
+    context_t *text;
+    
+    /* holds state are in -- allocate client size */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL)
+       return SASL_NOMEM;
+    memset(text, 0, sizeof(client_context_t));
+    
+    text->state = 1;
+    text->i_am = CLIENT;
+    text->reauth = ((digest_glob_context_t *) glob_context)->reauth;
+    
+    *conn_context = text;
+
+    return SASL_OK;
+}
+
+static int
+digestmd5_client_mech_step1(client_context_t *ctext,
+                           sasl_client_params_t *params,
+                           const char *serverin __attribute__((unused)), 
+                           unsigned serverinlen __attribute__((unused)), 
+                           sasl_interact_t **prompt_need,
+                           const char **clientout,
+                           unsigned *clientoutlen,
+                           sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) ctext;
+    int result = SASL_FAIL;
+    unsigned val;
+
+    params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                      "DIGEST-MD5 client step 1");
+
+    result = ask_user_info(ctext, params, NULL, 0, prompt_need, oparams);
+    if (result != SASL_OK) return result;
+
+    /* check if we have cached info for this user on this server */
+    val = hash(params->serverFQDN) % text->reauth->size;
+    if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+       if (text->reauth->e[val].u.c.serverFQDN &&
+           !strcasecmp(text->reauth->e[val].u.c.serverFQDN,
+                       params->serverFQDN) &&
+           !strcmp(text->reauth->e[val].authid, oparams->authid)) {
+
+           /* we have info, so use it */
+           _plug_strdup(params->utils, text->reauth->e[val].realm,
+                        &text->realm, NULL);
+           _plug_strdup(params->utils, text->reauth->e[val].nonce,
+                        (char **) &text->nonce, NULL);
+           text->nonce_count = ++text->reauth->e[val].nonce_count;
+           _plug_strdup(params->utils, text->reauth->e[val].cnonce,
+                        (char **) &text->cnonce, NULL);
+           ctext->protection = text->reauth->e[val].u.c.protection;
+           ctext->cipher = text->reauth->e[val].u.c.cipher;
+           ctext->server_maxbuf = text->reauth->e[val].u.c.server_maxbuf;
+       }
+       params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+    }
+
+    if (!text->nonce) {
+       /* we don't have any reauth info, so just return
+        * that there is no initial client send */
+       text->state = 2;
+       return SASL_CONTINUE;
+    }
+
+    /*
+     * (username | realm | nonce | cnonce | nonce-count | qop digest-uri |
+     * response | maxbuf | charset | auth-param )
+     */
+    
+    result = make_client_response(text, params, oparams);
+    if (result != SASL_OK) return result;
+
+    *clientoutlen = strlen(text->out_buf);
+    *clientout = text->out_buf;
+
+    text->state = 3;
+    return SASL_CONTINUE;
+}
+
+static int digestmd5_client_mech_step2(client_context_t *ctext,
+                                      sasl_client_params_t *params,
+                                      const char *serverin,
+                                      unsigned serverinlen,
+                                      sasl_interact_t **prompt_need,
+                                      const char **clientout,
+                                      unsigned *clientoutlen,
+                                      sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) ctext;
+    int result = SASL_FAIL;
+    char **realms = NULL;
+    int nrealm = 0;
+
+    params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                      "DIGEST-MD5 client step 2");
+
+    if (params->props.min_ssf > params->props.max_ssf) {
+       return SASL_BADPARAM;
+    }
+
+    /* don't bother parsing the challenge more than once */
+    if (text->nonce == NULL) {
+       result = parse_server_challenge(ctext, params, serverin, serverinlen,
+                                       &realms, &nrealm);
+       if (result != SASL_OK) goto FreeAllocatedMem;
+    
+       if (nrealm == 1) {
+           /* only one choice! */
+           text->realm = realms[0];
+
+           /* free realms */
+           params->utils->free(realms);
+           realms = NULL;
+       } else {
+           /* Save realms for later use */
+           text->realms = realms;
+           text->realm_cnt = nrealm;
+       }
+    } else {
+       /* Restore the list of realms */
+       realms = text->realms;
+       nrealm = text->realm_cnt;
+    }
+
+    result = ask_user_info(ctext, params, realms, nrealm,
+                          prompt_need, oparams);
+    if (result != SASL_OK) goto FreeAllocatedMem;
+
+    /*
+     * (username | realm | nonce | cnonce | nonce-count | qop | digest-uri |
+     *  response | maxbuf | charset | auth-param )
+     */
+    
+    result = make_client_response(text, params, oparams);
+    if (result != SASL_OK) goto FreeAllocatedMem;
+
+    *clientoutlen = strlen(text->out_buf);
+    *clientout = text->out_buf;
+
+    text->state = 3;
+    
+    result = SASL_CONTINUE;
+    
+  FreeAllocatedMem:
+    return result;
+}
+
+static int
+digestmd5_client_mech_step3(client_context_t *ctext,
+                           sasl_client_params_t *params,
+                           const char *serverin,
+                           unsigned serverinlen,
+                           sasl_interact_t **prompt_need __attribute__((unused)),
+                           const char **clientout __attribute__((unused)),
+                           unsigned *clientoutlen __attribute__((unused)),
+                           sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) ctext;
+    char           *in = NULL;
+    char           *in_start;
+    int result = SASL_FAIL;
+    
+    params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                      "DIGEST-MD5 client step 3");
+
+    /* Verify that server is really what he claims to be */
+    in_start = in = params->utils->malloc(serverinlen + 1);
+    if (in == NULL) return SASL_NOMEM;
+
+    memcpy(in, serverin, serverinlen);
+    in[serverinlen] = 0;
+    
+    /* parse the response */
+    while (in[0] != '\0') {
+       char *name, *value;
+       get_pair(&in, &name, &value);
+       
+       if (name == NULL) {
+           params->utils->seterror(params->utils->conn, 0,
+                                   "DIGEST-MD5 Received Garbage");
+           break;
+       }
+       
+       if (strcasecmp(name, "rspauth") == 0) {
+           
+           if (strcmp(text->response_value, value) != 0) {
+               params->utils->seterror(params->utils->conn, 0,
+                                       "DIGEST-MD5: This server wants us to believe that he knows shared secret");
+               result = SASL_BADSERV;
+           } else {
+               oparams->doneflag = 1;
+               oparams->param_version = 0;
+               
+               result = SASL_OK;
+           }
+           break;
+       } else {
+           params->utils->log(params->utils->conn, SASL_LOG_DEBUG,
+                              "DIGEST-MD5 unrecognized pair %s/%s: ignoring",
+                              name, value);
+       }
+    }
+    
+    params->utils->free(in_start);
+
+    if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+       unsigned val = hash(params->serverFQDN) % text->reauth->size;
+       switch (result) {
+       case SASL_OK:
+           if (text->nonce_count == 1) {
+               /* successful initial auth, setup for future reauth */
+               clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils);
+               _plug_strdup(params->utils, oparams->authid,
+                            &text->reauth->e[val].authid, NULL);
+               text->reauth->e[val].realm = text->realm; text->realm = NULL;
+               text->reauth->e[val].nonce = text->nonce; text->nonce = NULL;
+               text->reauth->e[val].nonce_count = text->nonce_count;
+               text->reauth->e[val].cnonce = text->cnonce; text->cnonce = NULL;
+               _plug_strdup(params->utils, params->serverFQDN,
+                            &text->reauth->e[val].u.c.serverFQDN, NULL);
+               text->reauth->e[val].u.c.protection = ctext->protection;
+               text->reauth->e[val].u.c.cipher = ctext->cipher;
+               text->reauth->e[val].u.c.server_maxbuf = ctext->server_maxbuf;
+           }
+           else {
+               /* reauth, we already incremented nonce_count */
+           }
+           break;
+       default:
+           if (text->nonce_count > 1) {
+               /* failed reauth, clear cache */
+               clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils);
+           }
+           else {
+               /* failed initial auth, leave existing cache */
+           }
+       }
+       params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+    }
+
+    return result;
+}
+
+static int digestmd5_client_mech_step(void *conn_context,
+                                     sasl_client_params_t *params,
+                                     const char *serverin,
+                                     unsigned serverinlen,
+                                     sasl_interact_t **prompt_need,
+                                     const char **clientout,
+                                     unsigned *clientoutlen,
+                                     sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) conn_context;
+    client_context_t *ctext = (client_context_t *) conn_context;
+    unsigned val = hash(params->serverFQDN) % text->reauth->size;
+    
+    if (serverinlen > 2048) return SASL_BADPROT;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+
+    switch (text->state) {
+
+    case 1:
+       if (!serverin) {
+           /* here's where we attempt fast reauth if possible */
+           int reauth = 0;
+
+           /* check if we have saved info for this server */
+           if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+               reauth = text->reauth->e[val].u.c.serverFQDN &&
+                   !strcasecmp(text->reauth->e[val].u.c.serverFQDN,
+                               params->serverFQDN);
+               params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+           }
+           if (reauth) {
+               return digestmd5_client_mech_step1(ctext, params,
+                                                  serverin, serverinlen,
+                                                  prompt_need,
+                                                  clientout, clientoutlen,
+                                                  oparams);
+           }
+           else {
+               /* we don't have any reauth info, so just return
+                * that there is no initial client send */
+               text->state = 2;
+               return SASL_CONTINUE;
+           }
+       }
+       
+       /* fall through and respond to challenge */
+       
+    case 3:
+       if (serverin && !strncasecmp(serverin, "rspauth=", 8)) {
+           return digestmd5_client_mech_step3(ctext, params,
+                                              serverin, serverinlen,
+                                              prompt_need,
+                                              clientout, clientoutlen,
+                                              oparams);
+       }
+
+       /* fall through and respond to challenge */
+       text->state = 2;
+
+       /* cleanup after a failed reauth attempt */
+       if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */
+           clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils);
+
+           params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */
+       }
+
+       if (text->realm) params->utils->free(text->realm);
+       if (text->nonce) params->utils->free(text->nonce);
+       if (text->cnonce) params->utils->free(text->cnonce);
+       text->realm = text->nonce = text->cnonce = NULL;
+       ctext->cipher = NULL;
+    
+    case 2:
+       return digestmd5_client_mech_step2(ctext, params,
+                                          serverin, serverinlen,
+                                          prompt_need,
+                                          clientout, clientoutlen,
+                                          oparams);
+
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid DIGEST-MD5 client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void digestmd5_client_mech_dispose(void *conn_context,
+                                         const sasl_utils_t *utils)
+{
+    client_context_t *ctext = (client_context_t *) conn_context;
+    
+    if (!ctext || !utils) return;
+    
+    if (ctext->free_password) _plug_free_secret(utils, &ctext->password);
+
+    digestmd5_common_mech_dispose(conn_context, utils);
+}
+
+static sasl_client_plug_t digestmd5_client_plugins[] =
+{
+    {
+       "DIGEST-MD5",
+#ifdef WITH_RC4                                /* mech_name */
+       128,                            /* max ssf */
+#elif WITH_DES
+       112,
+#else
+       1,
+#endif
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_NEEDSERVERFQDN
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* required_prompts */
+       &client_glob_context,           /* glob_context */
+       &digestmd5_client_mech_new,     /* mech_new */
+       &digestmd5_client_mech_step,    /* mech_step */
+       &digestmd5_client_mech_dispose, /* mech_dispose */
+       &digestmd5_common_mech_free,    /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare1 */
+       NULL                            /* spare2 */
+    }
+};
+
+int digestmd5_client_plug_init(sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_client_plug_t **pluglist,
+                              int *plugcount)
+{
+    reauth_cache_t *reauth_cache;
+
+    if (maxversion < SASL_CLIENT_PLUG_VERSION)
+       return SASL_BADVERS;
+    
+    /* reauth cache */
+    reauth_cache = utils->malloc(sizeof(reauth_cache_t));
+    if (reauth_cache == NULL)
+       return SASL_NOMEM;
+    memset(reauth_cache, 0, sizeof(reauth_cache_t));
+    reauth_cache->i_am = CLIENT;
+    
+    /* mutex */
+    reauth_cache->mutex = utils->mutex_alloc();
+    if (!reauth_cache->mutex)
+       return SASL_FAIL;
+
+    /* entries */
+    reauth_cache->size = 10;
+    reauth_cache->e = utils->malloc(reauth_cache->size *
+                                   sizeof(reauth_entry_t));
+    if (reauth_cache->e == NULL)
+       return SASL_NOMEM;
+    memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t));
+
+    ((digest_glob_context_t *) digestmd5_client_plugins[0].glob_context)->reauth = reauth_cache;
+
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = digestmd5_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/digestmd5_init.c b/plugins/digestmd5_init.c
new file mode 100644 (file)
index 0000000..25c4356
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_digestmd5_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( digestmd5 )
+SASL_SERVER_PLUG_INIT( digestmd5 )
+
diff --git a/plugins/gssapi.c b/plugins/gssapi.c
new file mode 100644 (file)
index 0000000..d19a6c2
--- /dev/null
@@ -0,0 +1,1798 @@
+/* GSSAPI SASL plugin
+ * Leif Johansson
+ * Rob Siemborski (SASL v2 Conversion)
+ * $Id: gssapi.c,v 1.92 2004/07/21 14:39:06 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.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_GSSAPI_H
+#include <gssapi.h>
+#else
+#include <gssapi/gssapi.h>
+#endif
+
+#ifdef WIN32
+#  include <winsock2.h>
+
+#  ifndef R_OK
+#    define R_OK 04
+#  endif
+/* we also need io.h for access() prototype */
+#  include <io.h>
+#else
+#  include <sys/param.h>
+#  include <sys/socket.h>
+#  include <netinet/in.h>
+#  include <arpa/inet.h>
+#  include <netdb.h>
+#endif /* WIN32 */
+#include <fcntl.h>
+#include <stdio.h>
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: gssapi.c,v 1.92 2004/07/21 14:39:06 rjs3 Exp $";
+
+static const char * GSSAPI_BLANK_STRING = "";
+
+#ifndef HAVE_GSS_C_NT_HOSTBASED_SERVICE
+extern gss_OID gss_nt_service_name;
+#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name
+#endif
+
+#ifdef WANT_KERBEROS5_3DES
+/* Check if CyberSafe flag is defined */
+#ifdef CSF_GSS_C_DES3_FLAG
+#define K5_MAX_SSF     112
+#endif
+
+/* Heimdal and MIT use the following */
+#ifdef GSS_KRB5_CONF_C_QOP_DES3_KD
+#define K5_MAX_SSF     112
+#endif
+
+#endif
+
+#ifndef K5_MAX_SSF
+/* All Kerberos implementations support DES */
+#define K5_MAX_SSF     56
+#endif
+
+/* GSSAPI SASL Mechanism by Leif Johansson <leifj@matematik.su.se>
+ * inspired by the kerberos mechanism and the gssapi_server and
+ * gssapi_client from the heimdal distribution by Assar Westerlund
+ * <assar@sics.se> and Johan Danielsson <joda@pdc.kth.se>. 
+ * See the configure.in file for details on dependencies.
+ *
+ * Important contributions from Sam Hartman <hartmans@fundsxpress.com>.
+ *
+ * This code was tested with the following distributions of Kerberos:
+ * Heimdal (http://www.pdc.kth.se/heimdal), MIT (http://web.mit.edu/kerberos/www/)
+ * CyberSafe (http://www.cybersafe.com/) and SEAM.
+ */
+
+#ifdef GSS_USE_MUTEXES
+#define GSS_LOCK_MUTEX(utils)  \
+    if(((sasl_utils_t *)(utils))->mutex_lock(gss_mutex) != 0) { \
+       return SASL_FAIL; \
+    }
+
+#define GSS_UNLOCK_MUTEX(utils) \
+    if(((sasl_utils_t *)(utils))->mutex_unlock(gss_mutex) != 0) { \
+        return SASL_FAIL; \
+    }
+
+static void *gss_mutex = NULL;
+#else
+#define GSS_LOCK_MUTEX(utils)
+#define GSS_UNLOCK_MUTEX(utils)
+#endif
+
+typedef struct context {
+    int state;
+    
+    gss_ctx_id_t gss_ctx;
+    gss_name_t   client_name;
+    gss_name_t   server_name;
+    gss_cred_id_t server_creds;
+    gss_cred_id_t client_creds;
+
+    sasl_ssf_t limitssf, requiressf; /* application defined bounds, for the
+                                       server */
+    const sasl_utils_t *utils;
+    
+    /* layers buffering */
+    decode_context_t decode_context;
+    
+    char *encode_buf;                /* For encoding/decoding mem management */
+    char *decode_buf;
+    char *decode_once_buf;
+    unsigned encode_buf_len;
+    unsigned decode_buf_len;
+    unsigned decode_once_buf_len;
+    buffer_info_t *enc_in_buf;
+    
+    char *out_buf;                   /* per-step mem management */
+    unsigned out_buf_len;    
+    
+    char *authid; /* hold the authid between steps - server */
+    const char *user;   /* hold the userid between steps - client */
+} context_t;
+
+enum {
+    SASL_GSSAPI_STATE_AUTHNEG = 1,
+    SASL_GSSAPI_STATE_SSFCAP = 2,
+    SASL_GSSAPI_STATE_SSFREQ = 3,
+    SASL_GSSAPI_STATE_AUTHENTICATED = 4
+};
+
+/* sasl_gss_log: only logs status string returned from gss_display_status() */
+#define sasl_gss_log(x,y,z) sasl_gss_seterror_(x,y,z,1)
+#define sasl_gss_seterror(x,y,z) sasl_gss_seterror_(x,y,z,0)
+
+static int
+sasl_gss_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min,
+                  int logonly)
+{
+    OM_uint32 maj_stat, min_stat;
+    gss_buffer_desc msg;
+    OM_uint32 msg_ctx;
+    int ret;
+    char *out = NULL;
+    size_t len, curlen = 0;
+    const char prefix[] = "GSSAPI Error: ";
+    
+    len = sizeof(prefix);
+    ret = _plug_buf_alloc(utils, &out, &curlen, 256);
+    if(ret != SASL_OK) return SASL_OK;
+    
+    strcpy(out, prefix);
+    
+    msg_ctx = 0;
+    while (1) {
+       GSS_LOCK_MUTEX(utils);
+       maj_stat = gss_display_status(&min_stat, maj,
+                                     GSS_C_GSS_CODE, GSS_C_NULL_OID,
+                                     &msg_ctx, &msg);
+       GSS_UNLOCK_MUTEX(utils);
+       
+       if(GSS_ERROR(maj_stat)) {
+           if (logonly) {
+               utils->log(utils->conn, SASL_LOG_FAIL,
+                       "GSSAPI Failure: (could not get major error message)");
+           } else {
+               utils->seterror(utils->conn, 0,
+                               "GSSAPI Failure "
+                               "(could not get major error message)");
+           }
+           utils->free(out);
+           return SASL_OK;
+       }
+       
+       len += len + msg.length;
+       ret = _plug_buf_alloc(utils, &out, &curlen, len);
+       
+       if(ret != SASL_OK) {
+           utils->free(out);
+           return SASL_OK;
+       }
+       
+       strcat(out, msg.value);
+       
+       GSS_LOCK_MUTEX(utils);
+       gss_release_buffer(&min_stat, &msg);
+       GSS_UNLOCK_MUTEX(utils);
+       
+       if (!msg_ctx)
+           break;
+    }
+    
+    /* Now get the minor status */
+    
+    len += 2;
+    ret = _plug_buf_alloc(utils, &out, &curlen, len);
+    if(ret != SASL_OK) {
+       utils->free(out);
+       return SASL_NOMEM;
+    }
+    
+    strcat(out, " (");
+    
+    msg_ctx = 0;
+    while (1) {
+       GSS_LOCK_MUTEX(utils);
+       maj_stat = gss_display_status(&min_stat, min,
+                                     GSS_C_MECH_CODE, GSS_C_NULL_OID,
+                                     &msg_ctx, &msg);
+       GSS_UNLOCK_MUTEX(utils);
+       
+       if(GSS_ERROR(maj_stat)) {
+           if (logonly) {
+               utils->log(utils->conn, SASL_LOG_FAIL,
+                       "GSSAPI Failure: (could not get minor error message)");
+           } else {
+               utils->seterror(utils->conn, 0,
+                               "GSSAPI Failure "
+                               "(could not get minor error message)");
+           }
+           utils->free(out);
+           return SASL_OK;
+       }
+       
+       len += len + msg.length;
+
+       ret = _plug_buf_alloc(utils, &out, &curlen, len);
+       if(ret != SASL_OK) {
+           utils->free(out);
+           return SASL_NOMEM;
+       }
+       
+       strcat(out, msg.value);
+       
+       GSS_LOCK_MUTEX(utils);
+       gss_release_buffer(&min_stat, &msg);
+       GSS_UNLOCK_MUTEX(utils);
+       
+       if (!msg_ctx)
+           break;
+    }
+    
+    len += 1;
+    ret = _plug_buf_alloc(utils, &out, &curlen, len);
+    if(ret != SASL_OK) {
+       utils->free(out);
+       return SASL_NOMEM;
+    }
+    
+    strcat(out, ")");
+    
+    if (logonly) {
+       utils->log(utils->conn, SASL_LOG_FAIL, out);
+    } else {
+       utils->seterror(utils->conn, 0, out);
+    }
+    utils->free(out);
+
+    return SASL_OK;
+}
+
+static int 
+sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov,
+               const char **output, unsigned *outputlen, int privacy)
+{
+    context_t *text = (context_t *)context;
+    OM_uint32 maj_stat, min_stat;
+    gss_buffer_t input_token, output_token;
+    gss_buffer_desc real_input_token, real_output_token;
+    int ret;
+    struct buffer_info *inblob, bufinfo;
+    
+    if(!output) return SASL_BADPARAM;
+    
+    if(numiov > 1) {
+       ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf);
+       if(ret != SASL_OK) return ret;
+       inblob = text->enc_in_buf;
+    } else {
+       bufinfo.data = invec[0].iov_base;
+       bufinfo.curlen = invec[0].iov_len;
+       inblob = &bufinfo;
+    }
+    
+    if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) return SASL_NOTDONE;
+    
+    input_token = &real_input_token;
+    
+    real_input_token.value  = inblob->data;
+    real_input_token.length = inblob->curlen;
+    
+    output_token = &real_output_token;
+    output_token->value = NULL;
+    output_token->length = 0;
+    
+    GSS_LOCK_MUTEX(text->utils);
+    maj_stat = gss_wrap (&min_stat,
+                        text->gss_ctx,
+                        privacy,
+                        GSS_C_QOP_DEFAULT,
+                        input_token,
+                        NULL,
+                        output_token);
+    GSS_UNLOCK_MUTEX(text->utils);
+    
+    if (GSS_ERROR(maj_stat))
+       {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(text->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(text->utils);
+           }
+           return SASL_FAIL;
+       }
+    
+    if (output_token->value && output) {
+       int len;
+       
+       ret = _plug_buf_alloc(text->utils, &(text->encode_buf),
+                             &(text->encode_buf_len), output_token->length + 4);
+       
+       if (ret != SASL_OK) {
+           GSS_LOCK_MUTEX(text->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(text->utils);
+           return ret;
+       }
+       
+       len = htonl(output_token->length);
+       memcpy(text->encode_buf, &len, 4);
+       memcpy(text->encode_buf + 4, output_token->value, output_token->length);
+    }
+    
+    if (outputlen) {
+       *outputlen = output_token->length + 4;
+    }
+    
+    *output = text->encode_buf;
+    
+    if (output_token->value) {
+       GSS_LOCK_MUTEX(text->utils);
+       gss_release_buffer(&min_stat, output_token);
+       GSS_UNLOCK_MUTEX(text->utils);
+    } 
+    return SASL_OK;
+}
+
+static int gssapi_privacy_encode(void *context, const struct iovec *invec,
+                                unsigned numiov, const char **output,
+                                unsigned *outputlen)
+{
+    return sasl_gss_encode(context,invec,numiov,output,outputlen,1);
+}
+
+static int gssapi_integrity_encode(void *context, const struct iovec *invec,
+                                  unsigned numiov, const char **output,
+                                  unsigned *outputlen) 
+{
+    return sasl_gss_encode(context,invec,numiov,output,outputlen,0);
+}
+
+static int gssapi_decode_packet(void *context,
+                               const char *input, unsigned inputlen,
+                               char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    OM_uint32 maj_stat, min_stat;
+    gss_buffer_t input_token, output_token;
+    gss_buffer_desc real_input_token, real_output_token;
+    int result;
+    
+    if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) {
+       SETERROR(text->utils, "GSSAPI Failure");
+       return SASL_NOTDONE;
+    }
+    
+    input_token = &real_input_token; 
+    real_input_token.value = (char *) input;
+    real_input_token.length = inputlen;
+    
+    output_token = &real_output_token;
+    output_token->value = NULL;
+    output_token->length = 0;
+    
+    GSS_LOCK_MUTEX(text->utils);
+    maj_stat = gss_unwrap (&min_stat,
+                          text->gss_ctx,
+                          input_token,
+                          output_token,
+                          NULL,
+                          NULL);
+    GSS_UNLOCK_MUTEX(text->utils);
+    
+    if (GSS_ERROR(maj_stat))
+       {
+           sasl_gss_seterror(text->utils,maj_stat,min_stat);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(text->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(text->utils);
+           }
+           return SASL_FAIL;
+       }
+    
+    if (outputlen)
+       *outputlen = output_token->length;
+    
+    if (output_token->value) {
+       if (output) {
+           result = _plug_buf_alloc(text->utils, &text->decode_once_buf,
+                                    &text->decode_once_buf_len,
+                                    *outputlen);
+           if(result != SASL_OK) {
+               GSS_LOCK_MUTEX(text->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(text->utils);
+               return result;
+           }
+           *output = text->decode_once_buf;
+           memcpy(*output, output_token->value, *outputlen);
+       }
+       GSS_LOCK_MUTEX(text->utils);
+       gss_release_buffer(&min_stat, output_token);
+       GSS_UNLOCK_MUTEX(text->utils);
+    }
+    
+    return SASL_OK;
+}
+
+static int gssapi_decode(void *context,
+                        const char *input, unsigned inputlen,
+                        const char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+    
+    ret = _plug_decode(&text->decode_context, input, inputlen,
+                      &text->decode_buf, &text->decode_buf_len, outputlen,
+                      gssapi_decode_packet, text);
+    
+    *output = text->decode_buf;
+    
+    return ret;
+}
+
+static context_t *sasl_gss_new_context(const sasl_utils_t *utils)
+{
+    context_t *ret;
+    
+    ret = utils->malloc(sizeof(context_t));
+    if(!ret) return NULL;
+    
+    memset(ret,0,sizeof(context_t));
+    ret->utils = utils;
+    
+    return ret;
+}
+
+static int sasl_gss_free_context_contents(context_t *text)
+{
+    OM_uint32 maj_stat, min_stat;
+    
+    if (!text) return SASL_OK;
+    
+    GSS_LOCK_MUTEX(text->utils);
+
+    if (text->gss_ctx != GSS_C_NO_CONTEXT) {
+       maj_stat = gss_delete_sec_context(&min_stat,&text->gss_ctx,
+                                         GSS_C_NO_BUFFER);
+       text->gss_ctx = GSS_C_NO_CONTEXT;
+    }
+    
+    if (text->client_name != GSS_C_NO_NAME) {
+       maj_stat = gss_release_name(&min_stat,&text->client_name);
+       text->client_name = GSS_C_NO_NAME;
+    }
+    
+    if (text->server_name != GSS_C_NO_NAME) {
+       maj_stat = gss_release_name(&min_stat,&text->server_name);
+       text->server_name = GSS_C_NO_NAME;
+    }
+    
+    if ( text->server_creds != GSS_C_NO_CREDENTIAL) {
+       maj_stat = gss_release_cred(&min_stat, &text->server_creds);
+       text->server_creds = GSS_C_NO_CREDENTIAL;
+    }
+
+    if ( text->client_creds != GSS_C_NO_CREDENTIAL) {
+       maj_stat = gss_release_cred(&min_stat, &text->client_creds);
+       text->client_creds = GSS_C_NO_CREDENTIAL;
+    }
+
+    GSS_UNLOCK_MUTEX(text->utils);
+    
+    if (text->out_buf) {
+       text->utils->free(text->out_buf);
+       text->out_buf = NULL;
+    }
+    
+    if (text->encode_buf) {
+       text->utils->free(text->encode_buf);
+       text->encode_buf = NULL;
+    }
+    
+    if (text->decode_buf) {
+       text->utils->free(text->decode_buf);
+       text->decode_buf = NULL;
+    }
+    
+    if (text->decode_once_buf) {
+       text->utils->free(text->decode_once_buf);
+       text->decode_once_buf = NULL;
+    }
+    
+    if (text->enc_in_buf) {
+       if(text->enc_in_buf->data) text->utils->free(text->enc_in_buf->data);
+       text->utils->free(text->enc_in_buf);
+       text->enc_in_buf = NULL;
+    }
+
+    _plug_decode_free(&text->decode_context);
+    
+    if (text->authid) { /* works for both client and server */
+       text->utils->free(text->authid);
+       text->authid = NULL;
+    }
+
+    return SASL_OK;
+
+}
+
+static void gssapi_common_mech_dispose(void *conn_context,
+                                      const sasl_utils_t *utils)
+{
+    sasl_gss_free_context_contents((context_t *)(conn_context));
+    utils->free(conn_context);
+}
+
+static void gssapi_common_mech_free(void *global_context __attribute__((unused)),
+                                   const sasl_utils_t *utils)
+{
+#ifdef GSS_USE_MUTEXES
+    if (gss_mutex) {
+      utils->mutex_free(gss_mutex);
+      gss_mutex=NULL;
+    }
+#endif
+}
+
+/*****************************  Server Section  *****************************/
+
+static int 
+gssapi_server_mech_new(void *glob_context __attribute__((unused)), 
+                      sasl_server_params_t *params,
+                      const char *challenge __attribute__((unused)), 
+                      unsigned challen __attribute__((unused)),
+                      void **conn_context)
+{
+    context_t *text;
+    
+    text = sasl_gss_new_context(params->utils);
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    text->gss_ctx = GSS_C_NO_CONTEXT;
+    text->client_name = GSS_C_NO_NAME;
+    text->server_name = GSS_C_NO_NAME;
+    text->server_creds = GSS_C_NO_CREDENTIAL;
+    text->client_creds = GSS_C_NO_CREDENTIAL;
+    text->state = SASL_GSSAPI_STATE_AUTHNEG;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int 
+gssapi_server_mech_step(void *conn_context,
+                       sasl_server_params_t *params,
+                       const char *clientin,
+                       unsigned clientinlen,
+                       const char **serverout,
+                       unsigned *serveroutlen,
+                       sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *)conn_context;
+    gss_buffer_t input_token, output_token;
+    gss_buffer_desc real_input_token, real_output_token;
+    OM_uint32 maj_stat = 0, min_stat = 0;
+    OM_uint32 max_input;
+    gss_buffer_desc name_token;
+    int ret, out_flags = 0 ;
+    
+    input_token = &real_input_token;
+    output_token = &real_output_token;
+    output_token->value = NULL; output_token->length = 0;
+    input_token->value = NULL; input_token->length = 0;
+    
+    if(!serverout) {
+       PARAMERROR(text->utils);
+       return SASL_BADPARAM;
+    }
+    
+    *serverout = NULL;
+    *serveroutlen = 0; 
+           
+    switch (text->state) {
+
+    case SASL_GSSAPI_STATE_AUTHNEG:
+       if (text->server_name == GSS_C_NO_NAME) { /* only once */
+           name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN);
+           name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char));
+           if (name_token.value == NULL) {
+               MEMERROR(text->utils);
+               sasl_gss_free_context_contents(text);
+               return SASL_NOMEM;
+           }
+           sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN);
+           
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_import_name (&min_stat,
+                                       &name_token,
+                                       GSS_C_NT_HOSTBASED_SERVICE,
+                                       &text->server_name);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           params->utils->free(name_token.value);
+           name_token.value = NULL;
+           
+           if (GSS_ERROR(maj_stat)) {
+               sasl_gss_seterror(text->utils, maj_stat, min_stat);
+               sasl_gss_free_context_contents(text);
+               return SASL_FAIL;
+           }
+           
+           if ( text->server_creds != GSS_C_NO_CREDENTIAL) {
+               GSS_LOCK_MUTEX(params->utils);
+               maj_stat = gss_release_cred(&min_stat, &text->server_creds);
+               GSS_UNLOCK_MUTEX(params->utils);
+               text->server_creds = GSS_C_NO_CREDENTIAL;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_acquire_cred(&min_stat, 
+                                       text->server_name,
+                                       GSS_C_INDEFINITE, 
+                                       GSS_C_NO_OID_SET,
+                                       GSS_C_ACCEPT,
+                                       &text->server_creds, 
+                                       NULL, 
+                                       NULL);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (GSS_ERROR(maj_stat)) {
+               sasl_gss_seterror(text->utils, maj_stat, min_stat);
+               sasl_gss_free_context_contents(text);
+               return SASL_FAIL;
+           }
+       }
+       
+       if (clientinlen) {
+           real_input_token.value = (void *)clientin;
+           real_input_token.length = clientinlen;
+       }
+       
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat =
+           gss_accept_sec_context(&min_stat,
+                                  &(text->gss_ctx),
+                                  text->server_creds,
+                                  input_token,
+                                  GSS_C_NO_CHANNEL_BINDINGS,
+                                  &text->client_name,
+                                  NULL,
+                                  output_token,
+                                  &out_flags,
+                                  NULL,
+                                  &(text->client_creds));
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_log(text->utils, maj_stat, min_stat);
+           text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context");
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           sasl_gss_free_context_contents(text);
+           return SASL_BADAUTH;
+       }
+           
+
+       if ((params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) &&
+           (!(out_flags & GSS_C_DELEG_FLAG) ||
+            text->client_creds == GSS_C_NO_CREDENTIAL) ) 
+       {
+           text->utils->seterror(text->utils->conn, SASL_LOG_WARN,
+                                 "GSSAPI warning: no credentials were passed");
+           /* continue with authentication */
+       }
+           
+       if (serveroutlen)
+           *serveroutlen = output_token->length;
+       if (output_token->value) {
+           if (serverout) {
+               ret = _plug_buf_alloc(text->utils, &(text->out_buf),
+                                     &(text->out_buf_len), *serveroutlen);
+               if(ret != SASL_OK) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, output_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+                   return ret;
+               }
+               memcpy(text->out_buf, output_token->value, *serveroutlen);
+               *serverout = text->out_buf;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+       } else {
+           /* No output token, send an empty string */
+           *serverout = GSSAPI_BLANK_STRING;
+           serveroutlen = 0;
+       }
+       
+       if (maj_stat == GSS_S_COMPLETE) {
+           /* Switch to ssf negotiation */
+           text->state = SASL_GSSAPI_STATE_SSFCAP;
+       }
+       
+       return SASL_CONTINUE;
+
+    case SASL_GSSAPI_STATE_SSFCAP: {
+       unsigned char sasldata[4];
+       gss_buffer_desc name_token;
+       gss_buffer_desc name_without_realm;
+       gss_name_t without = NULL;
+       int equal;
+       
+       name_token.value = NULL;
+       name_without_realm.value = NULL;
+       
+       /* We ignore whatever the client sent us at this stage */
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_display_name (&min_stat,
+                                    text->client_name,
+                                    &name_token,
+                                    NULL);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           if (without) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_name(&min_stat, &without);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           SETERROR(text->utils, "GSSAPI Failure");
+           sasl_gss_free_context_contents(text);
+           return SASL_BADAUTH;
+       }
+       
+       /* If the id contains a realm get the identifier for the user
+          without the realm and see if it's the same id (i.e. 
+          tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want
+          to return the id (i.e. just "tmartin" */
+       if (strchr((char *) name_token.value, (int) '@') != NULL) {
+           /* NOTE: libc malloc, as it is freed below by a gssapi internal
+            *       function! */
+           name_without_realm.value = params->utils->malloc(strlen(name_token.value)+1);
+           if (name_without_realm.value == NULL) {
+               if (name_token.value) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, &name_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+               }
+               MEMERROR(text->utils);
+               return SASL_NOMEM;
+           }
+           
+           strcpy(name_without_realm.value, name_token.value);
+           
+           /* cut off string at '@' */
+           (strchr(name_without_realm.value,'@'))[0] = '\0';
+           
+           name_without_realm.length = strlen( (char *) name_without_realm.value );
+           
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_import_name (&min_stat,
+                                       &name_without_realm,
+           /* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here,
+              so use GSS_C_NT_USER_NAME instead if available.  */
+#ifdef HAVE_GSS_C_NT_USER_NAME
+                                       GSS_C_NT_USER_NAME,
+#else
+                                       GSS_C_NULL_OID,
+#endif
+                                       &without);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (GSS_ERROR(maj_stat)) {
+               params->utils->free(name_without_realm.value);
+               if (name_token.value) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, &name_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+               }
+               SETERROR(text->utils, "GSSAPI Failure");
+               sasl_gss_free_context_contents(text);
+               return SASL_BADAUTH;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_compare_name(&min_stat,
+                                       text->client_name,
+                                       without,
+                                       &equal);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (GSS_ERROR(maj_stat)) {
+               params->utils->free(name_without_realm.value);
+               if (name_token.value) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, &name_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+               }
+               if (without) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_name(&min_stat, &without);
+                   GSS_UNLOCK_MUTEX(params->utils);
+               }
+               SETERROR(text->utils, "GSSAPI Failure");
+               sasl_gss_free_context_contents(text);
+               return SASL_BADAUTH;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_name(&min_stat,&without);
+           GSS_UNLOCK_MUTEX(params->utils);
+
+       } else {
+           equal = 0;
+       }
+       
+       if (equal) {
+           text->authid = strdup(name_without_realm.value);
+           
+           if (text->authid == NULL) {
+               MEMERROR(params->utils);
+               return SASL_NOMEM;
+           }
+       } else {
+           text->authid = strdup(name_token.value);
+           
+           if (text->authid == NULL) {
+               MEMERROR(params->utils);
+               return SASL_NOMEM;
+           }
+       }
+       
+       if (name_token.value) {
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, &name_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+       }
+       if (name_without_realm.value) {
+           params->utils->free(name_without_realm.value);
+       }       
+       
+       /* we have to decide what sort of encryption/integrity/etc.,
+          we support */
+       if (params->props.max_ssf < params->external_ssf) {
+           text->limitssf = 0;
+       } else {
+           text->limitssf = params->props.max_ssf - params->external_ssf;
+       }
+       if (params->props.min_ssf < params->external_ssf) {
+           text->requiressf = 0;
+       } else {
+           text->requiressf = params->props.min_ssf - params->external_ssf;
+       }
+       
+       /* build up our security properties token */
+        if (params->props.maxbufsize > 0xFFFFFF) {
+            /* make sure maxbufsize isn't too large */
+            /* maxbufsize = 0xFFFFFF */
+            sasldata[1] = sasldata[2] = sasldata[3] = 0xFF;
+        } else {
+            sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF;
+            sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF;
+            sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF;
+        }
+       sasldata[0] = 0;
+       if(text->requiressf != 0 && !params->props.maxbufsize) {
+           params->utils->seterror(params->utils->conn, 0,
+                                   "GSSAPI needs a security layer but one is forbidden");
+           return SASL_TOOWEAK;
+       }
+       
+       if (text->requiressf == 0) {
+           sasldata[0] |= 1; /* authentication */
+       }
+       if (text->requiressf <= 1 && text->limitssf >= 1
+           && params->props.maxbufsize) {
+           sasldata[0] |= 2;
+       }
+       if (text->requiressf <= K5_MAX_SSF && text->limitssf >= K5_MAX_SSF
+           && params->props.maxbufsize) {
+           sasldata[0] |= 4;
+       }
+       
+       real_input_token.value = (void *)sasldata;
+       real_input_token.length = 4;
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_wrap(&min_stat,
+                           text->gss_ctx,
+                           0, /* Just integrity checking here */
+                           GSS_C_QOP_DEFAULT,
+                           input_token,
+                           NULL,
+                           output_token);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }
+       
+       
+       if (serveroutlen)
+           *serveroutlen = output_token->length;
+       if (output_token->value) {
+           if (serverout) {
+               ret = _plug_buf_alloc(text->utils, &(text->out_buf),
+                                     &(text->out_buf_len), *serveroutlen);
+               if(ret != SASL_OK) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, output_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+                   return ret;
+               }
+               memcpy(text->out_buf, output_token->value, *serveroutlen);
+               *serverout = text->out_buf;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+       }
+       
+       /* Wait for ssf request and authid */
+       text->state = SASL_GSSAPI_STATE_SSFREQ; 
+       
+       return SASL_CONTINUE;
+    }
+
+    case SASL_GSSAPI_STATE_SSFREQ: {
+       int layerchoice;
+       
+       real_input_token.value = (void *)clientin;
+       real_input_token.length = clientinlen;
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_unwrap(&min_stat,
+                             text->gss_ctx,
+                             input_token,
+                             output_token,
+                             NULL,
+                             NULL);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }
+       
+       layerchoice = (int)(((char *)(output_token->value))[0]);
+       if (layerchoice == 1 && text->requiressf == 0) { /* no encryption */
+           oparams->encode = NULL;
+           oparams->decode = NULL;
+           oparams->mech_ssf = 0;
+       } else if (layerchoice == 2 && text->requiressf <= 1 &&
+                  text->limitssf >= 1) { /* integrity */
+           oparams->encode=&gssapi_integrity_encode;
+           oparams->decode=&gssapi_decode;
+           oparams->mech_ssf=1;
+       } else if (layerchoice == 4 && text->requiressf <= K5_MAX_SSF &&
+                  text->limitssf >= K5_MAX_SSF) { /* privacy */
+           oparams->encode = &gssapi_privacy_encode;
+           oparams->decode = &gssapi_decode;
+           /* FIX ME: Need to extract the proper value here */
+           oparams->mech_ssf = K5_MAX_SSF;
+       } else {
+           /* not a supported encryption layer */
+           SETERROR(text->utils,
+                    "protocol violation: client requested invalid layer");
+           /* Mark that we attempted negotiation */
+           oparams->mech_ssf = 2;
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }
+       
+       if (output_token->length > 4) {
+           int ret;
+           
+           ret = params->canon_user(params->utils->conn,
+                                    ((char *) output_token->value) + 4,
+                                    (output_token->length - 4) * sizeof(char),
+                                    SASL_CU_AUTHZID, oparams);
+           
+           if (ret != SASL_OK) {
+               sasl_gss_free_context_contents(text);
+               return ret;
+           }
+           
+           ret = params->canon_user(params->utils->conn,
+                                    text->authid,
+                                    0, /* strlen(text->authid) */
+                                    SASL_CU_AUTHID, oparams);
+           if (ret != SASL_OK) {
+               sasl_gss_free_context_contents(text);
+               return ret;
+           }
+       } else if(output_token->length == 4) {
+           /* null authzid */
+           int ret;
+           
+           ret = params->canon_user(params->utils->conn,
+                                    text->authid,
+                                    0, /* strlen(text->authid) */
+                                    SASL_CU_AUTHZID | SASL_CU_AUTHID,
+                                    oparams);
+           
+           if (ret != SASL_OK) {
+               sasl_gss_free_context_contents(text);
+               return ret;
+           }       
+       } else {
+           SETERROR(text->utils,
+                    "token too short");
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }       
+       
+       /* No matter what, set the rest of the oparams */
+       
+       if (text->client_creds != GSS_C_NO_CREDENTIAL)  {
+           oparams->client_creds =  &text->client_creds;
+       }
+       else {
+           oparams->client_creds = NULL;
+       }
+
+        oparams->maxoutbuf =
+           (((unsigned char *) output_token->value)[1] << 16) |
+            (((unsigned char *) output_token->value)[2] << 8) |
+            (((unsigned char *) output_token->value)[3] << 0);
+
+       if (oparams->mech_ssf) {
+           maj_stat = gss_wrap_size_limit( &min_stat,
+                                           text->gss_ctx,
+                                           1,
+                                           GSS_C_QOP_DEFAULT,
+                                           (OM_uint32) oparams->maxoutbuf,
+                                           &max_input);
+
+           if(max_input > oparams->maxoutbuf) {
+               /* Heimdal appears to get this wrong */
+               oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
+           } else {
+               /* This code is actually correct */
+               oparams->maxoutbuf = max_input;
+           }    
+       }
+       
+       GSS_LOCK_MUTEX(params->utils);
+       gss_release_buffer(&min_stat, output_token);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
+       
+       /* used by layers */
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         params->props.maxbufsize);
+       
+       oparams->doneflag = 1;
+       
+       return SASL_OK;
+    }
+    
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid GSSAPI server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static sasl_server_plug_t gssapi_server_plugins[] = 
+{
+    {
+       "GSSAPI",                       /* mech_name */
+       K5_MAX_SSF,                     /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH          /* security_flags */
+       | SASL_SEC_PASS_CREDENTIALS,
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &gssapi_server_mech_new,        /* mech_new */
+       &gssapi_server_mech_step,       /* mech_step */
+       &gssapi_common_mech_dispose,    /* mech_dispose */
+       &gssapi_common_mech_free,       /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int gssapiv2_server_plug_init(
+#ifndef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
+    const sasl_utils_t *utils __attribute__((unused)),
+#else
+    const sasl_utils_t *utils,
+#endif 
+    int maxversion,
+    int *out_version,
+    sasl_server_plug_t **pluglist,
+    int *plugcount)
+{
+#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
+    const char *keytab = NULL;
+    char keytab_path[1024];
+    unsigned int rl;
+#endif
+    
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       return SASL_BADVERS;
+    }
+    
+#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
+    /* unfortunately, we don't check for readability of keytab if it's
+       the standard one, since we don't know where it is */
+    
+    /* FIXME: This code is broken */
+    
+    utils->getopt(utils->getopt_context, "GSSAPI", "keytab", &keytab, &rl);
+    if (keytab != NULL) {
+       if (access(keytab, R_OK) != 0) {
+           utils->log(NULL, SASL_LOG_ERR,
+                      "Could not find keytab file: %s: %m",
+                      keytab, errno);
+           return SASL_FAIL;
+       }
+       
+       if(strlen(keytab) > 1024) {
+           utils->log(NULL, SASL_LOG_ERR,
+                      "path to keytab is > 1024 characters");
+           return SASL_BUFOVER;
+       }
+       
+       strncpy(keytab_path, keytab, 1024);
+       
+       gsskrb5_register_acceptor_identity(keytab_path);
+    }
+#endif
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = gssapi_server_plugins;
+    *plugcount = 1;  
+
+#ifdef GSS_USE_MUTEXES
+    if (!gss_mutex) {
+       gss_mutex = utils->mutex_alloc();
+       if (!gss_mutex) {
+           return SASL_FAIL;
+       }
+    }
+#endif
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+static int gssapi_client_mech_new(void *glob_context __attribute__((unused)), 
+                                 sasl_client_params_t *params,
+                                 void **conn_context)
+{
+    context_t *text;
+    
+    /* holds state are in */
+    text = sasl_gss_new_context(params->utils);
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    text->state = SASL_GSSAPI_STATE_AUTHNEG;
+    text->gss_ctx = GSS_C_NO_CONTEXT;
+    text->client_name = GSS_C_NO_NAME;
+    text->server_creds = GSS_C_NO_CREDENTIAL;
+    text->client_creds  = GSS_C_NO_CREDENTIAL;
+
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int gssapi_client_mech_step(void *conn_context,
+                                  sasl_client_params_t *params,
+                                  const char *serverin,
+                                  unsigned serverinlen,
+                                  sasl_interact_t **prompt_need,
+                                  const char **clientout,
+                                  unsigned *clientoutlen,
+                                  sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *)conn_context;
+    gss_buffer_t input_token, output_token;
+    gss_buffer_desc real_input_token, real_output_token;
+    OM_uint32 maj_stat = 0, min_stat = 0;
+    OM_uint32 max_input;
+    gss_buffer_desc name_token;
+    int ret;
+    OM_uint32 req_flags = 0, out_req_flags = 0;
+    input_token = &real_input_token;
+    output_token = &real_output_token;
+    output_token->value = NULL;
+    input_token->value = NULL; 
+    input_token->length = 0;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    switch (text->state) {
+
+    case SASL_GSSAPI_STATE_AUTHNEG:
+       /* try to get the userid */
+       if (text->user == NULL) {
+           int user_result = SASL_OK;
+           
+           user_result = _plug_get_userid(params->utils, &text->user,
+                                          prompt_need);
+           
+           if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) {
+               sasl_gss_free_context_contents(text);
+               return user_result;
+           }
+                   
+           /* free prompts we got */
+           if (prompt_need && *prompt_need) {
+               params->utils->free(*prompt_need);
+               *prompt_need = NULL;
+           }
+                   
+           /* if there are prompts not filled in */
+           if (user_result == SASL_INTERACT) {
+               /* make the prompt list */
+               int result =
+                   _plug_make_prompts(params->utils, prompt_need,
+                                      user_result == SASL_INTERACT ?
+                                      "Please enter your authorization name" : NULL, NULL,
+                                      NULL, NULL,
+                                      NULL, NULL,
+                                      NULL, NULL, NULL,
+                                      NULL, NULL, NULL);
+               if (result != SASL_OK) return result;
+               
+               return SASL_INTERACT;
+           }
+       }
+           
+       if (text->server_name == GSS_C_NO_NAME) { /* only once */
+           name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN);
+           name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char));
+           if (name_token.value == NULL) {
+               sasl_gss_free_context_contents(text);
+               return SASL_NOMEM;
+           }
+           if (params->serverFQDN == NULL
+               || strlen(params->serverFQDN) == 0) {
+               SETERROR(text->utils, "GSSAPI Failure: no serverFQDN");
+               return SASL_FAIL;
+           }
+           
+           sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN);
+           
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_import_name (&min_stat,
+                                       &name_token,
+                                       GSS_C_NT_HOSTBASED_SERVICE,
+                                       &text->server_name);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           params->utils->free(name_token.value);
+           name_token.value = NULL;
+           
+           if (GSS_ERROR(maj_stat)) {
+               sasl_gss_seterror(text->utils, maj_stat, min_stat);
+               sasl_gss_free_context_contents(text);
+               return SASL_FAIL;
+           }
+       }
+           
+       if (serverinlen == 0)
+           input_token = GSS_C_NO_BUFFER;
+
+       if (serverinlen) {
+           real_input_token.value = (void *)serverin;
+           real_input_token.length = serverinlen;
+       }
+       else if (text->gss_ctx != GSS_C_NO_CONTEXT ) {
+           /* This can't happen under GSSAPI: we have a non-null context
+            * and no input from the server.  However, thanks to Imap,
+            * which discards our first output, this happens all the time.
+            * Throw away the context and try again. */
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER);
+           GSS_UNLOCK_MUTEX(params->utils);
+           text->gss_ctx = GSS_C_NO_CONTEXT;
+       }
+           
+       /* Setup req_flags properly */
+       req_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG;
+       if(params->props.max_ssf > params->external_ssf) {
+           /* We are requesting a security layer */
+           req_flags |= GSS_C_INTEG_FLAG;
+           /* Any SSF bigger than 1 is confidentiality. */
+           /* Let's check if the client of the API requires confidentiality,
+              and it wasn't already provided by an external layer */
+           if(params->props.max_ssf - params->external_ssf > 1) {
+               /* We want to try for privacy */
+               req_flags |= GSS_C_CONF_FLAG;
+           }
+       }
+       
+       if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS)
+           req_flags = req_flags |  GSS_C_DELEG_FLAG;
+
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_init_sec_context(&min_stat,
+                                       GSS_C_NO_CREDENTIAL,
+                                       &text->gss_ctx,
+                                       text->server_name,
+                                       GSS_C_NO_OID,
+                                       req_flags,
+                                       0,
+                                       GSS_C_NO_CHANNEL_BINDINGS,
+                                       input_token,
+                                       NULL,
+                                       output_token,
+                                       &out_req_flags,
+                                       NULL);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }
+
+       if ((out_req_flags & GSS_C_DELEG_FLAG) != (req_flags & GSS_C_DELEG_FLAG)) {
+           text->utils->seterror(text->utils->conn, SASL_LOG_WARN, "GSSAPI warning: no credentials were passed");
+           /* not a fatal error */
+       }
+           
+       *clientoutlen = output_token->length;
+           
+       if (output_token->value) {
+           if (clientout) {
+               ret = _plug_buf_alloc(text->utils, &(text->out_buf),
+                                     &(text->out_buf_len), *clientoutlen);
+               if(ret != SASL_OK) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, output_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+                   return ret;
+               }
+               memcpy(text->out_buf, output_token->value, *clientoutlen);
+               *clientout = text->out_buf;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+       }
+       
+       if (maj_stat == GSS_S_COMPLETE) {
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_inquire_context(&min_stat,
+                                          text->gss_ctx,
+                                          &text->client_name,
+                                          NULL,       /* targ_name */
+                                          NULL,       /* lifetime */
+                                          NULL,       /* mech */
+                                          /* FIX ME: Should check the resulting flags here */
+                                          NULL,       /* flags */
+                                          NULL,       /* local init */
+                                          NULL);      /* open */
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (GSS_ERROR(maj_stat)) {
+               sasl_gss_seterror(text->utils, maj_stat, min_stat);
+               sasl_gss_free_context_contents(text);
+               return SASL_FAIL;
+           }
+           
+           name_token.length = 0;
+           GSS_LOCK_MUTEX(params->utils);
+           maj_stat = gss_display_name(&min_stat,
+                                       text->client_name,
+                                       &name_token,
+                                       NULL);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (GSS_ERROR(maj_stat)) {
+               if (name_token.value) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, &name_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+               }
+               SETERROR(text->utils, "GSSAPI Failure");
+               sasl_gss_free_context_contents(text);
+               return SASL_FAIL;
+           }
+           
+           if (text->user && text->user[0]) {
+               ret = params->canon_user(params->utils->conn,
+                                        text->user, 0,
+                                        SASL_CU_AUTHZID, oparams);
+               if (ret == SASL_OK) 
+                   ret = params->canon_user(params->utils->conn,
+                                            name_token.value, 0,
+                                            SASL_CU_AUTHID, oparams);
+           } else {
+               ret = params->canon_user(params->utils->conn,
+                                        name_token.value, 0,
+                                        SASL_CU_AUTHID | SASL_CU_AUTHZID,
+                                        oparams);
+           }
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, &name_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+           
+           if (ret != SASL_OK) return ret;
+           
+           /* Switch to ssf negotiation */
+           text->state = SASL_GSSAPI_STATE_SSFCAP;
+       }
+       
+       return SASL_CONTINUE;
+
+    case SASL_GSSAPI_STATE_SSFCAP: {
+       sasl_security_properties_t *secprops = &(params->props);
+       unsigned int alen, external = params->external_ssf;
+       sasl_ssf_t need, allowed;
+       char serverhas, mychoice;
+       
+       real_input_token.value = (void *) serverin;
+       real_input_token.length = serverinlen;
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_unwrap(&min_stat,
+                             text->gss_ctx,
+                             input_token,
+                             output_token,
+                             NULL,
+                             NULL);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           sasl_gss_free_context_contents(text);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           return SASL_FAIL;
+       }
+       
+       /* taken from kerberos.c */
+       if (secprops->min_ssf > (K5_MAX_SSF + external)) {
+           return SASL_TOOWEAK;
+       } else if (secprops->min_ssf > secprops->max_ssf) {
+           return SASL_BADPARAM;
+       }
+       
+       /* need bits of layer -- sasl_ssf_t is unsigned so be careful */
+       if (secprops->max_ssf >= external) {
+           allowed = secprops->max_ssf - external;
+       } else {
+           allowed = 0;
+       }
+       if (secprops->min_ssf >= external) {
+           need = secprops->min_ssf - external;
+       } else {
+           /* good to go */
+           need = 0;
+       }
+       
+       /* bit mask of server support */
+       serverhas = ((char *)output_token->value)[0];
+       
+       /* if client didn't set use strongest layer available */
+       if (allowed >= K5_MAX_SSF && need <= K5_MAX_SSF && (serverhas & 4)) {
+           /* encryption */
+           oparams->encode = &gssapi_privacy_encode;
+           oparams->decode = &gssapi_decode;
+           /* FIX ME: Need to extract the proper value here */
+           oparams->mech_ssf = K5_MAX_SSF;
+           mychoice = 4;
+       } else if (allowed >= 1 && need <= 1 && (serverhas & 2)) {
+           /* integrity */
+           oparams->encode = &gssapi_integrity_encode;
+           oparams->decode = &gssapi_decode;
+           oparams->mech_ssf = 1;
+           mychoice = 2;
+       } else if (need <= 0 && (serverhas & 1)) {
+           /* no layer */
+           oparams->encode = NULL;
+           oparams->decode = NULL;
+           oparams->mech_ssf = 0;
+           mychoice = 1;
+       } else {
+           /* there's no appropriate layering for us! */
+           sasl_gss_free_context_contents(text);
+           return SASL_TOOWEAK;
+       }
+       
+        oparams->maxoutbuf =
+           (((unsigned char *) output_token->value)[1] << 16) |
+            (((unsigned char *) output_token->value)[2] << 8) |
+            (((unsigned char *) output_token->value)[3] << 0);
+
+       if(oparams->mech_ssf) {
+            maj_stat = gss_wrap_size_limit( &min_stat,
+                                            text->gss_ctx,
+                                            1,
+                                            GSS_C_QOP_DEFAULT,
+                                            (OM_uint32) oparams->maxoutbuf,
+                                            &max_input);
+
+           if(max_input > oparams->maxoutbuf) {
+               /* Heimdal appears to get this wrong */
+               oparams->maxoutbuf -= (max_input - oparams->maxoutbuf);
+           } else {
+               /* This code is actually correct */
+               oparams->maxoutbuf = max_input;
+           }
+       }
+       
+       GSS_LOCK_MUTEX(params->utils);
+       gss_release_buffer(&min_stat, output_token);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       /* oparams->user is always set, due to canon_user requirements.
+        * Make sure the client actually requested it though, by checking
+        * if our context was set.
+        */
+       if (text->user && text->user[0])
+           alen = strlen(oparams->user);
+       else
+           alen = 0;
+       
+       input_token->length = 4 + alen;
+       input_token->value =
+           (char *)params->utils->malloc((input_token->length + 1)*sizeof(char));
+       if (input_token->value == NULL) {
+           sasl_gss_free_context_contents(text);
+           return SASL_NOMEM;
+       }
+       
+       if (alen)
+           memcpy((char *)input_token->value+4,oparams->user,alen);
+
+       /* build up our security properties token */
+        if (params->props.maxbufsize > 0xFFFFFF) {
+            /* make sure maxbufsize isn't too large */
+            /* maxbufsize = 0xFFFFFF */
+            ((unsigned char *)input_token->value)[1] = 0xFF;
+            ((unsigned char *)input_token->value)[2] = 0xFF;
+            ((unsigned char *)input_token->value)[3] = 0xFF;
+        } else {
+            ((unsigned char *)input_token->value)[1] = 
+                (params->props.maxbufsize >> 16) & 0xFF;
+            ((unsigned char *)input_token->value)[2] = 
+                (params->props.maxbufsize >> 8) & 0xFF;
+            ((unsigned char *)input_token->value)[3] = 
+                (params->props.maxbufsize >> 0) & 0xFF;
+        }
+       ((unsigned char *)input_token->value)[0] = mychoice;
+       
+       GSS_LOCK_MUTEX(params->utils);
+       maj_stat = gss_wrap (&min_stat,
+                            text->gss_ctx,
+                            0, /* Just integrity checking here */
+                            GSS_C_QOP_DEFAULT,
+                            input_token,
+                            NULL,
+                            output_token);
+       GSS_UNLOCK_MUTEX(params->utils);
+       
+       params->utils->free(input_token->value);
+       input_token->value = NULL;
+       
+       if (GSS_ERROR(maj_stat)) {
+           sasl_gss_seterror(text->utils, maj_stat, min_stat);
+           if (output_token->value) {
+               GSS_LOCK_MUTEX(params->utils);
+               gss_release_buffer(&min_stat, output_token);
+               GSS_UNLOCK_MUTEX(params->utils);
+           }
+           sasl_gss_free_context_contents(text);
+           return SASL_FAIL;
+       }
+       
+       if (clientoutlen)
+           *clientoutlen = output_token->length;
+       if (output_token->value) {
+           if (clientout) {
+               ret = _plug_buf_alloc(text->utils, &(text->out_buf),
+                                     &(text->out_buf_len), *clientoutlen);
+               if (ret != SASL_OK) {
+                   GSS_LOCK_MUTEX(params->utils);
+                   gss_release_buffer(&min_stat, output_token);
+                   GSS_UNLOCK_MUTEX(params->utils);
+                   return ret;
+               }
+               memcpy(text->out_buf, output_token->value, *clientoutlen);
+               *clientout = text->out_buf;
+           }
+           
+           GSS_LOCK_MUTEX(params->utils);
+           gss_release_buffer(&min_stat, output_token);
+           GSS_UNLOCK_MUTEX(params->utils);
+
+       }
+       
+       text->state = SASL_GSSAPI_STATE_AUTHENTICATED;
+       
+       oparams->doneflag = 1;
+       
+       /* used by layers */
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         params->props.maxbufsize);
+       
+       return SASL_OK;
+    }
+       
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid GSSAPI client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static const long gssapi_required_prompts[] = {
+    SASL_CB_LIST_END
+};  
+
+static sasl_client_plug_t gssapi_client_plugins[] = 
+{
+    {
+       "GSSAPI",                       /* mech_name */
+       K5_MAX_SSF,                     /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH 
+       | SASL_SEC_PASS_CREDENTIALS,    /* security_flags */
+       SASL_FEAT_NEEDSERVERFQDN
+       | SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       gssapi_required_prompts,        /* required_prompts */
+       NULL,                           /* glob_context */
+       &gssapi_client_mech_new,        /* mech_new */
+       &gssapi_client_mech_step,       /* mech_step */
+       &gssapi_common_mech_dispose,    /* mech_dispose */
+       &gssapi_common_mech_free,       /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int gssapiv2_client_plug_init(const sasl_utils_t *utils __attribute__((unused)), 
+                             int maxversion,
+                             int *out_version, 
+                             sasl_client_plug_t **pluglist,
+                             int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "Version mismatch in GSSAPI");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = gssapi_client_plugins;
+    *plugcount = 1;
+
+#ifdef GSS_USE_MUTEXES
+    if(!gss_mutex) {
+      gss_mutex = utils->mutex_alloc();
+      if(!gss_mutex) {
+        return SASL_FAIL;
+      }
+    }
+#endif
+    
+    return SASL_OK;
+}
+
diff --git a/plugins/gssapiv2_init.c b/plugins/gssapiv2_init.c
new file mode 100644 (file)
index 0000000..04c9a15
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_gssapiv2_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( gssapiv2 )
+SASL_SERVER_PLUG_INIT( gssapiv2 )
+
diff --git a/plugins/kerberos4.c b/plugins/kerberos4.c
new file mode 100644 (file)
index 0000000..af8b469
--- /dev/null
@@ -0,0 +1,1406 @@
+/* Kerberos4 SASL plugin
+ * Rob Siemborski
+ * Tim Martin 
+ * $Id: kerberos4.c,v 1.99 2005/01/10 07:08:53 shadow 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.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+#include <krb.h>
+
+#ifdef WITH_DES
+# ifdef WITH_SSL_DES
+#  include <openssl/des.h>
+# else
+#  include <des.h>
+# endif /* WITH_SSL_DES */
+#endif /* WITH_DES */
+
+#ifdef WIN32
+# include <winsock2.h>
+#elif defined(macintosh)
+#include <kcglue_krb.h>
+#else
+# include <sys/param.h>
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+#endif /* WIN32 */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+
+#include <errno.h>
+#include <ctype.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+/*
+ * krb.h doenst include some functions and mac compiler is picky
+ * about declartions
+ */
+#include <extra_krb.h>
+#include <sasl_kerberos4_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+/* This must be after sasl.h, saslutil.h */
+# include "saslKERBEROSV4.h"
+
+/* KClient doesn't define this */
+typedef struct krb_principal {
+    char name[ANAME_SZ];
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+} krb_principal;
+
+/* This isn't defined under WIN32.  For access() */
+#ifndef R_OK
+#define R_OK 04
+#endif
+/* we also need io.h for access() prototype */
+#include <io.h>
+#endif /* WIN32 */
+
+#ifdef sun
+/* gotta define gethostname ourselves on suns */
+extern int gethostname(char *, int);
+#endif
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: kerberos4.c,v 1.99 2005/01/10 07:08:53 shadow Exp $";
+
+#ifndef KEYFILE
+#define KEYFILE "/etc/srvtab";
+#endif
+
+#define KRB_SECFLAG_NONE (1)
+#define KRB_SECFLAG_INTEGRITY (2)
+#define KRB_SECFLAG_ENCRYPTION (4)
+#define KRB_SECFLAGS (7)
+#define KRB_SECFLAG_CREDENTIALS (8)
+
+#define KRB_DES_SECURITY_BITS (56)
+#define KRB_INTEGRITY_BITS (1)
+
+typedef enum Krb_sec {
+    KRB_SEC_NONE = 0,
+    KRB_SEC_INTEGRITY = 1,
+    KRB_SEC_ENCRYPTION = 2
+} Krb_sec_t;
+
+typedef struct context {
+    int state;
+    
+    int challenge;         /* this is the challenge (32 bit int) used 
+                             for the authentication */
+    
+    char *service;                   /* kerberos service */
+    char instance[ANAME_SZ];
+    char pname[ANAME_SZ];
+    char pinst[INST_SZ];
+    char prealm[REALM_SZ];
+    char *hostname;                  /* hostname */
+    char *realm;                     /* kerberos realm */
+    char *auth;                      /* */
+    
+    CREDENTIALS credentials;
+    
+    des_cblock key;                  /* session key */
+    des_cblock session;              /* session key */
+    
+    des_key_schedule init_keysched;  /* key schedule for initialization */
+    des_key_schedule enc_keysched;   /* encryption key schedule */
+    des_key_schedule dec_keysched;   /* decryption key schedule */
+    
+    
+    struct sockaddr_in ip_local;     /* local ip address and port.
+                                       needed for layers */
+    struct sockaddr_in ip_remote;    /* remote ip address and port.
+                                       needed for layers */
+    
+    const sasl_utils_t *utils;       /* this is useful to have around */
+    
+    Krb_sec_t sec_type;
+    char *encode_buf;                /* For encoding/decoding mem management */
+    char *decode_buf;
+    char *decode_once_buf;
+    unsigned encode_buf_len;
+    unsigned decode_buf_len;
+    unsigned decode_once_buf_len;
+    buffer_info_t *enc_in_buf;
+
+    decode_context_t decode_context;
+    
+    char *out_buf;                   /* per-step mem management */
+    unsigned out_buf_len;
+    
+    const char *user;                      /* used by client */
+    
+    int secflags; /* client/server supports layers? */
+    
+    long time_sec; /* These are used to make sure we are getting */
+    char time_5ms; /* strictly increasing timestamps */
+    
+} context_t;
+
+#define KRB_LOCK_MUTEX(utils)  \
+    if(((sasl_utils_t *)(utils))->mutex_lock(krb_mutex) != 0) { \
+       ((sasl_utils_t *)(utils))->seterror(((sasl_utils_t *)(utils))->conn, \
+                                           0, "error locking mutex"); \
+                                  return SASL_FAIL; \
+                                }
+#define KRB_UNLOCK_MUTEX(utils) \
+    if(((sasl_utils_t *)(utils))->mutex_unlock(krb_mutex) != 0) { \
+       ((sasl_utils_t *)(utils))->seterror(((sasl_utils_t *)(utils))->conn, \
+                                           0, "error unlocking mutex"); \
+                                  return SASL_FAIL; \
+                                }
+
+/* Mutex for not-thread-safe kerberos 4 library */
+static void *krb_mutex = NULL;
+static char *srvtab = NULL;
+static unsigned refcount = 0;
+
+static int kerberosv4_encode(void *context,
+                            const struct iovec *invec,
+                            unsigned numiov,
+                            const char **output,
+                            unsigned *outputlen)
+{
+    int len, ret;
+    context_t *text = (context_t *)context;
+    struct buffer_info *inblob, bufinfo;
+    
+    if(numiov > 1) {
+       ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf);
+       if(ret != SASL_OK) return ret;
+       inblob = text->enc_in_buf;
+    } else {
+       bufinfo.data = invec[0].iov_base;
+       bufinfo.curlen = invec[0].iov_len;
+       inblob = &bufinfo;
+    }
+    
+    ret = _plug_buf_alloc(text->utils, &(text->encode_buf),
+                         &text->encode_buf_len, inblob->curlen+40);
+    
+    if(ret != SASL_OK) return ret;
+    
+    KRB_LOCK_MUTEX(text->utils);
+    
+    if (text->sec_type == KRB_SEC_ENCRYPTION) {
+       /* Type incompatibility on 4th arg probably means you're
+          building against krb4 in MIT krb5, but got the OpenSSL
+          headers in your way. You need to not use openssl/des.h with
+          MIT kerberos. */
+       len=krb_mk_priv(inblob->data, (text->encode_buf+4),
+                       inblob->curlen,  text->init_keysched, 
+                       &text->session, &text->ip_local,
+                       &text->ip_remote);
+    } else if (text->sec_type == KRB_SEC_INTEGRITY) {
+       len=krb_mk_safe(inblob->data, (text->encode_buf+4),
+                       inblob->curlen,
+                       &text->session, &text->ip_local, &text->ip_remote);
+    } else {
+       len = -1;
+    }
+    
+    KRB_UNLOCK_MUTEX(text->utils);
+    
+    /* returns -1 on error */
+    if (len==-1) return SASL_FAIL;
+    
+    /* now copy in the len of the buffer in network byte order */
+    *outputlen=len+4;
+    len=htonl(len);
+    memcpy(text->encode_buf, &len, 4);
+    
+    /* Setup the const pointer */
+    *output = text->encode_buf;
+    
+    return SASL_OK;
+}
+
+static int kerberosv4_decode_packet(void *context,
+                                   const char *input, unsigned inputlen,
+                                   char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int result;
+    MSG_DAT data;
+    
+    memset(&data,0,sizeof(MSG_DAT));
+    
+    KRB_LOCK_MUTEX(text->utils);
+    
+    if (text->sec_type == KRB_SEC_ENCRYPTION) {
+       result=krb_rd_priv(input, inputlen, text->init_keysched, 
+                          &text->session, &text->ip_remote,
+                          &text->ip_local, &data);
+    } else if (text->sec_type == KRB_SEC_INTEGRITY) {
+        result = krb_rd_safe(input, inputlen,
+                            &text->session, &text->ip_remote,
+                            &text->ip_local, &data);
+    } else {
+        KRB_UNLOCK_MUTEX(text->utils);
+       text->utils->seterror(text->utils->conn, 0,
+                             "KERBEROS_4 decode called with KRB_SEC_NONE");
+       return SASL_FAIL;
+    }
+    
+    KRB_UNLOCK_MUTEX(text->utils);
+    
+    /* see if the krb library gave us a failure */
+    if (result != 0) {
+       text->utils->seterror(text->utils->conn, 0, get_krb_err_txt(result));
+       return SASL_FAIL;
+    }
+    
+    /* check to make sure the timestamps are ok */
+    if ((data.time_sec < text->time_sec) || /* if an earlier time */
+       (((data.time_sec == text->time_sec) && /* or the exact same time */
+         (data.time_5ms < text->time_5ms)))) 
+       {
+           text->utils->seterror(text->utils->conn, 0, "timestamps not ok");
+           return SASL_FAIL;
+       }
+    
+    text->time_sec = data.time_sec;
+    text->time_5ms = data.time_5ms;
+    
+    result = _plug_buf_alloc(text->utils, &text->decode_once_buf,
+                            &text->decode_once_buf_len,
+                            data.app_length + 1);
+    if(result != SASL_OK)
+       return result;
+    
+    *output = text->decode_once_buf;
+    *outputlen = data.app_length;
+    memcpy(*output, data.app_data, data.app_length);
+    (*output)[*outputlen] = '\0';
+    
+    return SASL_OK;
+}
+
+static int kerberosv4_decode(void *context,
+                            const char *input, unsigned inputlen,
+                            const char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+    
+    ret = _plug_decode(&text->decode_context, input, inputlen,
+                      &text->decode_buf, &text->decode_buf_len, outputlen,
+                      kerberosv4_decode_packet, text);
+    
+    *output = text->decode_buf;
+    
+    return ret;
+}
+
+static int new_text(const sasl_utils_t *utils, context_t **text)
+{
+    context_t *ret = (context_t *) utils->malloc(sizeof(context_t));
+
+    if (ret == NULL) {
+       MEMERROR(utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(ret, 0, sizeof(context_t));
+    
+    ret->state = 1;
+    ret->utils = utils;
+    
+    *text = ret;
+    
+    return SASL_OK;
+}
+
+static void kerberosv4_common_mech_dispose(void *conn_context,
+                                          const sasl_utils_t *utils)
+{
+    context_t *text = (context_t *)conn_context;
+    
+    if(!text) return;
+    
+    _plug_decode_free(&text->decode_context);
+    if (text->encode_buf) utils->free(text->encode_buf);
+    if (text->decode_buf) utils->free(text->decode_buf);
+    if (text->decode_once_buf) utils->free(text->decode_once_buf);
+    if (text->out_buf) utils->free(text->out_buf);
+    if (text->enc_in_buf) {
+       if(text->enc_in_buf->data) utils->free(text->enc_in_buf->data);
+       utils->free(text->enc_in_buf);
+    }
+    /* no need to free userid, it's just the interaction result */
+    
+    utils->free(text);
+}
+
+static void
+kerberosv4_common_mech_free(void *glob_context __attribute__((unused)),
+                           const sasl_utils_t *utils)
+{
+    if (krb_mutex) {
+       utils->mutex_free(krb_mutex);
+       krb_mutex = NULL; /* in case we need to re-use it */
+    }
+    refcount--;
+    if (srvtab && !refcount) {
+       utils->free(srvtab);
+       srvtab = NULL;
+    }
+}
+
+/*****************************  Server Section  *****************************/
+
+static int cando_sec(sasl_security_properties_t *props,
+                    int external_ssf,
+                    int secflag)
+{
+    int need;
+    int musthave;
+    
+    if(props->maxbufsize == 0) {
+       need = musthave = 0;
+    } else {
+       need = props->max_ssf - external_ssf;
+       musthave = props->min_ssf - external_ssf;
+    }
+
+    switch (secflag) {
+    case KRB_SECFLAG_NONE:
+       if (musthave <= 0)
+           return 1;
+       break;
+    case KRB_SECFLAG_INTEGRITY:
+       if ((musthave <= KRB_INTEGRITY_BITS)
+           && (KRB_INTEGRITY_BITS <= need))
+           return 1;
+       break;
+    case KRB_SECFLAG_ENCRYPTION:
+       if ((musthave <= KRB_DES_SECURITY_BITS)
+           && (KRB_DES_SECURITY_BITS <= need))
+           return 1;
+       break;
+    case KRB_SECFLAG_CREDENTIALS:
+       if (props->security_flags & SASL_SEC_PASS_CREDENTIALS)
+           return 1;
+       break;
+    }
+    return 0;
+}
+
+static int ipv4_ipfromstring(const sasl_utils_t *utils, const char *addr,
+                            struct sockaddr_in *out) 
+{
+    struct sockaddr_storage ss;
+    int result;
+    
+    result = _plug_ipfromstring(utils, addr,
+                               (struct sockaddr *)&ss, sizeof(ss));
+    if (result != SASL_OK) {
+       /* couldn't get local IP address */
+       return result;
+    }
+    /* Kerberos_V4 supports only IPv4 */
+    if (((struct sockaddr *)&ss)->sa_family != AF_INET)
+       return SASL_FAIL;
+    memcpy(out, &ss, sizeof(struct sockaddr_in));
+    
+    return SASL_OK;
+}
+
+#ifndef macintosh
+static int
+kerberosv4_server_mech_new(void *glob_context __attribute__((unused)),
+                          sasl_server_params_t *sparams,
+                          const char *challenge __attribute__((unused)),
+                          unsigned challen __attribute__((unused)),
+                          void **conn_context)
+{
+    return new_text(sparams->utils, (context_t **) conn_context);
+}
+
+static int kerberosv4_server_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)
+{
+    context_t *text = (context_t *) conn_context;
+    int result;
+
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    switch (text->state) {
+
+    case 1: {
+       /* random 32-bit number */
+       int randocts, nchal;
+       
+       /* shouldn't we check for erroneous client input here?!? */
+       
+       sparams->utils->rand(sparams->utils->rpool,(char *) &randocts ,
+                            sizeof(randocts));    
+       text->challenge=randocts; 
+       nchal = htonl(text->challenge);
+       
+       result = _plug_buf_alloc(text->utils, &text->out_buf,
+                                &text->out_buf_len, 5);
+       if (result != SASL_OK) return result;
+       
+       memcpy(text->out_buf,&nchal,4);
+       *serverout = text->out_buf;
+       *serveroutlen = 4;
+       
+       text->state = 2;
+
+       return SASL_CONTINUE;
+    }
+    
+    case 2: {
+       int nchal;
+       unsigned char sout[8];  
+       AUTH_DAT ad;
+       KTEXT_ST ticket;
+       unsigned lup;
+       struct sockaddr_in addr;
+       char *dot;
+       
+       /* received authenticator */
+       
+       /* create ticket */
+       if (clientinlen > MAX_KTXT_LEN) {
+           text->utils->seterror(text->utils->conn,0,
+                                 "request larger than maximum ticket size");
+           return SASL_FAIL;
+       }
+       
+       ticket.length=clientinlen;
+       for (lup = 0; lup < clientinlen; lup++)      
+           ticket.dat[lup] = clientin[lup];
+       
+       KRB_LOCK_MUTEX(sparams->utils);
+       
+       text->realm = krb_realmofhost(sparams->serverFQDN);
+       
+       /* get instance */
+       strncpy (text->instance, krb_get_phost (sparams->serverFQDN),
+                sizeof (text->instance));
+       
+       KRB_UNLOCK_MUTEX(sparams->utils);
+       
+       text->instance[sizeof(text->instance)-1] = 0;
+
+       /* At some sites, krb_get_phost() sensibly but
+        * atypically returns FQDNs, versus the first component,
+        * which is what we need for RFC2222 section 7.1
+        */
+       dot = strchr(text->instance, '.');
+       if (dot) *dot = '\0';
+
+       memset(&addr, 0, sizeof(struct sockaddr_in));
+       
+#ifndef KRB4_IGNORE_IP_ADDRESS
+       /* (we ignore IP addresses in krb4 tickets at CMU to facilitate moving
+          from machine to machine) */
+       
+       /* get ip number in addr*/
+       result = ipv4_ipfromstring(sparams->utils, sparams->ipremoteport, &addr);
+       if (result != SASL_OK || !sparams->ipremoteport) {
+           SETERROR(text->utils, "couldn't get remote IP address");
+           return result;
+       }
+#endif
+       
+       /* check ticket */
+       
+       KRB_LOCK_MUTEX(sparams->utils);
+       result = krb_rd_req(&ticket, (char *) sparams->service, text->instance, 
+                           addr.sin_addr.s_addr, &ad, srvtab);
+       KRB_UNLOCK_MUTEX(sparams->utils);
+       
+       if (result) { /* if fails mechanism fails */
+           text->utils->seterror(text->utils->conn,0,
+                                 "krb_rd_req failed service=%s instance=%s error code=%s (%i)",
+                                 sparams->service, text->instance,get_krb_err_txt(result),result);
+           return SASL_BADAUTH;
+       }
+       
+       /* 8 octets of data
+        * 1-4 checksum+1
+        * 5 security layers
+        * 6-8max cipher text buffer size
+        * use DES ECB in the session key
+        */
+       
+       nchal=htonl(text->challenge+1);
+       memcpy(sout, &nchal, 4);
+       sout[4]= 0;
+       if (cando_sec(&sparams->props, sparams->external_ssf,
+                     KRB_SECFLAG_NONE))
+           sout[4] |= KRB_SECFLAG_NONE;
+       if (cando_sec(&sparams->props, sparams->external_ssf,
+                     KRB_SECFLAG_INTEGRITY))
+           sout[4] |= KRB_SECFLAG_INTEGRITY;
+       if (cando_sec(&sparams->props, sparams->external_ssf,
+                     KRB_SECFLAG_ENCRYPTION))
+           sout[4] |= KRB_SECFLAG_ENCRYPTION;
+       if (cando_sec(&sparams->props, sparams->external_ssf,
+                     KRB_SECFLAG_CREDENTIALS))
+           sout[4] |= KRB_SECFLAG_CREDENTIALS;
+
+       if(sparams->props.maxbufsize) {
+           int tmpmaxbuf = (sparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : sparams->props.maxbufsize;
+
+           sout[5]=((tmpmaxbuf >> 16) & 0xFF);
+           sout[6]=((tmpmaxbuf >> 8) & 0xFF);
+           sout[7]=(tmpmaxbuf & 0xFF);
+       } else {
+            /* let's say we can support up to 64K */
+           /* no inherent inability with our layers to support more */
+
+           sout[5]=0x00;  /* max ciphertext buffer size */
+           sout[6]=0xFF;
+           sout[7]=0xFF;
+       }
+    
+       memcpy(text->session, ad.session, 8);
+       memcpy(text->pname, ad.pname, sizeof(text->pname));
+       memcpy(text->pinst, ad.pinst, sizeof(text->pinst));
+       memcpy(text->prealm, ad.prealm, sizeof(text->prealm));
+       des_key_sched(&ad.session, text->init_keysched);
+       
+       /* make keyschedule for encryption and decryption */
+       des_key_sched(&ad.session, text->enc_keysched);
+       des_key_sched(&ad.session, text->dec_keysched);
+       
+       des_ecb_encrypt((des_cblock *)sout,
+                       (des_cblock *)sout,
+                       text->init_keysched,
+                       DES_ENCRYPT);
+       
+       result = _plug_buf_alloc(text->utils, &text->out_buf,
+                                &text->out_buf_len, 9);
+       if(result != SASL_OK)
+           return result;
+       
+       memcpy(text->out_buf,&sout,8);
+       *serverout = text->out_buf;
+       *serveroutlen = 8;
+       
+       text->state = 3;
+
+       return SASL_CONTINUE;
+    }
+    
+    case 3: {
+       int result;
+       int testnum;
+       int flag;
+       unsigned char *in;
+       
+       if ((clientinlen == 0) || (clientinlen % 8 != 0)) {
+           text->utils->seterror(text->utils->conn,0,
+                                 "Response to challengs is not a multiple of 8 octets (a DES block)");
+           return SASL_FAIL;   
+       }
+       
+       /* we need to make a copy because des does in place decrpytion */
+       in = sparams->utils->malloc(clientinlen + 1);
+       if (in == NULL) {
+           MEMERROR(sparams->utils);
+           return SASL_NOMEM;
+       }
+       
+       memcpy(in, clientin, clientinlen);
+       in[clientinlen] = '\0';
+       
+       /* decrypt; verify checksum */
+       
+       des_pcbc_encrypt((des_cblock *)in,
+                        (des_cblock *)in,
+                        clientinlen,
+                        text->init_keysched,
+                        &text->session,
+                        DES_DECRYPT);
+       
+       testnum = (in[0]*256*256*256)+(in[1]*256*256)+(in[2]*256)+in[3];
+       
+       if (testnum != text->challenge) {
+           SETERROR(sparams->utils, "incorrect response to challenge");
+           return SASL_BADAUTH;
+       }
+       
+       if (!cando_sec(&sparams->props, sparams->external_ssf,
+                      in[4] & KRB_SECFLAGS)) {
+           SETERROR(sparams->utils,
+                    "invalid security property specified");
+           return SASL_BADPROT;
+       }
+       
+       oparams->encode = &kerberosv4_encode;
+       oparams->decode = &kerberosv4_decode;
+       
+       switch (in[4] & KRB_SECFLAGS) {
+       case KRB_SECFLAG_NONE:
+           text->sec_type = KRB_SEC_NONE;
+           oparams->encode = NULL;
+           oparams->decode = NULL;
+           oparams->mech_ssf = 0;
+           break;
+       case KRB_SECFLAG_INTEGRITY:
+           text->sec_type = KRB_SEC_INTEGRITY;
+           oparams->mech_ssf = KRB_INTEGRITY_BITS;
+           break;
+       case KRB_SECFLAG_ENCRYPTION:
+           text->sec_type = KRB_SEC_ENCRYPTION;
+           oparams->mech_ssf = KRB_DES_SECURITY_BITS;
+           break;
+       default:
+           /* Mark that we tried */
+           oparams->mech_ssf = 2;
+           SETERROR(sparams->utils, "not a supported encryption layer");
+           return SASL_BADPROT;
+       }
+       
+       /* get ip data */
+       /* get ip number in addr*/
+       result = ipv4_ipfromstring(sparams->utils,
+                                  sparams->iplocalport, &(text->ip_local));
+       if (result != SASL_OK) {
+           SETERROR(sparams->utils, "couldn't get local ip address");
+           /* couldn't get local IP address */
+           return result;
+       }
+       
+       result = ipv4_ipfromstring(sparams->utils,
+                                  sparams->ipremoteport, &(text->ip_remote));
+       if (result != SASL_OK) {
+           SETERROR(sparams->utils, "couldn't get remote ip address");
+           /* couldn't get remote IP address */
+           return result;
+       }
+       
+       /* fill in oparams */
+       oparams->maxoutbuf = (in[5] << 16) + (in[6] << 8) + in[7];
+       if(oparams->mech_ssf) {
+           /* FIXME: Likely to be too large */
+           oparams->maxoutbuf -= 50;
+       }
+       
+       if (sparams->canon_user) {
+           char *user=NULL, *authid=NULL;
+           size_t ulen = 0, alen = strlen(text->pname);
+           int ret, cflag = SASL_CU_AUTHID;
+           
+           if (text->pinst[0]) {
+               alen += strlen(text->pinst) + 1 /* for the . */;
+           }
+           flag = 0;
+           if (strcmp(text->realm, text->prealm)) {
+               alen += strlen(text->prealm) + 1 /* for the @ */;
+               flag = 1;
+           }
+           
+           authid = sparams->utils->malloc(alen + 1);
+           if (!authid) {
+               MEMERROR(sparams->utils);
+               return SASL_NOMEM;
+           }
+           
+           strcpy(authid, text->pname);
+           if (text->pinst[0]) {
+               strcat(authid, ".");
+               strcat(authid, text->pinst);
+           }
+           if (flag) {
+               strcat(authid, "@");
+               strcat(authid, text->prealm);
+           }
+           
+           if (in[8]) {
+               user = sparams->utils->malloc(strlen((char *) in + 8) + 1);
+               if (!user) {
+                   MEMERROR(sparams->utils);
+                   return SASL_NOMEM;
+               }
+               
+               strcpy(user, (char *) in + 8);
+               ulen = strlen(user);
+           } else {
+               cflag |= SASL_CU_AUTHZID;
+           }
+           
+           ret = sparams->canon_user(sparams->utils->conn, authid, alen,
+                                     cflag, oparams);
+           sparams->utils->free(authid);
+           if (ret != SASL_OK) {
+               if (user)
+                   sparams->utils->free(user);
+               return ret;
+           }
+           
+           if (user) {
+               ret = sparams->canon_user(sparams->utils->conn, user, ulen,
+                                     SASL_CU_AUTHZID, oparams);
+           
+               sparams->utils->free(user);
+           }
+           
+           if (ret != SASL_OK) return ret;
+       }
+       
+       /* nothing more to do; authenticated */
+       oparams->doneflag = 1;
+       oparams->param_version = 0;
+       
+       /* used by layers */
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (sparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         sparams->props.maxbufsize);
+       
+       sparams->utils->free(in);
+
+       return SASL_OK;
+    }
+    
+    default:
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "Invalid Kerberos server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static int kerberosv4_mech_avail(void *glob_context __attribute__((unused)),
+                                sasl_server_params_t *sparams,
+                                void **conn_context __attribute__((unused))) 
+{
+    struct sockaddr_in addr;
+    
+    if (!sparams->iplocalport || !sparams->ipremoteport
+       || ipv4_ipfromstring(sparams->utils,
+                            sparams->iplocalport, &addr) != SASL_OK
+       || ipv4_ipfromstring(sparams->utils,
+                            sparams->ipremoteport, &addr) != SASL_OK) {
+       SETERROR(sparams->utils,
+                "KERBEROS_V4 unavailable due to lack of IPv4 information");
+       return SASL_NOMECH;
+    }
+    
+    return SASL_OK;
+}
+
+
+static sasl_server_plug_t kerberosv4_server_plugins[] = 
+{
+    {
+       "KERBEROS_V4",                  /* mech_name */
+       KRB_DES_SECURITY_BITS,          /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_SERVER_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &kerberosv4_server_mech_new,    /* mech_new */
+       &kerberosv4_server_mech_step,   /* mech_step */
+       &kerberosv4_common_mech_dispose,/* mech_dispose */
+       &kerberosv4_common_mech_free,   /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       &kerberosv4_mech_avail,         /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+#endif /* macintosh */
+
+int kerberos4_server_plug_init(const sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_server_plug_t **pluglist,
+                              int *plugcount)
+{
+#ifdef macintosh
+    return SASL_BADVERS;
+#else
+    const char *ret;
+    unsigned int rl;
+    
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       return SASL_BADVERS;
+    }
+    
+    
+    if (!krb_mutex) {
+       krb_mutex = utils->mutex_alloc();
+       if(!krb_mutex) {
+           return SASL_FAIL;
+       }
+    }
+    
+    if (!srvtab) {     
+       utils->getopt(utils->getopt_context,
+                     "KERBEROS_V4", "srvtab", &ret, &rl);
+       
+       if (ret == NULL) {
+           ret = KEYFILE;
+           rl = strlen(ret);
+       }
+       
+       srvtab = utils->malloc(sizeof(char) * (rl + 1));
+       if(!srvtab) {
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+       
+       strcpy(srvtab, ret);
+    }
+    
+    refcount++;
+    
+    /* fail if we can't open the srvtab file */
+    if (access(srvtab, R_OK) != 0) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "can't access srvtab file %s: %m", srvtab, errno);
+       if(!(--refcount)) {
+           utils->free(srvtab);
+           srvtab=NULL;
+       }
+       return SASL_FAIL;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = kerberosv4_server_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+#endif
+}
+
+/*****************************  Client Section  *****************************/
+
+static int
+kerberosv4_client_mech_new(void *glob_context __attribute__((unused)), 
+                          sasl_client_params_t *params,
+                          void **conn_context)
+{
+    return new_text(params->utils, (context_t **) conn_context);
+}
+
+static int kerberosv4_client_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)
+{
+    context_t *text = (context_t *) conn_context;
+    KTEXT_ST authent;
+    int ret;
+
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    authent.length = MAX_KTXT_LEN;
+    
+    switch (text->state) {
+
+    case 1: {
+       /* We should've just recieved a 32-bit number in network byte order.
+        * We want to reply with an authenticator. */
+       int result;
+       KTEXT_ST ticket;
+       char *dot;
+       
+       memset(&ticket, 0L, sizeof(ticket));
+       ticket.length = MAX_KTXT_LEN;   
+       
+       if (serverinlen != 4) {
+           text->utils->seterror(text->utils->conn, 0,
+                                 "server challenge not 4 bytes long");
+           return SASL_BADPROT; 
+       }
+       
+       memcpy(&text->challenge, serverin, 4);
+       
+       text->challenge=ntohl(text->challenge); 
+       
+       if (cparams->serverFQDN == NULL) {
+           cparams->utils->log(NULL, SASL_LOG_ERR,
+                               "no 'serverFQDN' set");
+           SETERROR(text->utils, "paramater error");
+           return SASL_BADPARAM;
+       }
+       if (cparams->service == NULL) {
+           cparams->utils->log(NULL, SASL_LOG_ERR,
+                               "no 'service' set");
+           SETERROR(text->utils, "paramater error");
+           return SASL_BADPARAM;
+       }
+       
+       KRB_LOCK_MUTEX(cparams->utils);
+       text->realm=krb_realmofhost(cparams->serverFQDN);
+       text->hostname=(char *) cparams->serverFQDN;
+       
+       /* the instance of the principal we're authenticating with */
+       strncpy (text->instance, krb_get_phost (cparams->serverFQDN), 
+                sizeof (text->instance));
+       
+       /* text->instance is NULL terminated unless it was too long */
+       text->instance[sizeof(text->instance)-1] = '\0';
+
+       /* At some sites, krb_get_phost() sensibly but
+        * atypically returns FQDNs, versus the first component,
+        * which is what we need for RFC2222 section 7.1
+        */
+       dot = strchr(text->instance, '.');
+       if (dot) *dot = '\0';
+       
+#ifndef macintosh
+       if ((result = krb_mk_req(&ticket, (char *) cparams->service, 
+                                text->instance, text->realm, text->challenge)))
+#else
+           memset(&text->credentials,0,sizeof(text->credentials));
+       if (kcglue_krb_mk_req(ticket.dat,
+                             &ticket.length,
+                             cparams->service,
+                             text->instance,
+                             text->realm,
+                             text->challenge,
+                             &text->credentials.session,
+                             text->credentials.pname,
+                             text->credentials.pinst) != 0)
+#endif
+           {
+               KRB_UNLOCK_MUTEX(cparams->utils);
+               
+               text->utils->seterror(text->utils->conn,SASL_NOLOG,
+                                     "krb_mk_req() failed");
+               
+               cparams->utils->log(NULL, SASL_LOG_ERR, 
+                                   "krb_mk_req() failed: %s (%d)",
+                                   get_krb_err_txt(result), result);
+               return SASL_FAIL;
+           }
+       
+       KRB_UNLOCK_MUTEX(cparams->utils);
+       
+       ret = _plug_buf_alloc(text->utils, &(text->out_buf),
+                             &(text->out_buf_len), ticket.length);
+       if (ret != SASL_OK) return ret;
+       
+       memcpy(text->out_buf, ticket.dat, ticket.length);
+       
+       *clientout = text->out_buf;
+       *clientoutlen = ticket.length;
+       
+       text->state = 2;
+
+       return SASL_CONTINUE;
+    }
+    
+    /* challenge #2 */
+    case 2: {
+       int need = 0;
+       int musthave = 0;
+       int testnum;
+       int nchal;    
+       unsigned char *sout = NULL;
+       unsigned len;
+       unsigned char in[8];
+       int result;
+       int servermaxbuf;
+       char *buf;
+       int user_result = SASL_OK;
+       
+       /* try to get the authid */
+       if (text->user == NULL) {
+           user_result = _plug_get_userid(cparams->utils, &text->user,
+                                          prompt_need);
+           
+           if (user_result != SASL_OK && user_result != SASL_INTERACT)
+               return user_result;
+       }
+       
+       /* free prompts we got */
+       if (prompt_need && *prompt_need) {
+           cparams->utils->free(*prompt_need);
+           *prompt_need = NULL;
+       }
+       
+       /* if there are prompts not filled in */
+       if (user_result == SASL_INTERACT) {
+           /* make the prompt list */
+           int result =
+               _plug_make_prompts(cparams->utils, prompt_need,
+                                  user_result == SASL_INTERACT ?
+                                  "Please enter your authorization name" : NULL, NULL,
+                                  NULL, NULL,
+                                  NULL, NULL,
+                                  NULL, NULL, NULL,
+                                  NULL, NULL, NULL);
+           if (result!=SASL_OK) return result;
+           
+           return SASL_INTERACT;
+       }
+       
+       /* must be 8 octets */
+       if (serverinlen!=8) {
+           SETERROR(cparams->utils,
+                    "server response not 8 bytes long");
+           return SASL_BADAUTH;
+       }
+       
+       memcpy(in, serverin, 8);
+       
+#ifndef macintosh
+       /* get credentials */
+       KRB_LOCK_MUTEX(cparams->utils);
+       result = krb_get_cred((char *)cparams->service,
+                             text->instance,
+                             text->realm,
+                             &text->credentials);
+       KRB_UNLOCK_MUTEX(cparams->utils);
+       
+       if(result != 0) {
+           cparams->utils->log(NULL, SASL_LOG_ERR,
+                               "krb_get_cred() failed: %s (%d)",
+                               get_krb_err_txt(result), result);
+           SETERROR(cparams->utils, "krb_get_cred() failed");
+           return SASL_BADAUTH;
+       }
+#endif
+       memcpy(text->session, text->credentials.session, 8);
+       
+       /* make key schedule for encryption and decryption */
+       des_key_sched(&text->session, text->init_keysched);
+       des_key_sched(&text->session, text->enc_keysched);
+       des_key_sched(&text->session, text->dec_keysched);
+       
+       /* decrypt from server */
+       des_ecb_encrypt((des_cblock *)in, (des_cblock *)in,
+                       text->init_keysched, DES_DECRYPT);
+       
+       /* convert to 32bit int */
+       testnum = (in[0]*256*256*256)+(in[1]*256*256)+(in[2]*256)+in[3];
+       
+       /* verify data 1st 4 octets must be equal to chal+1 */
+       if (testnum != text->challenge+1) {
+           SETERROR(cparams->utils,"server response incorrect");
+           return SASL_BADAUTH;
+       }
+       
+       /* construct 8 octets
+        * 1-4 - original checksum
+        * 5 - bitmask of sec layer
+        * 6-8 max buffer size
+        */
+       if (cparams->props.min_ssf > 
+           KRB_DES_SECURITY_BITS + cparams->external_ssf) {
+           SETERROR(cparams->utils,
+                    "minimum ssf too strong for this mechanism");
+           return SASL_TOOWEAK;
+       } else if (cparams->props.min_ssf > cparams->props.max_ssf) {
+           SETERROR(cparams->utils,
+                    "minimum ssf larger than maximum ssf");
+           return SASL_BADPARAM;
+       }
+       
+       /* create stuff to send to server */
+       sout = (char *)
+           cparams->utils->malloc(9+(text->user ? strlen(text->user) : 0)+9);
+       if (!sout) {
+           MEMERROR(cparams->utils);
+           return SASL_NOMEM;
+       }
+       
+       nchal = htonl(text->challenge);
+       memcpy(sout, &nchal, 4);
+       
+       /* need bits of layer */
+       if(cparams->props.maxbufsize == 0) {
+           need = musthave = 0;
+       } else {
+           need = cparams->props.max_ssf - cparams->external_ssf;
+           musthave = cparams->props.min_ssf - cparams->external_ssf;
+       }
+       
+       oparams->decode = &kerberosv4_decode;
+       oparams->encode = &kerberosv4_encode;
+       
+       if ((in[4] & KRB_SECFLAG_ENCRYPTION)
+           && (need>=56) && (musthave <= 56)) {
+           /* encryption */
+           text->sec_type = KRB_SEC_ENCRYPTION;
+           oparams->mech_ssf = 56;
+           sout[4] = KRB_SECFLAG_ENCRYPTION;
+           /* using encryption layer */
+       } else if ((in[4] & KRB_SECFLAG_INTEGRITY)
+                  && (need >= 1) && (musthave <= 1)) {
+           /* integrity */
+           text->sec_type = KRB_SEC_INTEGRITY;
+           oparams->mech_ssf=1;
+           sout[4] = KRB_SECFLAG_INTEGRITY;
+           /* using integrity layer */
+       } else if ((in[4] & KRB_SECFLAG_NONE) && (musthave <= 0)) {
+           /* no layer */
+           text->sec_type = KRB_SEC_NONE;
+           oparams->encode=NULL;
+           oparams->decode=NULL;
+           oparams->mech_ssf=0;
+           sout[4] = KRB_SECFLAG_NONE;
+       } else {
+           /* Mark that we tried */
+           oparams->mech_ssf=2;
+           SETERROR(cparams->utils,
+                    "unable to agree on layers with server");
+           return SASL_BADPROT;
+       }
+       
+       servermaxbuf = in[5]*256*256+in[6]*256+in[7];
+       oparams->maxoutbuf = servermaxbuf;
+       if (oparams->mech_ssf) {
+           /* FIXME: Likely to be too large */
+           oparams->maxoutbuf -= 50;
+       }
+       
+       if(cparams->props.maxbufsize) {
+           int tmpmaxbuf = ( cparams->props.maxbufsize > 0xFFFFFF ) ? 0xFFFFFF : cparams->props.maxbufsize;
+
+           sout[5]=((tmpmaxbuf >> 16) & 0xFF);
+           sout[6]=((tmpmaxbuf >> 8) & 0xFF);
+           sout[7]=(tmpmaxbuf & 0xFF);
+       } else {
+            /* let's say we can support up to 64K */
+           /* no inherent inability with our layers to support more */
+
+           sout[5]=0x00;  /* max ciphertext buffer size */
+           sout[6]=0xFF;
+           sout[7]=0xFF;
+       }
+       
+       sout[8] = 0x00; /* just to be safe */
+       
+       /* append userid */
+       len = 9;                        /* 8 + trailing NULL */
+       if (text->user) {
+           strcpy((char *)sout + 8, text->user);
+           len += strlen(text->user);
+       }
+       
+       /* append 0 based octets so is multiple of 8 */
+       while(len % 8) {
+           sout[len]=0;
+           len++;
+       }
+       sout[len]=0;
+       
+       des_pcbc_encrypt((des_cblock *)sout,
+                        (des_cblock *)sout,
+                        len,
+                        text->init_keysched,
+                        (des_cblock *)text->session,
+                        DES_ENCRYPT);
+       
+       result = _plug_buf_alloc(text->utils, &text->out_buf,
+                                &text->out_buf_len, len);
+       if (result != SASL_OK)  return result;
+       
+       memcpy(text->out_buf, sout, len);
+       
+       *clientout = text->out_buf;
+       *clientoutlen = len;
+       
+       /* nothing more to do; should be authenticated */
+       if(cparams->iplocalport) {   
+           result = ipv4_ipfromstring(cparams->utils,
+                                      cparams->iplocalport,
+                                      &(text->ip_local));
+           if (result != SASL_OK) {
+               /* couldn't get local IP address */
+               return result;
+           }
+       }
+       
+       if (cparams->ipremoteport) {
+           result = ipv4_ipfromstring(cparams->utils,
+                                      cparams->ipremoteport,
+                                      &(text->ip_remote));
+           if (result != SASL_OK) {
+               /* couldn't get local IP address */
+               return result;
+           }
+       }
+       
+       buf = cparams->utils->malloc(strlen(text->credentials.pname)
+                                    + strlen(text->credentials.pinst)
+                                    + 2);
+       if (!buf) {
+           MEMERROR(cparams->utils);
+           return SASL_NOMEM;
+       }
+       strcpy(buf, text->credentials.pname);
+       if (text->credentials.pinst[0]) {
+           strcat(buf, ".");
+           strcat(buf, text->credentials.pinst);
+       }
+       
+       if (text->user && !text->user[0]) {
+           text->user = NULL;
+       }
+       
+       ret = cparams->canon_user(cparams->utils->conn, buf, 0,
+                                 SASL_CU_AUTHID, oparams);
+       if (ret != SASL_OK) {
+           cparams->utils->free(buf);
+           cparams->utils->free(sout);
+           return ret;
+       }
+       
+       if (!text->user) {
+           /* 0 in length fields means use strlen() */
+           ret = cparams->canon_user(cparams->utils->conn, buf, 0,
+                                     SASL_CU_AUTHZID, oparams);
+       } else {
+           ret = cparams->canon_user(cparams->utils->conn, text->user, 0,
+                                     SASL_CU_AUTHZID, oparams);
+       }
+       
+       cparams->utils->free(buf);
+       
+       oparams->doneflag = 1;
+       oparams->param_version = 0;
+       
+       /* used by layers */
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (cparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         cparams->props.maxbufsize);
+       
+       if (sout) cparams->utils->free(sout);
+       
+       return SASL_OK;
+    }
+    
+    default:
+       cparams->utils->log(NULL, SASL_LOG_ERR,
+                           "Invalid Kerberos client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+
+    return SASL_FAIL; /* should never get here */
+}
+
+static const long kerberosv4_required_prompts[] = {
+    SASL_CB_LIST_END
+};
+
+static sasl_client_plug_t kerberosv4_client_plugins[] = 
+{
+    {
+       "KERBEROS_V4",                  /* mech_name */
+       KRB_DES_SECURITY_BITS,          /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_NEEDSERVERFQDN
+       | SASL_FEAT_SERVER_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       kerberosv4_required_prompts,    /* required_prompts */
+       NULL,                           /* glob_context */
+       &kerberosv4_client_mech_new,    /* mech_new */
+       &kerberosv4_client_mech_step,   /* mech_step */
+       &kerberosv4_common_mech_dispose,/* mech_dispose */
+       &kerberosv4_common_mech_free,   /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int kerberos4_client_plug_init(const sasl_utils_t *utils,
+                              int maxversion,
+                              int *out_version,
+                              sasl_client_plug_t **pluglist,
+                              int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "Wrong KERBEROS_V4 version");
+       return SASL_BADVERS;
+    }
+    
+    if(!krb_mutex) {
+       krb_mutex = utils->mutex_alloc();
+       if(!krb_mutex) {
+           return SASL_FAIL;
+       }
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = kerberosv4_client_plugins;
+    *plugcount = 1;
+    
+    refcount++;
+    
+    return SASL_OK;
+}
diff --git a/plugins/kerberos4_init.c b/plugins/kerberos4_init.c
new file mode 100644 (file)
index 0000000..1058033
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_kerberos4_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( kerberos4 )
+SASL_SERVER_PLUG_INIT( kerberos4 )
+
diff --git a/plugins/ldapdb.c b/plugins/ldapdb.c
new file mode 100644 (file)
index 0000000..1c8929f
--- /dev/null
@@ -0,0 +1,334 @@
+/* $OpenLDAP: pkg/ldap/contrib/ldapsasl/ldapdb.c,v 1.1.2.7 2003/11/29 22:10:03 hyc Exp $ */
+/* SASL LDAP auxprop implementation
+ * Copyright (C) 2002,2003 Howard Chu, All rights reserved. <hyc@symas.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "sasl.h"
+#include "saslutil.h"
+#include "saslplug.h"
+
+#include "plugin_common.h"
+
+#include <ldap.h>
+
+static char ldapdb[] = "ldapdb";
+
+typedef struct ldapctx {
+       const char *uri;        /* URI of LDAP server */
+       struct berval id;       /* SASL authcid to bind as */
+       struct berval pw;       /* password for bind */
+       struct berval mech;     /* SASL mech */
+       int use_tls;            /* Issue StartTLS request? */
+} ldapctx;
+
+static int ldapdb_interact(LDAP *ld, unsigned flags __attribute__((unused)),
+       void *def, void *inter)
+{
+       sasl_interact_t *in = inter;
+       ldapctx *ctx = def;
+       struct berval p;
+
+       for (;in->id != SASL_CB_LIST_END;in++)
+       {
+               p.bv_val = NULL;
+               switch(in->id)
+               {
+                       case SASL_CB_GETREALM:
+                               ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &p.bv_val);
+                               if (p.bv_val) p.bv_len = strlen(p.bv_val);
+                               break;          
+                       case SASL_CB_AUTHNAME:
+                               p = ctx->id;
+                               break;
+                       case SASL_CB_PASS:
+                               p = ctx->pw;
+                               break;
+               }
+               if (p.bv_val)
+               {
+                       in->result = p.bv_val;
+                       in->len = p.bv_len;
+               }
+       }
+       return LDAP_SUCCESS;
+}
+
+typedef struct connparm {
+       LDAP *ld;
+       LDAPControl c;
+       LDAPControl *ctrl[2];
+       struct berval *dn;
+} connparm;
+
+static int ldapdb_connect(ldapctx *ctx, sasl_server_params_t *sparams,
+       const char *user, unsigned ulen, connparm *cp)
+{
+    int i;
+    char *authzid;
+
+    if((i=ldap_initialize(&cp->ld, ctx->uri))) {
+       return i;
+    }
+
+    authzid = sparams->utils->malloc(ulen + sizeof("u:"));
+    if (!authzid) {
+       return LDAP_NO_MEMORY;
+    } 
+    strcpy(authzid, "u:");
+    strcpy(authzid+2, user);
+    cp->c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
+    cp->c.ldctl_value.bv_val = authzid;
+    cp->c.ldctl_value.bv_len = ulen + 2;
+    cp->c.ldctl_iscritical = 1;
+
+    i = LDAP_VERSION3;
+    ldap_set_option(cp->ld, LDAP_OPT_PROTOCOL_VERSION, &i);
+
+    /* If TLS is set and it fails, continue or bail out as requested */
+    if (ctx->use_tls && (i=ldap_start_tls_s(cp->ld, NULL, NULL)) != LDAP_SUCCESS
+       && ctx->use_tls > 1) {
+       sparams->utils->free(authzid);
+       return i;
+    }
+
+    i = ldap_sasl_interactive_bind_s(cp->ld, NULL, ctx->mech.bv_val, NULL,
+       NULL, LDAP_SASL_QUIET, ldapdb_interact, ctx);
+    if (i != LDAP_SUCCESS) {
+       sparams->utils->free(authzid);
+       return i;
+    }
+    
+    cp->ctrl[0] = &cp->c;
+    cp->ctrl[1] = NULL;
+    i = ldap_whoami_s(cp->ld, &cp->dn, cp->ctrl, NULL);
+    if (i == LDAP_SUCCESS && cp->dn) {
+       if (!cp->dn->bv_val || strncmp(cp->dn->bv_val, "dn:", 3)) {
+           ber_bvfree(cp->dn);
+           cp->dn = NULL;
+           i = LDAP_INVALID_SYNTAX;
+       } else {
+           cp->c.ldctl_value = *(cp->dn);
+       }
+    }
+    sparams->utils->free(authzid);
+    return i;
+}
+
+static void ldapdb_auxprop_lookup(void *glob_context,
+                                 sasl_server_params_t *sparams,
+                                 unsigned flags,
+                                 const char *user,
+                                 unsigned ulen)
+{
+    ldapctx *ctx = glob_context;
+    connparm cp;
+    int ret, i, n, *aindx;
+    const struct propval *pr;
+    struct berval **bvals;
+    LDAPMessage *msg, *res;
+    char **attrs = NULL;
+    
+    if(!ctx || !sparams || !user) return;
+
+    pr = sparams->utils->prop_get(sparams->propctx);
+    if(!pr) return;
+
+    /* count how many attrs to fetch */
+    for(i = 0, n = 0; pr[i].name; i++) {
+       if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID))
+           continue;
+       if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE))
+           continue;
+       n++;
+    }
+    /* nothing to do, bail out */
+    if (!n) return;
+
+    /* alloc an array of attr names for search, and index to the props */
+    attrs = sparams->utils->malloc((n+1)*sizeof(char *)*2);
+    if (!attrs) return;
+
+    aindx = (int *)(attrs + n + 1);
+
+    /* copy attr list */
+    for (i=0, n=0; pr[i].name; i++) {
+       if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID))
+           continue;
+       if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE))
+           continue;
+       attrs[n] = (char *)pr[i].name;
+       if (pr[i].name[0] == '*') attrs[n]++;
+       aindx[n] = i;
+       n++;
+    }
+    attrs[n] = NULL;
+
+    if(ldapdb_connect(ctx, sparams, user, ulen, &cp)) {
+       goto done;
+    }
+
+    ret = ldap_search_ext_s(cp.ld, cp.dn->bv_val+3, LDAP_SCOPE_BASE,
+       "(objectclass=*)", attrs, 0, cp.ctrl, NULL, NULL, 1, &res);
+    ber_bvfree(cp.dn);
+
+    if (ret != LDAP_SUCCESS) goto done;
+
+    for(msg=ldap_first_message(cp.ld, res); msg; msg=ldap_next_message(cp.ld, msg))
+    {
+       if (ldap_msgtype(msg) != LDAP_RES_SEARCH_ENTRY) continue;
+       for (i=0; i<n; i++)
+       {
+           bvals = ldap_get_values_len(cp.ld, msg, attrs[i]);
+           if (!bvals) continue;
+           if (pr[aindx[i]].values)
+               sparams->utils->prop_erase(sparams->propctx, pr[aindx[i]].name);
+           sparams->utils->prop_set(sparams->propctx, pr[aindx[i]].name,
+                                bvals[0]->bv_val, bvals[0]->bv_len);
+           ber_bvecfree(bvals);
+       }
+    }
+    ldap_msgfree(res);
+
+ done:
+    if(attrs) sparams->utils->free(attrs);
+    if(cp.ld) ldap_unbind(cp.ld);
+}
+
+static int ldapdb_auxprop_store(void *glob_context,
+                                 sasl_server_params_t *sparams,
+                                 struct propctx *prctx,
+                                 const char *user,
+                                 unsigned ulen)
+{
+    ldapctx *ctx = glob_context;
+    connparm cp;
+    const struct propval *pr;
+    int i, n;
+    LDAPMod **mods;
+
+    /* just checking if we are enabled */
+    if (!prctx) return SASL_OK;
+
+    if (!sparams || !user) return SASL_BADPARAM;
+
+    pr = sparams->utils->prop_get(prctx);
+    if (!pr) return SASL_BADPARAM;
+
+    for (n=0; pr[n].name; n++);
+    if (!n) return SASL_BADPARAM;
+
+    mods = sparams->utils->malloc((n+1) * sizeof(LDAPMod*) + n * sizeof(LDAPMod));
+    if (!mods) return SASL_NOMEM;
+
+    if((i=ldapdb_connect(ctx, sparams, user, ulen, &cp)) == 0) {
+
+       for (i=0; i<n; i++) {
+           mods[i] = (LDAPMod *)((char *)(mods+n+1) + i * sizeof(LDAPMod));
+           mods[i]->mod_op = LDAP_MOD_REPLACE;
+           mods[i]->mod_type = (char *)pr[i].name;
+           mods[i]->mod_values = (char **)pr[i].values;
+       }
+       mods[i] = NULL;
+
+       i = ldap_modify_ext_s(cp.ld, cp.dn->bv_val+3, mods, cp.ctrl, NULL);
+       ber_bvfree(cp.dn);
+    }
+
+    sparams->utils->free(mods);
+
+    if (i) {
+       sparams->utils->seterror(sparams->utils->conn, 0,
+           ldap_err2string(i));
+       if (i == LDAP_NO_MEMORY) i = SASL_NOMEM;
+       else i = SASL_FAIL;
+    }
+    if (cp.ld) ldap_unbind(cp.ld);
+    return i;
+}
+
+static void ldapdb_auxprop_free(void *glob_ctx, const sasl_utils_t *utils)
+{
+       utils->free(glob_ctx);
+}
+
+static sasl_auxprop_plug_t ldapdb_auxprop_plugin = {
+    0,                         /* Features */
+    0,                         /* spare */
+    NULL,                      /* glob_context */
+    ldapdb_auxprop_free,       /* auxprop_free */
+    ldapdb_auxprop_lookup,     /* auxprop_lookup */
+    ldapdb,                    /* name */
+    ldapdb_auxprop_store       /* auxprop store */
+};
+
+int ldapdb_auxprop_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_auxprop_plug_t **plug,
+                             const char *plugname __attribute__((unused))) 
+{
+    ldapctx tmp, *p;
+    const char *s;
+    unsigned len;
+
+    if(!out_version || !plug) return SASL_BADPARAM;
+
+    if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS;
+    
+    memset(&tmp, 0, sizeof(tmp));
+
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_uri", &tmp.uri, NULL);
+    if(!tmp.uri) return SASL_BADPARAM;
+
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_id",
+       (const char **)&tmp.id.bv_val, &len);
+    tmp.id.bv_len = len;
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_pw",
+       (const char **)&tmp.pw.bv_val, &len);
+    tmp.pw.bv_len = len;
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_mech",
+       (const char **)&tmp.mech.bv_val, &len);
+    tmp.mech.bv_len = len;
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_starttls", &s, NULL);
+    if (s)
+    {
+       if (!strcasecmp(s, "demand")) tmp.use_tls = 2;
+       else if (!strcasecmp(s, "try")) tmp.use_tls = 1;
+    }
+    utils->getopt(utils->getopt_context, ldapdb, "ldapdb_rc", &s, &len);
+    if (s)
+    {
+       char *str = utils->malloc(sizeof("LDAPRC=")+len);
+       if (!str) return SASL_NOMEM;
+       strcpy( str, "LDAPRC=" );
+       strcpy( str + sizeof("LDAPRC=")-1, s );
+       if (putenv(str))
+       {
+           utils->free(str);
+           return SASL_NOMEM;
+       }
+    }
+
+    p = utils->malloc(sizeof(ldapctx));
+    if (!p) return SASL_NOMEM;
+    *p = tmp;
+    ldapdb_auxprop_plugin.glob_context = p;
+
+    *out_version = SASL_AUXPROP_PLUG_VERSION;
+
+    *plug = &ldapdb_auxprop_plugin;
+
+    return SASL_OK;
+}
diff --git a/plugins/ldapdb_init.c b/plugins/ldapdb_init.c
new file mode 100644 (file)
index 0000000..f94f03b
--- /dev/null
@@ -0,0 +1,38 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_AUXPROP_PLUG_INIT( ldapdb )
+
diff --git a/plugins/login.c b/plugins/login.c
new file mode 100644 (file)
index 0000000..0b65e1a
--- /dev/null
@@ -0,0 +1,488 @@
+/* Login SASL plugin
+ * Rob Siemborski (SASLv2 Conversion)
+ * contributed by Rainer Schoepf <schoepf@uni-mainz.de>
+ * based on PLAIN, by Tim Martin <tmartin@andrew.cmu.edu>
+ * $Id: login.c,v 1.27 2004/09/08 11:09:10 mel 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sasl.h>
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: login.c,v 1.27 2004/09/08 11:09:10 mel Exp $";
+
+/*****************************  Server Section  *****************************/
+
+typedef struct context {
+    int state;
+
+    char *username;
+    unsigned username_len;
+} server_context_t;
+
+static int login_server_mech_new(void *glob_context __attribute__((unused)), 
+                                sasl_server_params_t *sparams,
+                                const char *challenge __attribute__((unused)),
+                                unsigned challen __attribute__((unused)),
+                                void **conn_context)
+{
+    server_context_t *text;
+    
+    /* holds state are in */
+    text = sparams->utils->malloc(sizeof(server_context_t));
+    if (text == NULL) {
+       MEMERROR( sparams->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(server_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+#define USERNAME_CHALLENGE "Username:"
+#define PASSWORD_CHALLENGE "Password:"
+
+static int login_server_mech_step(void *conn_context,
+                                 sasl_server_params_t *params,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen,
+                                 sasl_out_params_t *oparams)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    switch (text->state) {
+
+    case 1:
+       text->state = 2;
+
+       /* Check inlen, (possibly we have already the user name) */
+       /* In this case fall through to state 2 */
+       if (clientinlen == 0) {
+           /* demand username */
+           
+           *serveroutlen = (unsigned) strlen(USERNAME_CHALLENGE);
+           *serverout = USERNAME_CHALLENGE;
+
+           return SASL_CONTINUE;
+       }
+       
+       
+    case 2:
+       /* Catch really long usernames */
+       if (clientinlen > 1024) {
+           SETERROR(params->utils, "username too long (>1024 characters)");
+           return SASL_BADPROT;
+       }
+       
+       /* get username */
+       text->username =
+           params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1);
+       if (!text->username) {
+           MEMERROR( params->utils );
+           return SASL_NOMEM;
+       }
+       
+       strncpy(text->username, clientin, clientinlen);
+       text->username_len = clientinlen;
+       text->username[clientinlen] = '\0';
+       
+       /* demand password */
+       *serveroutlen = (unsigned) strlen(PASSWORD_CHALLENGE);
+       *serverout = PASSWORD_CHALLENGE;
+       
+       text->state = 3;
+       
+       return SASL_CONTINUE;
+       
+       
+    case 3: {
+       sasl_secret_t *password;
+       int result;
+       
+       /* Catch really long passwords */
+       if (clientinlen > 1024) {
+           SETERROR(params->utils,
+                    "clientinlen is > 1024 characters in LOGIN plugin");
+           return SASL_BADPROT;
+       }
+       
+       /* get password */
+       password =
+           params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1);
+       if (!password) {
+           MEMERROR(params->utils);
+           return SASL_NOMEM;
+       }
+       
+       strncpy(password->data, clientin, clientinlen);
+       password->data[clientinlen] = '\0';
+       password->len = clientinlen;
+
+       /* canonicalize username first, so that password verification is
+        * done against the canonical id */
+       result = params->canon_user(params->utils->conn, text->username,
+                                   text->username_len,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+       
+       /* verify_password - return sasl_ok on success */
+       result = params->utils->checkpass(params->utils->conn,
+                                         oparams->authid, oparams->alen,
+                                         password->data, password->len);
+       
+       if (result != SASL_OK) {
+           _plug_free_secret(params->utils, &password);
+           return result;
+       }
+       
+       _plug_free_secret(params->utils, &password);
+       
+       *serverout = NULL;
+       *serveroutlen = 0;
+       
+       oparams->doneflag = 1;
+       oparams->mech_ssf = 0;
+       oparams->maxoutbuf = 0;
+       oparams->encode_context = NULL;
+       oparams->encode = NULL;
+       oparams->decode_context = NULL;
+       oparams->decode = NULL;
+       oparams->param_version = 0;
+       
+       return SASL_OK;
+    }
+
+
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid LOGIN server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void login_server_mech_dispose(void *conn_context,
+                                     const sasl_utils_t *utils)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->username) utils->free(text->username);
+    
+    utils->free(text);
+}
+
+static sasl_server_plug_t login_server_plugins[] = 
+{
+    {
+       "LOGIN",                        /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOANONYMOUS,           /* security_flags */
+       0,                              /* features */
+       NULL,                           /* glob_context */
+       &login_server_mech_new,         /* mech_new */
+       &login_server_mech_step,        /* mech_step */
+       &login_server_mech_dispose,     /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int login_server_plug_init(sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_server_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "LOGIN version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = login_server_plugins;
+    *plugcount = 1;  
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    int state;
+
+    sasl_secret_t *password;
+    unsigned int free_password; /* set if we need to free password */
+} client_context_t;
+
+static int login_client_mech_new(void *glob_context __attribute__((unused)),
+                                sasl_client_params_t *params,
+                                void **conn_context)
+{
+    client_context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int login_client_mech_step(void *conn_context,
+                                 sasl_client_params_t *params,
+                                 const char *serverin __attribute__((unused)),
+                                 unsigned serverinlen __attribute__((unused)),
+                                 sasl_interact_t **prompt_need,
+                                 const char **clientout,
+                                 unsigned *clientoutlen,
+                                 sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    switch (text->state) {
+
+    case 1: {
+       const char *user;
+       int auth_result = SASL_OK;
+       int pass_result = SASL_OK;
+       int result;
+       
+       /* check if sec layer strong enough */
+       if (params->props.min_ssf > params->external_ssf) {
+           SETERROR( params->utils, "SSF requested of LOGIN plugin");
+           return SASL_TOOWEAK;
+       }
+       
+       /* try to get the userid */
+       /* Note: we want to grab the authname and not the userid, which is
+        *       who we AUTHORIZE as, and will be the same as the authname
+        *       for the LOGIN mech.
+        */
+       if (oparams->user == NULL) {
+           auth_result = _plug_get_authid(params->utils, &user, prompt_need);
+           
+           if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+               return auth_result;
+       }
+       
+       /* try to get the password */
+       if (text->password == NULL) {
+           pass_result = _plug_get_password(params->utils, &text->password,
+                                            &text->free_password, prompt_need);
+           
+           if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+               return pass_result;
+       }
+       
+       /* free prompts we got */
+       if (prompt_need && *prompt_need) {
+           params->utils->free(*prompt_need);
+           *prompt_need = NULL;
+       }
+       
+       /* if there are prompts not filled in */
+       if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) {
+           /* make the prompt list */
+           result =
+               _plug_make_prompts(params->utils, prompt_need,
+                                  NULL, NULL,
+                                  auth_result == SASL_INTERACT ?
+                                  "Please enter your authentication name" : NULL,
+                                  NULL,
+                                  pass_result == SASL_INTERACT ?
+                                  "Please enter your password" : NULL, NULL,
+                                  NULL, NULL, NULL,
+                                  NULL, NULL, NULL);
+           if (result != SASL_OK) return result;
+           
+           return SASL_INTERACT;
+       }
+       
+       if (!text->password) {
+           PARAMERROR(params->utils);
+           return SASL_BADPARAM;
+       }
+    
+       result = params->canon_user(params->utils->conn, user, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+       
+       /* server should have sent request for username - we ignore it */
+       if (!serverin) {
+           SETERROR( params->utils,
+                     "Server didn't issue challenge for USERNAME");
+           return SASL_BADPROT;
+       }
+       
+       if (!clientout) {
+           PARAMERROR( params->utils );
+           return SASL_BADPARAM;
+       }
+       
+       if (clientoutlen) *clientoutlen = oparams->alen;
+       *clientout = oparams->authid;
+       
+       text->state = 2;
+       
+       return SASL_CONTINUE;
+    }
+
+    case 2:
+       /* server should have sent request for password - we ignore it */
+       if (!serverin) {
+           SETERROR( params->utils,
+                     "Server didn't issue challenge for PASSWORD");
+           return SASL_BADPROT;
+       }
+       
+       if (!clientout) {
+           PARAMERROR(params->utils);
+           return SASL_BADPARAM;
+       }
+       
+       if (clientoutlen) *clientoutlen = text->password->len;
+       *clientout = text->password->data;
+       
+       /* set oparams */
+       oparams->doneflag = 1;
+       oparams->mech_ssf = 0;
+       oparams->maxoutbuf = 0;
+       oparams->encode_context = NULL;
+       oparams->encode = NULL;
+       oparams->decode_context = NULL;
+       oparams->decode = NULL;
+       oparams->param_version = 0;
+       
+       return SASL_OK;
+
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid LOGIN client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+
+    return SASL_FAIL; /* should never get here */
+}
+
+static void login_client_mech_dispose(void *conn_context,
+                                     const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    /* free sensitive info */
+    if (text->free_password) _plug_free_secret(utils, &(text->password));
+    
+    utils->free(text);
+}
+
+static sasl_client_plug_t login_client_plugins[] = 
+{
+    {
+       "LOGIN",                        /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOANONYMOUS,           /* security_flags */
+       SASL_FEAT_SERVER_FIRST,         /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &login_client_mech_new,         /* mech_new */
+       &login_client_mech_step,        /* mech_step */
+       &login_client_mech_dispose,     /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int login_client_plug_init(sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_client_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "Version mismatch in LOGIN");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = login_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/login_init.c b/plugins/login_init.c
new file mode 100644 (file)
index 0000000..cad7575
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_login_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( login )
+SASL_SERVER_PLUG_INIT( login )
+
diff --git a/plugins/makeinit.sh b/plugins/makeinit.sh
new file mode 100644 (file)
index 0000000..7f3acc2
--- /dev/null
@@ -0,0 +1,89 @@
+for mech in anonymous crammd5 digestmd5 gssapiv2 kerberos4 login ntlm otp passdss plain srp; do
+
+echo "
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include \"plugin_common.h\"
+
+#ifdef macintosh
+#include <sasl_${mech}_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( $mech )
+SASL_SERVER_PLUG_INIT( $mech )
+" > ${mech}_init.c
+done
+
+for mech in sasldb sql ldapdb; do
+
+echo "
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include \"plugin_common.h\"
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_AUXPROP_PLUG_INIT( $mech )
+" > ${mech}_init.c
+done
+
diff --git a/plugins/ntlm.c b/plugins/ntlm.c
new file mode 100644 (file)
index 0000000..51bebc3
--- /dev/null
@@ -0,0 +1,2147 @@
+/* NTLM SASL plugin
+ * Ken Murchison
+ * $Id: ntlm.c,v 1.30 2005/07/07 16:10:14 mel Exp $
+ *
+ * References:
+ *   http://www.innovation.ch/java/ntlm.html
+ *   http://www.opengroup.org/comsource/techref2/NCH1222X.HTM
+ *   http://www.ubiqx.org/cifs/rfc-draft/draft-leach-cifs-v1-spec-02.html
+ */
+/* 
+ * 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifdef WIN32
+# include <process.h>      /* for getpid */
+  typedef int pid_t;
+#else
+# include <unistd.h>
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <sys/utsname.h>
+# include <netdb.h>
+
+#ifndef SYS_NMLN
+  struct utsname dummy;
+# define SYS_NMLN sizeof(dummy.sysname)
+#endif
+
+# define closesocket(sock)   close(sock)
+  typedef int SOCKET;
+#endif /* WIN32 */
+
+#include <openssl/md4.h>
+#include <openssl/md5.h>
+#include <openssl/hmac.h>
+#include <openssl/des.h>
+#include <openssl/opensslv.h>
+#if (OPENSSL_VERSION_NUMBER >= 0x0090700f) && \
+     !defined(OPENSSL_ENABLE_OLD_DES_SUPPORT)
+# define des_cblock DES_cblock
+# define des_key_schedule DES_key_schedule
+# define des_set_odd_parity(k) \
+        DES_set_odd_parity((k))
+# define des_set_key(k,ks) \
+        DES_set_key((k),&(ks))
+# define des_key_sched(k,ks) \
+         DES_key_sched((k),&(ks))
+# define des_ecb_encrypt(i,o,k,e) \
+        DES_ecb_encrypt((i),(o),&(k),(e))
+#endif /* OpenSSL 0.9.7+ w/o old DES support */
+
+#include <sasl.h>
+#define MD5_H  /* suppress internal MD5 */
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: ntlm.c,v 1.30 2005/07/07 16:10:14 mel Exp $";
+
+#ifdef WIN32
+static ssize_t writev (SOCKET fd, const struct iovec *iov, size_t iovcnt);
+
+ssize_t writev (SOCKET fd, const struct iovec *iov, size_t iovcnt)
+{
+    ssize_t nwritten;          /* amount written */
+    ssize_t nbytes;
+    size_t i;
+  
+    nbytes = 0;
+
+    for (i = 0; i < iovcnt; i++) {
+       if ((nwritten = send (fd, iov[i].iov_base, iov[i].iov_len, 0)) == SOCKET_ERROR) {
+/* Unless socket is nonblocking, we should always write everything */
+           return (-1);
+       }
+
+       nbytes += nwritten;
+         
+       if (nwritten < iov[i].iov_len) {
+           break;
+       }
+    }
+    return (nbytes);
+}
+#endif /* WIN32 */
+
+#ifndef UINT16_MAX
+#define UINT16_MAX 65535U
+#endif
+
+#if UINT_MAX == UINT16_MAX
+typedef unsigned int uint16;
+#elif USHRT_MAX == UINT16_MAX
+typedef unsigned short uint16;
+#else
+#error dont know what to use for uint16
+#endif
+
+#ifndef UINT32_MAX
+#define UINT32_MAX 4294967295U
+#endif
+
+#if UINT_MAX == UINT32_MAX
+typedef unsigned int uint32;
+#elif ULONG_MAX == UINT32_MAX
+typedef unsigned long uint32;
+#elif USHRT_MAX == UINT32_MAX
+typedef unsigned short uint32;
+#else
+#error dont know what to use for uint32
+#endif
+
+#define NTLM_SIGNATURE         "NTLMSSP"
+
+enum {
+    NTLM_TYPE_REQUEST          = 1,
+    NTLM_TYPE_CHALLENGE                = 2,
+    NTLM_TYPE_RESPONSE         = 3
+};
+
+enum {
+    NTLM_USE_UNICODE           = 0x00001,
+    NTLM_USE_ASCII             = 0x00002,
+    NTLM_ASK_TARGET            = 0x00004,
+    NTLM_AUTH_NTLM             = 0x00200,
+    NTLM_ALWAYS_SIGN           = 0x08000,
+    NTLM_TARGET_IS_DOMAIN      = 0x10000,
+    NTLM_TARGET_IS_SERVER      = 0x20000,
+    NTLM_FLAGS_MASK            = 0x0ffff
+};
+
+enum {
+    NTLM_NONCE_LENGTH          = 8,
+    NTLM_HASH_LENGTH           = 21,
+    NTLM_RESP_LENGTH           = 24,
+    NTLM_SESSKEY_LENGTH                = 16,
+};
+
+enum {
+    NTLM_SIG_OFFSET            = 0,
+    NTLM_TYPE_OFFSET           = 8,
+
+    NTLM_TYPE1_FLAGS_OFFSET    = 12,
+    NTLM_TYPE1_DOMAIN_OFFSET   = 16,
+    NTLM_TYPE1_WORKSTN_OFFSET  = 24,
+    NTLM_TYPE1_DATA_OFFSET     = 32,
+    NTLM_TYPE1_MINSIZE         = 16,
+
+    NTLM_TYPE2_TARGET_OFFSET   = 12,
+    NTLM_TYPE2_FLAGS_OFFSET    = 20,
+    NTLM_TYPE2_CHALLENGE_OFFSET        = 24,
+    NTLM_TYPE2_CONTEXT_OFFSET  = 32,
+    NTLM_TYPE2_TARGETINFO_OFFSET= 40,
+    NTLM_TYPE2_DATA_OFFSET     = 48,
+    NTLM_TYPE2_MINSIZE         = 32,
+
+    NTLM_TYPE3_LMRESP_OFFSET   = 12,
+    NTLM_TYPE3_NTRESP_OFFSET   = 20,
+    NTLM_TYPE3_DOMAIN_OFFSET   = 28,
+    NTLM_TYPE3_USER_OFFSET     = 36,
+    NTLM_TYPE3_WORKSTN_OFFSET  = 44,
+    NTLM_TYPE3_SESSIONKEY_OFFSET= 52,
+    NTLM_TYPE3_FLAGS_OFFSET    = 60,
+    NTLM_TYPE3_DATA_OFFSET     = 64,
+    NTLM_TYPE3_MINSIZE         = 52,
+
+    NTLM_BUFFER_LEN_OFFSET     = 0,
+    NTLM_BUFFER_MAXLEN_OFFSET  = 2,
+    NTLM_BUFFER_OFFSET_OFFSET  = 4,
+    NTLM_BUFFER_SIZE           = 8
+};
+
+/* return the length of a string (even if it is NULL) */
+#define xstrlen(s) (s ? strlen(s) : 0)
+
+/* machine-independent routines to convert to/from Intel byte-order */
+#define htois(is, hs) \
+    (is)[0] = hs & 0xff; \
+    (is)[1] = hs >> 8
+
+#define itohs(is) \
+    ((is)[0] | ((is)[1] << 8))
+
+#define htoil(il, hl) \
+    (il)[0] = hl & 0xff; \
+    (il)[1] = (hl >> 8) & 0xff; \
+    (il)[2] = (hl >> 16) & 0xff; \
+    (il)[3] = hl >> 24
+
+#define itohl(il) \
+    ((il)[0] | ((il)[1] << 8) | ((il)[2] << 16) | ((il)[3] << 24))
+
+/* convert string to all upper case */
+static const char *ucase(const char *str, size_t len)
+{
+    char *cp = (char *) str;
+
+    if (!len) len = xstrlen(str);
+    
+    while (len && cp && *cp) {
+       *cp = toupper((int) *cp);
+       cp++;
+       len--;
+    }
+
+    return (str);
+}
+
+/* copy src to dst as unicode (in Intel byte-order) */
+static void to_unicode(u_char *dst, const char *src, int len)
+{
+    for (; len; len--) {
+       *dst++ = *src++;
+       *dst++ = 0;
+    }
+}
+
+/* copy unicode src (in Intel byte-order) to dst */
+static void from_unicode(char *dst, u_char *src, int len)
+{
+    for (; len; len--) {
+       *dst++ = *src & 0x7f;
+       src += 2;
+    }
+}
+
+/* load a string into an NTLM buffer */
+static void load_buffer(u_char *buf, const u_char *str, uint16 len,
+                       int unicode, u_char *base, uint32 *offset)
+{
+    if (len) {
+       if (unicode) {
+           to_unicode(base + *offset, str, len);
+           len *= 2;
+       }
+       else {
+           memcpy(base + *offset, str, len);
+       }
+    }
+
+    htois(buf + NTLM_BUFFER_LEN_OFFSET, len);
+    htois(buf + NTLM_BUFFER_MAXLEN_OFFSET, len);
+    htoil(buf + NTLM_BUFFER_OFFSET_OFFSET, *offset);
+    *offset += len;
+}
+
+/* unload a string from an NTLM buffer */
+static int unload_buffer(const sasl_utils_t *utils, const u_char *buf,
+                        u_char **str, unsigned *outlen,
+                        int unicode, const u_char *base, unsigned msglen)
+{
+    uint16 len = itohs(buf + NTLM_BUFFER_LEN_OFFSET);
+
+    if (len) {
+       uint32 offset;
+
+       *str = utils->malloc(len + 1); /* add 1 for NUL */
+       if (*str == NULL) {
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+
+       offset = itohl(buf + NTLM_BUFFER_OFFSET_OFFSET);
+
+       /* sanity check */
+       if (offset > msglen || len > (msglen - offset)) return SASL_BADPROT;
+
+       if (unicode) {
+           len /= 2;
+           from_unicode((char *) *str, (u_char *) base + offset, len);
+       }
+       else
+           memcpy(*str, base + offset, len);
+
+       (*str)[len] = '\0'; /* add NUL */
+    }
+    else {
+       *str = NULL;
+    }
+
+    if (outlen) *outlen = len;
+
+    return SASL_OK;
+}
+
+/*
+ * NTLM encryption/authentication routines per section 2.10 of
+ * draft-leach-cifs-v1-spec-02
+ */
+static void E(unsigned char *out, unsigned char *K, unsigned Klen,
+             unsigned char *D, unsigned Dlen)
+             
+{
+    unsigned k, d;
+    des_cblock K64;
+    des_key_schedule ks;
+    unsigned char *Dp;
+#define KEY_SIZE   7
+#define BLOCK_SIZE 8
+
+    for (k = 0; k < Klen; k += KEY_SIZE, K += KEY_SIZE) {
+       /* convert 56-bit key to 64-bit */
+       K64[0] = K[0];
+       K64[1] = ((K[0] << 7) & 0xFF) | (K[1] >> 1);
+       K64[2] = ((K[1] << 6) & 0xFF) | (K[2] >> 2);
+       K64[3] = ((K[2] << 5) & 0xFF) | (K[3] >> 3);
+       K64[4] = ((K[3] << 4) & 0xFF) | (K[4] >> 4);
+       K64[5] = ((K[4] << 3) & 0xFF) | (K[5] >> 5);
+       K64[6] = ((K[5] << 2) & 0xFF) | (K[6] >> 6);
+       K64[7] =  (K[6] << 1) & 0xFF;
+
+       des_set_odd_parity(&K64); /* XXX is this necessary? */
+       des_set_key(&K64, ks);
+
+       for (d = 0, Dp = D; d < Dlen;
+            d += BLOCK_SIZE, Dp += BLOCK_SIZE, out += BLOCK_SIZE) {
+           des_ecb_encrypt((void *) Dp, (void *) out, ks, DES_ENCRYPT);
+       }
+    }
+}
+
+static unsigned char *P16_lm(unsigned char *P16, sasl_secret_t *passwd,
+                            const sasl_utils_t *utils __attribute__((unused)),
+                            char **buf __attribute__((unused)),
+                            unsigned *buflen __attribute__((unused)),
+                            int *result)
+{
+    char P14[14];
+    unsigned char S8[] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+
+    strncpy(P14, passwd->data, sizeof(P14));
+    ucase(P14, sizeof(P14));
+
+    E(P16, P14, sizeof(P14), S8, sizeof(S8));
+    *result = SASL_OK;
+    return P16;
+}
+
+static unsigned char *P16_nt(unsigned char *P16, sasl_secret_t *passwd,
+                            const sasl_utils_t *utils,
+                            char **buf, unsigned *buflen, int *result)
+{
+    if (_plug_buf_alloc(utils, buf, buflen, 2 * passwd->len) != SASL_OK) {
+       SETERROR(utils, "cannot allocate P16_nt unicode buffer");
+       *result = SASL_NOMEM;
+    }
+    else {
+       to_unicode(*buf, passwd->data, passwd->len);
+       MD4(*buf, 2 * passwd->len, P16);
+       *result = SASL_OK;
+    }
+    return P16;
+}
+
+static unsigned char *P21(unsigned char *P21, sasl_secret_t *passwd,
+                         unsigned char * (*P16)(unsigned char *,
+                                                sasl_secret_t *,
+                                                const sasl_utils_t *,
+                                                char **, unsigned *, int *),
+                         const sasl_utils_t *utils,
+                         char **buf, unsigned *buflen, int *result)
+{
+    memset(P16(P21, passwd, utils, buf, buflen, result) + 16, 0, 5);
+    return P21;
+}
+
+static unsigned char *P24(unsigned char *P24, unsigned char *P21,
+                         unsigned char *C8)
+                     
+{
+    E(P24, P21, NTLM_HASH_LENGTH, C8, NTLM_NONCE_LENGTH);
+    return P24;
+}
+
+static unsigned char *V2(unsigned char *V2, sasl_secret_t *passwd,
+                        const char *authid, const char *target,
+                        const unsigned char *challenge,
+                        const unsigned char *blob, unsigned bloblen,
+                        const sasl_utils_t *utils,
+                        char **buf, unsigned *buflen, int *result)
+{
+    HMAC_CTX ctx;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    char *upper;
+    int len;
+
+    /* Allocate enough space for the unicode target */
+    len = (int) (strlen(authid) + xstrlen(target));
+    if (_plug_buf_alloc(utils, buf, buflen, 2 * len + 1) != SASL_OK) {
+       SETERROR(utils, "cannot allocate NTLMv2 hash");
+       *result = SASL_NOMEM;
+    }
+    else {
+       /* NTLMv2hash = HMAC-MD5(NTLMhash, unicode(ucase(authid + domain))) */
+       P16_nt(hash, passwd, utils, buf, buflen, result);
+
+       /* Use the tail end of the buffer for ucase() conversion */
+       upper = *buf + len;
+       strcpy(upper, authid);
+       if (target) strcat(upper, target);
+       ucase(upper, len);
+       to_unicode(*buf, upper, len);
+
+       HMAC(EVP_md5(), hash, MD4_DIGEST_LENGTH, *buf, 2 * len, hash, &len);
+
+       /* V2 = HMAC-MD5(NTLMv2hash, challenge + blob) + blob */
+       HMAC_Init(&ctx, hash, len, EVP_md5());
+       HMAC_Update(&ctx, challenge, NTLM_NONCE_LENGTH);
+       HMAC_Update(&ctx, blob, bloblen);
+       HMAC_Final(&ctx, V2, &len);
+       HMAC_cleanup(&ctx);
+
+       /* the blob is concatenated outside of this function */
+
+       *result = SASL_OK;
+    }
+
+    return V2;
+}
+
+/*****************************  Server Section  *****************************/
+
+typedef struct server_context {
+    int state;
+
+    uint32 flags;
+    unsigned char nonce[NTLM_NONCE_LENGTH];
+
+    /* per-step mem management */
+    char *out_buf;
+    unsigned out_buf_len;
+
+    /* socket to remote authentication host */
+    SOCKET sock;
+
+} server_context_t;
+
+#define        N(a)                    (sizeof (a) / sizeof (a[0]))
+
+#define SMB_HDR_PROTOCOL       "\xffSMB"
+
+typedef struct {
+    unsigned char protocol[4];
+    unsigned char command;
+    uint32 status;
+    unsigned char flags;
+    uint16 flags2;
+    uint16 PidHigh;
+    unsigned char extra[10];
+    uint16 tid;
+    uint16 pid;
+    uint16 uid;
+    uint16 mid;
+} SMB_Header;
+
+typedef struct {
+    uint16 dialect_index;
+    unsigned char security_mode;
+    uint16 max_mpx_count;
+    uint16 max_number_vcs;
+    uint32 max_buffer_size;
+    uint32 max_raw_size;
+    uint32 session_key;
+    uint32 capabilities;
+    uint32 system_time_low;
+    uint32 system_time_high;
+    uint16 server_time_zone;
+    unsigned char encryption_key_length;
+} SMB_NegProt_Resp;
+
+typedef struct {
+    unsigned char andx_command;
+    unsigned char andx_reserved;
+    uint16 andx_offset;
+    uint16 max_buffer_size;
+    uint16 max_mpx_count;
+    uint16 vc_number;
+    uint32 session_key;
+    uint16 case_insensitive_passwd_len;
+    uint16 case_sensitive_passwd_len;
+    uint32 reserved;
+    uint32 capabilities;
+} SMB_SessionSetup;
+
+typedef struct {
+    unsigned char andx_command;
+    unsigned char andx_reserved;
+    uint16 andx_offset;
+    uint16 action;
+} SMB_SessionSetup_Resp;
+
+enum {
+    NBT_SESSION_REQUEST                = 0x81,
+    NBT_POSITIVE_SESSION_RESP  = 0x82,
+    NBT_NEGATIVE_SESSION_RESP  = 0x83,
+    NBT_ERR_NO_LISTEN_CALLED   = 0x80,
+    NBT_ERR_NO_LISTEN_CALLING  = 0x81,
+    NBT_ERR_CALLED_NOT_PRESENT = 0x82,
+    NBT_ERR_INSUFFICIENT_RESRC = 0x83,
+    NBT_ERR_UNSPECIFIED                = 0x8F,
+
+    SMB_HDR_SIZE               = 32,
+
+    SMB_COM_NEGOTIATE_PROTOCOL = 0x72,
+    SMB_COM_SESSION_SETUP_ANDX = 0x73,
+    SMB_COM_NONE               = 0xFF,
+
+    SMB_FLAGS_SERVER_TO_REDIR  = 0x80,
+
+    SMB_FLAGS2_ERR_STATUS      = 0x4000,
+    SMB_FLAGS2_UNICODE         = 0x8000,
+
+    SMB_NEGPROT_RESP_SIZE      = 34,
+
+    SMB_SECURITY_MODE_USER     = 0x1,
+    SMB_SECURITY_MODE_ENCRYPT  = 0x2,
+    SMB_SECURITY_MODE_SIGN     = 0x4,
+    SMB_SECURITY_MODE_SIGN_REQ = 0x8,
+
+    SMB_CAP_UNICODE            = 0x0004,
+    SMB_CAP_STATUS32           = 0x0040,
+    SMB_CAP_EXTENDED_SECURITY  = 0x80000000,
+
+    SMB_SESSION_SETUP_SIZE     = 26,
+    SMB_SESSION_SETUP_RESP_SIZE        = 6,
+
+    SMB_REQUEST_MODE_GUEST     = 0x1
+};
+
+static const char *SMB_DIALECTS[] = {
+#if 0
+    "\x02PC NETWORK PROGRAM 1.0",
+    "\x02PCLAN1.0",
+    "\x02MICROSOFT NETWORKS 1.03",
+    "\x02MICROSOFT NETWORKS 3.0",
+    "\x02LANMAN1.0",
+    "\x02Windows for Workgroups 3.1a",
+    "\x02LM1.2X002",
+    "\x02DOS LM1.2X002",
+    "\x02DOS LANLAM2.1",
+    "\x02LANMAN2.1",
+#endif
+    "\x02NT LM 0.12"
+};
+
+static void load_smb_header(unsigned char buf[], SMB_Header *hdr)
+{
+    unsigned char *p = buf;
+
+    memcpy(p, SMB_HDR_PROTOCOL, 4); p += 4;
+    *p++ = hdr->command;
+    htoil(p, hdr->status); p += 4;
+    *p++ = hdr->flags;
+    htois(p, hdr->flags2); p += 2;
+    htois(p, hdr->PidHigh); p += 2;
+    memcpy(p, hdr->extra, 10); p += 10;
+    htois(p, hdr->tid); p += 2;
+    htois(p, hdr->pid); p += 2;
+    htois(p, hdr->uid); p += 2;
+    htois(p, hdr->mid);
+}
+
+static void unload_smb_header(unsigned char buf[], SMB_Header *hdr)
+{
+    unsigned char *p = buf;
+
+    memcpy(hdr->protocol, p, 4); p += 4;
+    hdr->command = *p++;
+    hdr->status = itohl(p); p += 4;
+    hdr->flags = *p++;
+    hdr->flags2 = itohs(p); p += 2;
+    hdr->PidHigh = itohs(p); p += 2;
+    memcpy(hdr->extra, p, 10); p += 10;
+    hdr->tid = itohs(p); p += 2;
+    hdr->pid = itohs(p); p += 2;
+    hdr->uid = itohs(p); p += 2;
+    hdr->mid = itohs(p);
+}
+
+static void unload_negprot_resp(unsigned char buf[], SMB_NegProt_Resp *resp)
+{
+    unsigned char *p = buf;
+
+    resp->dialect_index = itohs(p); p += 2;
+    resp->security_mode = *p++;
+    resp->max_mpx_count = itohs(p); p += 2;
+    resp->max_number_vcs = itohs(p); p += 2;
+    resp->max_buffer_size = itohl(p); p += 4;
+    resp->max_raw_size = itohl(p); p += 4;
+    resp->session_key = itohl(p); p += 4;
+    resp->capabilities = itohl(p); p += 4;
+    resp->system_time_low = itohl(p); p += 4;
+    resp->system_time_high = itohl(p); p += 4;
+    resp->server_time_zone = itohs(p); p += 2;
+    resp->encryption_key_length = *p;
+}
+
+static void load_session_setup(unsigned char buf[], SMB_SessionSetup *setup)
+{
+    unsigned char *p = buf;
+
+    *p++ = setup->andx_command;
+    *p++ = setup->andx_reserved;
+    htois(p, setup->andx_offset); p += 2;
+    htois(p, setup->max_buffer_size); p += 2;
+    htois(p, setup->max_mpx_count); p += 2;
+    htois(p, setup->vc_number); p += 2;
+    htoil(p, setup->session_key); p += 4;
+    htois(p, setup->case_insensitive_passwd_len); p += 2;
+    htois(p, setup->case_sensitive_passwd_len); p += 2;
+    htoil(p, setup->reserved); p += 4;
+    htoil(p, setup->capabilities); p += 4;
+}
+
+static void unload_session_setup_resp(unsigned char buf[],
+                                     SMB_SessionSetup_Resp *resp)
+{
+    unsigned char *p = buf;
+
+    resp->andx_command = *p++;
+    resp->andx_reserved = *p++;
+    resp->andx_offset = itohs(p); p += 2;
+    resp->action = itohs(p);
+}
+
+/*
+ * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt'
+ * until all the data is written out or an error occurs.
+ */
+static int retry_writev(SOCKET fd, struct iovec *iov, int iovcnt)
+{
+    int n;
+    int i;
+    int written = 0;
+    static int iov_max =
+#ifdef MAXIOV
+       MAXIOV
+#else
+#ifdef IOV_MAX
+       IOV_MAX
+#else
+       8192
+#endif
+#endif
+       ;
+    
+    for (;;) {
+       while (iovcnt && iov[0].iov_len == 0) {
+           iov++;
+           iovcnt--;
+       }
+
+       if (!iovcnt) return written;
+
+       n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
+       if (n == -1) {
+#ifndef WIN32
+           if (errno == EINVAL && iov_max > 10) {
+               iov_max /= 2;
+               continue;
+           }
+           if (errno == EINTR) continue;
+#endif
+           return -1;
+       }
+
+       written += n;
+
+       for (i = 0; i < iovcnt; i++) {
+           if ((int) iov[i].iov_len > n) {
+               iov[i].iov_base = (char *) iov[i].iov_base + n;
+               iov[i].iov_len -= n;
+               break;
+           }
+           n -= iov[i].iov_len;
+           iov[i].iov_len = 0;
+       }
+
+       if (i == iovcnt) return written;
+    }
+}
+
+/*
+ * Keep calling the read() system call with 'fd', 'buf', and 'nbyte'
+ * until all the data is read in or an error occurs.
+ */
+static int retry_read(SOCKET fd, char *buf0, unsigned nbyte)
+{
+    int n;
+    int nread = 0;
+    char *buf = buf0;
+
+    if (nbyte == 0) return 0;
+
+    for (;;) {
+/* Can't use read() on sockets on Windows, but recv works on all platforms */
+       n = recv (fd, buf, nbyte, 0);
+       if (n == -1 || n == 0) {
+#ifndef WIN32
+           if (errno == EINTR || errno == EAGAIN) continue;
+#endif
+           return -1;
+       }
+
+       nread += n;
+
+       if (n >= (int) nbyte) return nread;
+
+       buf += n;
+       nbyte -= n;
+    }
+}
+
+static void make_netbios_name(const char *in, unsigned char out[])
+{
+    size_t i, j = 0, n;
+
+    /* create a NetBIOS name from the DNS name
+     *
+     * - use up to the first 16 chars of the first part of the hostname
+     * - convert to all uppercase
+     * - use the tail end of the output buffer as temp space
+     */
+    n = strcspn(in, ".");
+    if (n > 16) n = 16;
+    strncpy(out+18, in, n);
+    in = out+18;
+    ucase(in, n);
+
+    out[j++] = 0x20;
+    for (i = 0; i < n; i++) {
+       out[j++] = ((in[i] >> 4) & 0xf) + 0x41;
+       out[j++] = (in[i] & 0xf) + 0x41;
+    }
+    for (; i < 16; i++) {
+       out[j++] = ((0x20 >> 4) & 0xf) + 0x41;
+       out[j++] = (0x20 & 0xf) + 0x41;
+    }
+    out[j] = 0;
+}
+
+static SOCKET smb_connect_server(const sasl_utils_t *utils, const char *client,
+                             const char *server)
+{
+    struct addrinfo hints;
+    struct addrinfo *ai = NULL, *r;
+    SOCKET s = (SOCKET) -1;
+    int err;
+    char * error_str;
+#ifdef WIN32
+    DWORD saved_errno;
+#else
+    int saved_errno;
+#endif
+    int niflags;
+    char *port = "139";
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+
+    unsigned char called[34];
+    unsigned char calling[34];
+    struct iovec iov[3];
+    uint32 pkt;
+    int rc;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_CANONNAME;
+    if ((err = getaddrinfo(server, port, &hints, &ai)) != 0) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: getaddrinfo %s/%s: %s",
+                  server, port, gai_strerror(err));
+       return -1;
+    }
+
+    /* Make sure we have AF_INET or AF_INET6 addresses. */
+    if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
+       utils->log(NULL, SASL_LOG_ERR, "NTLM: no IP address info for %s",
+                  ai->ai_canonname ? ai->ai_canonname : server);
+       freeaddrinfo(ai);
+       return -1;
+    }
+
+    /* establish connection to authentication server */
+    for (r = ai; r; r = r->ai_next) {
+       s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+       if (s < 0)
+           continue;
+       if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
+           break;
+#ifdef WIN32
+       saved_errno = WSAGetLastError();
+#else
+       saved_errno = errno;
+#endif
+       closesocket (s);
+       s = -1;
+       niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+       if (r->ai_family == AF_INET6)
+           niflags |= NI_WITHSCOPEID;
+#endif
+       if (getnameinfo(r->ai_addr, r->ai_addrlen, hbuf, sizeof(hbuf),
+                       pbuf, sizeof(pbuf), niflags) != 0) {
+           strcpy(hbuf, "unknown");
+           strcpy(pbuf, "unknown");
+       }
+
+        /* Can't use errno (and %m), as it doesn't contain
+         * the socket error on Windows */
+       error_str = _plug_get_error_message (utils, saved_errno);
+       utils->log(NULL, SASL_LOG_WARN, "NTLM: connect %s[%s]/%s: %s",
+                  ai->ai_canonname ? ai->ai_canonname : server,
+                  hbuf,
+                  pbuf,
+                  error_str);
+       utils->free (error_str);
+    }
+    if (s < 0) {
+       if (getnameinfo(ai->ai_addr, ai->ai_addrlen, NULL, 0,
+                       pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) {
+               strcpy(pbuf, "unknown");
+       }
+       utils->log(NULL, SASL_LOG_ERR, "NTLM: couldn't connect to %s/%s",
+                  ai->ai_canonname ? ai->ai_canonname : server, pbuf);
+       freeaddrinfo(ai);
+       return -1;
+    }
+
+    freeaddrinfo(ai);
+
+    /*** send NetBIOS session request ***/
+
+    /* get length of data */
+    pkt = sizeof(called) + sizeof(calling);
+
+    /* make sure length is less than 17 bits */
+    if (pkt >= (1 << 17)) {
+       closesocket(s);
+       return -1;
+    }
+
+    /* prepend the packet type */
+    pkt |= (NBT_SESSION_REQUEST << 24);
+    pkt = htonl(pkt);
+
+    /* XXX should determine the real NetBIOS name */
+    make_netbios_name(server, called);
+    make_netbios_name(client, calling);
+
+    iov[0].iov_base = (void *) &pkt;
+    iov[0].iov_len = sizeof(pkt);
+    iov[1].iov_base = called;
+    iov[1].iov_len = sizeof(called);
+    iov[2].iov_base = calling;
+    iov[2].iov_len = sizeof(calling);
+
+    rc = retry_writev(s, iov, N(iov));
+    if (rc == -1) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error sending NetBIOS session request");
+       closesocket(s);
+       return -1;
+    }
+
+    rc = retry_read(s, (char *) &pkt, sizeof(pkt));
+    pkt = ntohl(pkt);
+    if (rc == -1 || pkt != (uint32) (NBT_POSITIVE_SESSION_RESP << 24)) {
+       unsigned char ec = NBT_ERR_UNSPECIFIED;
+       char *errstr;
+
+       retry_read(s, (char *) &ec, sizeof(ec));
+       switch (ec) {
+       case NBT_ERR_NO_LISTEN_CALLED:
+           errstr = "Not listening on called name";
+           break;
+       case NBT_ERR_NO_LISTEN_CALLING:
+           errstr = "Not listening for calling name";
+           break;
+       case NBT_ERR_CALLED_NOT_PRESENT:
+           errstr = "Called name not present";
+           break;
+       case NBT_ERR_INSUFFICIENT_RESRC:
+           errstr = "Called name present, but insufficient resources";
+           break;
+       default:
+           errstr = "Unspecified error";
+       }
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: negative NetBIOS session response: %s", errstr);
+       closesocket(s);
+       return -1;
+    }
+
+    return s;
+}
+
+static int smb_negotiate_protocol(const sasl_utils_t *utils,
+                                 server_context_t *text, char **domain)
+{
+    SMB_Header hdr;
+    SMB_NegProt_Resp resp;
+    unsigned char hbuf[SMB_HDR_SIZE], *p;
+    unsigned char wordcount = 0;
+    unsigned char bc[sizeof(uint16)];
+    uint16 bytecount;
+    uint32 len, nl;
+    int n_dialects = N(SMB_DIALECTS);
+    struct iovec iov[4+N(SMB_DIALECTS)];
+    int i, n;
+    int rc;
+    pid_t current_pid;
+
+    /*** create a negotiate protocol request ***/
+
+    /* create a header */
+    memset(&hdr, 0, sizeof(hdr));
+    hdr.command = SMB_COM_NEGOTIATE_PROTOCOL;
+#if 0
+    hdr.flags2 = SMB_FLAGS2_ERR_STATUS;
+    if (text->flags & NTLM_USE_UNICODE) hdr.flags2 |= SMB_FLAGS2_UNICODE;
+#endif
+    current_pid = getpid();
+    if (sizeof(current_pid) <= 2) {
+       hdr.pid = (uint16) current_pid;
+       hdr.PidHigh = 0;
+    } else {
+       hdr.pid = (uint16) (((uint32) current_pid) & 0xFFFF);
+       hdr.PidHigh = (uint16) (((uint32) current_pid) >> 16);
+    }
+
+    load_smb_header(hbuf, &hdr);
+
+    /* put together all of the pieces of the request */
+    n = 0;
+    iov[n].iov_base = (void *) &nl;
+    iov[n++].iov_len = sizeof(len);
+    iov[n].iov_base = hbuf;
+    iov[n++].iov_len = SMB_HDR_SIZE;
+    iov[n].iov_base = &wordcount;
+    iov[n++].iov_len = sizeof(wordcount);
+    iov[n].iov_base = (void *) &bc;
+    iov[n++].iov_len = sizeof(bc);
+
+    /* add our supported dialects */
+    for (i = 0; i < n_dialects; i++) {
+       iov[n].iov_base = (char *) SMB_DIALECTS[i];
+       iov[n++].iov_len = (long) strlen(SMB_DIALECTS[i]) + 1;
+    }
+
+    /* total up the lengths */
+    len = bytecount = 0;
+    for (i = 1; i < 4; i++) len += iov[i].iov_len;
+    for (i = 4; i < n; i++) bytecount += (uint16) iov[i].iov_len;
+    len += bytecount;
+    nl = htonl(len);
+    htois((char *) &bc, bytecount);
+
+    /* send it */
+    rc = retry_writev(text->sock, iov, n);
+    if (rc == -1) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error sending NEGPROT request");
+       return SASL_FAIL;
+    }
+
+    /*** read the negotiate protocol response ***/
+
+    /* read the total length */
+    rc = retry_read(text->sock, (char *) &nl, sizeof(nl));
+    if (rc < (int) sizeof(nl)) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error reading NEGPROT response length");
+       return SASL_FAIL;
+    }
+
+    /* read the data */
+    len = ntohl(nl);
+    if (_plug_buf_alloc(utils, &text->out_buf, &text->out_buf_len,
+                       len) != SASL_OK) {
+       SETERROR(utils, "cannot allocate NTLM NEGPROT response buffer");
+       return SASL_NOMEM;
+    }
+
+    rc = retry_read(text->sock, text->out_buf, len);
+    if (rc < (int) len) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error reading NEGPROT response");
+       return SASL_FAIL;
+    }
+    p = text->out_buf;
+
+    /* parse the header */
+    if (len < SMB_HDR_SIZE) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: not enough data for NEGPROT response header");
+       return SASL_FAIL;
+    }
+    unload_smb_header(p, &hdr);
+    p += SMB_HDR_SIZE;
+    len -= SMB_HDR_SIZE;
+
+    /* sanity check the header */
+    if (memcmp(hdr.protocol, SMB_HDR_PROTOCOL, 4)       /* correct protocol */
+       || hdr.command != SMB_COM_NEGOTIATE_PROTOCOL /* correct command */
+       || hdr.status                            /* no errors */
+       || !(hdr.flags & SMB_FLAGS_SERVER_TO_REDIR)) { /* response */
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error in NEGPROT response header: %ld",
+                  hdr.status);
+       return SASL_FAIL;
+    }
+
+    /* get the wordcount */
+    if (len < 1) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: not enough data for NEGPROT response wordcount");
+       return SASL_FAIL;
+    }
+    wordcount = *p++;
+    len--;
+
+    /* parse the parameters */
+    if (wordcount != SMB_NEGPROT_RESP_SIZE / sizeof(uint16)) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: incorrect NEGPROT wordcount for NT LM 0.12");
+       return SASL_FAIL;
+    }
+    unload_negprot_resp(p, &resp);
+    p += SMB_NEGPROT_RESP_SIZE;
+    len -= SMB_NEGPROT_RESP_SIZE;
+
+    /* sanity check the parameters */
+    if (resp.dialect_index != 0
+       || !(resp.security_mode & SMB_SECURITY_MODE_USER)
+       || !(resp.security_mode & SMB_SECURITY_MODE_ENCRYPT)
+       || resp.security_mode & SMB_SECURITY_MODE_SIGN_REQ
+       || resp.capabilities & SMB_CAP_EXTENDED_SECURITY
+       || resp.encryption_key_length != NTLM_NONCE_LENGTH) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error in NEGPROT response parameters");
+       return SASL_FAIL;
+    }
+
+    /* get the bytecount */
+    if (len < 2) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: not enough data for NEGPROT response bytecount");
+       return SASL_FAIL;
+    }
+    bytecount = itohs(p);
+    p += 2;
+    len -= 2;
+    if (len != bytecount) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: incorrect bytecount for NEGPROT response data");
+       return SASL_FAIL;
+    }
+
+    /* parse the data */
+    memcpy(text->nonce, p, resp.encryption_key_length);
+    p += resp.encryption_key_length;
+    len -= resp.encryption_key_length;
+
+    /* if client asked for target, send domain */
+    if (text->flags & NTLM_ASK_TARGET) {
+       *domain = utils->malloc(len);
+       if (domain == NULL) {
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+       memcpy(*domain, p, len);
+       from_unicode(*domain, *domain, len);
+
+       text->flags |= NTLM_TARGET_IS_DOMAIN;
+    }
+
+    return SASL_OK;
+}
+
+static int smb_session_setup(const sasl_utils_t *utils, server_context_t *text,
+                            const char *authid, char *domain,
+                            unsigned char *lm_resp, unsigned lm_resp_len,
+                            unsigned char *nt_resp, unsigned nt_resp_len)
+{
+    SMB_Header hdr;
+    SMB_SessionSetup setup;
+    SMB_SessionSetup_Resp resp;
+    unsigned char hbuf[SMB_HDR_SIZE], sbuf[SMB_SESSION_SETUP_SIZE], *p;
+    unsigned char wordcount = SMB_SESSION_SETUP_SIZE / sizeof(uint16);
+    unsigned char bc[sizeof(uint16)];
+    uint16 bytecount;
+    uint32 len, nl;
+    struct iovec iov[12];
+    int i, n;
+    int rc;
+#ifdef WIN32
+    char osbuf[80];
+#else
+    char osbuf[2*SYS_NMLN+2];
+#endif
+    char lanman[20];
+    pid_t current_pid;
+
+    /*** create a session setup request ***/
+
+    /* create a header */
+    memset(&hdr, 0, sizeof(hdr));
+    hdr.command = SMB_COM_SESSION_SETUP_ANDX;
+#if 0
+    hdr.flags2 = SMB_FLAGS2_ERR_STATUS;
+    if (text->flags & NTLM_USE_UNICODE) hdr.flags2 |= SMB_FLAGS2_UNICODE;
+#endif
+    current_pid = getpid();
+    if (sizeof(current_pid) <= 2) {
+       hdr.pid = (uint16) current_pid;
+       hdr.PidHigh = 0;
+    } else {
+       hdr.pid = (uint16) (((uint32) current_pid) & 0xFFFF);
+       hdr.PidHigh = (uint16) (((uint32) current_pid) >> 16);
+    }
+
+    load_smb_header(hbuf, &hdr);
+
+    /* create a the setup parameters */
+    memset(&setup, 0, sizeof(setup));
+    setup.andx_command = SMB_COM_NONE;
+    setup.max_buffer_size = 0xFFFF;
+    if (lm_resp) setup.case_insensitive_passwd_len = lm_resp_len;
+    if (nt_resp) setup.case_sensitive_passwd_len = nt_resp_len;
+#if 0
+    if (text->flags & NTLM_USE_UNICODE)
+       setup.capabilities = SMB_CAP_UNICODE;
+#endif
+    load_session_setup(sbuf, &setup);
+
+    _plug_snprintf_os_info (osbuf, sizeof(osbuf));
+
+    snprintf(lanman, sizeof(lanman), "Cyrus SASL %u.%u.%u",
+            SASL_VERSION_MAJOR, SASL_VERSION_MINOR,
+            SASL_VERSION_STEP);
+
+    /* put together all of the pieces of the request */
+    n = 0;
+    iov[n].iov_base = (void *) &nl;
+    iov[n++].iov_len = sizeof(len);
+    iov[n].iov_base = hbuf;
+    iov[n++].iov_len = SMB_HDR_SIZE;
+    iov[n].iov_base = &wordcount;
+    iov[n++].iov_len = sizeof(wordcount);
+    iov[n].iov_base = sbuf;
+    iov[n++].iov_len = SMB_SESSION_SETUP_SIZE;
+    iov[n].iov_base = (void *) &bc;
+    iov[n++].iov_len = sizeof(bc);
+    if (lm_resp) {
+       iov[n].iov_base = lm_resp;
+       iov[n++].iov_len = NTLM_RESP_LENGTH;
+    }
+    if (nt_resp) {
+       iov[n].iov_base = nt_resp;
+       iov[n++].iov_len = NTLM_RESP_LENGTH;
+    }
+    iov[n].iov_base = (char*) authid;
+    iov[n++].iov_len = (long) strlen(authid) + 1;
+    if (!domain) domain = "";
+    iov[n].iov_base = domain;
+    iov[n++].iov_len = (long) strlen(domain) + 1;
+    iov[n].iov_base = osbuf;
+    iov[n++].iov_len = (long) strlen(osbuf) + 1;
+    iov[n].iov_base = lanman;
+    iov[n++].iov_len = (long) strlen(lanman) + 1;
+
+    /* total up the lengths */
+    len = bytecount = 0;
+    for (i = 1; i < 5; i++) len += iov[i].iov_len;
+    for (i = 5; i < n; i++) bytecount += (uint16) iov[i].iov_len;
+    len += bytecount;
+    nl = htonl(len);
+    htois((char *) &bc, bytecount);
+
+    /* send it */
+    rc = retry_writev(text->sock, iov, n);
+    if (rc == -1) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error sending SESSIONSETUP request");
+       return SASL_FAIL;
+    }
+
+    /*** read the session setup response ***/
+
+    /* read the total length */
+    rc = retry_read(text->sock, (char *) &nl, sizeof(nl));
+    if (rc < (int) sizeof(nl)) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error reading SESSIONSETUP response length");
+       return SASL_FAIL;
+    }
+
+    /* read the data */
+    len = ntohl(nl);
+    if (_plug_buf_alloc(utils, &text->out_buf, &text->out_buf_len,
+                       len) != SASL_OK) {
+       SETERROR(utils,
+                "cannot allocate NTLM SESSIONSETUP response buffer");
+       return SASL_NOMEM;
+    }
+
+    rc = retry_read(text->sock, text->out_buf, len);
+    if (rc < (int) len) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error reading SESSIONSETUP response");
+       return SASL_FAIL;
+    }
+    p = text->out_buf;
+
+    /* parse the header */
+    if (len < SMB_HDR_SIZE) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: not enough data for SESSIONSETUP response header");
+       return SASL_FAIL;
+    }
+    unload_smb_header(p, &hdr);
+    p += SMB_HDR_SIZE;
+    len -= SMB_HDR_SIZE;
+
+    /* sanity check the header */
+    if (memcmp(hdr.protocol, SMB_HDR_PROTOCOL, 4)      /* correct protocol */
+       || hdr.command != SMB_COM_SESSION_SETUP_ANDX    /* correct command */
+       || !(hdr.flags & SMB_FLAGS_SERVER_TO_REDIR)) {  /* response */
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: error in SESSIONSETUP response header");
+       return SASL_FAIL;
+    }
+
+    /* check auth success */
+    if (hdr.status) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: auth failure: %ld", hdr.status);
+       return SASL_BADAUTH;
+    }
+
+    /* get the wordcount */
+    if (len < 1) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: not enough data for SESSIONSETUP response wordcount");
+       return SASL_FAIL;
+    }
+    wordcount = *p++;
+    len--;
+
+    /* parse the parameters */
+    if (wordcount < SMB_SESSION_SETUP_RESP_SIZE / sizeof(uint16)) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: incorrect SESSIONSETUP wordcount");
+       return SASL_FAIL;
+    }
+    unload_session_setup_resp(p, &resp);
+
+    /* check auth success */
+    if (resp.action & SMB_REQUEST_MODE_GUEST) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "NTLM: authenticated as guest");
+       return SASL_BADAUTH;
+    }
+
+    return SASL_OK;
+}
+
+/*
+ * Create a server challenge message (type 2) consisting of:
+ *
+ * signature (8 bytes)
+ * message type (uint32)
+ * target name (buffer)
+ * flags (uint32)
+ * challenge (8 bytes)
+ * context (8 bytes)
+ * target info (buffer)
+ * data
+ */
+static int create_challenge(const sasl_utils_t *utils,
+                           char **buf, unsigned *buflen,
+                           const char *target, uint32 flags,
+                           const u_char *nonce, unsigned *outlen)
+{
+    uint32 offset = NTLM_TYPE2_DATA_OFFSET;
+    u_char *base;
+
+    if (!nonce) {
+       SETERROR(utils, "need nonce for NTLM challenge");
+       return SASL_FAIL;
+    }
+
+    *outlen = offset + 2 * xstrlen(target);
+
+    if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) {
+       SETERROR(utils, "cannot allocate NTLM challenge");
+       return SASL_NOMEM;
+    }
+
+    base = *buf;
+    memset(base, 0, *outlen);
+    memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));
+    htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_CHALLENGE);
+    load_buffer(base + NTLM_TYPE2_TARGET_OFFSET,
+               ucase(target, 0), (uint16) xstrlen(target), flags & NTLM_USE_UNICODE,
+               base, &offset);
+    htoil(base + NTLM_TYPE2_FLAGS_OFFSET, flags);
+    memcpy(base + NTLM_TYPE2_CHALLENGE_OFFSET, nonce, NTLM_NONCE_LENGTH);
+
+    return SASL_OK;
+}
+
+static int ntlm_server_mech_new(void *glob_context __attribute__((unused)), 
+                               sasl_server_params_t *sparams,
+                               const char *challenge __attribute__((unused)),
+                               unsigned challen __attribute__((unused)),
+                               void **conn_context)
+{
+    server_context_t *text;
+    const char *serv;
+    unsigned int len;
+    SOCKET sock = (SOCKET) -1;
+
+    sparams->utils->getopt(sparams->utils->getopt_context,
+                          "NTLM", "ntlm_server", &serv, &len);
+    if (serv) {
+       /* try to start a NetBIOS session with the server */
+       sock = smb_connect_server(sparams->utils, sparams->serverFQDN, serv);
+       if (sock == (SOCKET) -1) return SASL_UNAVAIL;
+    }
+    
+    /* holds state are in */
+    text = sparams->utils->malloc(sizeof(server_context_t));
+    if (text == NULL) {
+       MEMERROR( sparams->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(server_context_t));
+    
+    text->state = 1;
+    text->sock = sock;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int ntlm_server_mech_step1(server_context_t *text,
+                                 sasl_server_params_t *sparams,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen,
+                                 sasl_out_params_t *oparams __attribute__((unused)))
+{
+    char *domain = NULL;
+    int result;
+
+    if (!clientin || clientinlen < NTLM_TYPE1_MINSIZE ||
+       memcmp(clientin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) ||
+       itohl(clientin + NTLM_TYPE_OFFSET) != NTLM_TYPE_REQUEST) {
+       SETERROR(sparams->utils, "client didn't issue valid NTLM request");
+       return SASL_BADPROT;
+    }
+
+    text->flags = itohl(clientin + NTLM_TYPE1_FLAGS_OFFSET);
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "client flags: %x", text->flags);
+
+    text->flags &= NTLM_FLAGS_MASK; /* mask off the bits we don't support */
+
+    /* if client can do Unicode, turn off ASCII */
+    if (text->flags & NTLM_USE_UNICODE) text->flags &= ~NTLM_USE_ASCII;
+
+    if (text->sock == -1) {
+       /* generate challenge internally */
+
+       /* if client asked for target, use FQDN as server target */
+       if (text->flags & NTLM_ASK_TARGET) {
+           result = _plug_strdup(sparams->utils, sparams->serverFQDN,
+                             &domain, NULL);
+           if (result != SASL_OK) return result;
+
+           text->flags |= NTLM_TARGET_IS_SERVER;
+       }
+
+       /* generate a nonce */
+       sparams->utils->rand(sparams->utils->rpool,
+                            (char *) text->nonce, NTLM_NONCE_LENGTH);
+    }
+    else {
+       /* proxy the response/challenge */
+       result = smb_negotiate_protocol(sparams->utils, text, &domain);
+       if (result != SASL_OK) goto cleanup;
+    }
+
+    result = create_challenge(sparams->utils,
+                             &text->out_buf, &text->out_buf_len,
+                             domain, text->flags, text->nonce, serveroutlen);
+    if (result != SASL_OK) goto cleanup;
+
+    *serverout = text->out_buf;
+
+    text->state = 2;
+    
+    result = SASL_CONTINUE;
+
+  cleanup:
+    if (domain) sparams->utils->free(domain);
+
+    return result;
+}
+
+static int ntlm_server_mech_step2(server_context_t *text,
+                                 sasl_server_params_t *sparams,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout __attribute__((unused)),
+                                 unsigned *serveroutlen __attribute__((unused)),
+                                 sasl_out_params_t *oparams)
+{
+    unsigned char *lm_resp = NULL, *nt_resp = NULL;
+    char *domain = NULL, *authid = NULL;
+    unsigned lm_resp_len, nt_resp_len, domain_len, authid_len;
+    int result;
+
+    if (!clientin || clientinlen < NTLM_TYPE3_MINSIZE ||
+       memcmp(clientin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) ||
+       itohl(clientin + NTLM_TYPE_OFFSET) != NTLM_TYPE_RESPONSE) {
+       SETERROR(sparams->utils, "client didn't issue valid NTLM response");
+       return SASL_BADPROT;
+    }
+
+    result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_LMRESP_OFFSET,
+                          (u_char **) &lm_resp, &lm_resp_len, 0,
+                          clientin, clientinlen);
+    if (result != SASL_OK) goto cleanup;
+
+    result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_NTRESP_OFFSET,
+                          (u_char **) &nt_resp, &nt_resp_len, 0,
+                          clientin, clientinlen);
+    if (result != SASL_OK) goto cleanup;
+
+    result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_DOMAIN_OFFSET,
+                          (u_char **) &domain, &domain_len,
+                          text->flags & NTLM_USE_UNICODE,
+                          clientin, clientinlen);
+    if (result != SASL_OK) goto cleanup;
+
+    result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_USER_OFFSET,
+                          (u_char **) &authid, &authid_len,
+                          text->flags & NTLM_USE_UNICODE,
+                          clientin, clientinlen);
+    if (result != SASL_OK) goto cleanup;
+
+    /* require at least one response and an authid */
+    if ((!lm_resp && !nt_resp) ||
+       (lm_resp && lm_resp_len < NTLM_RESP_LENGTH) ||
+       (nt_resp && nt_resp_len < NTLM_RESP_LENGTH) ||
+       !authid) {
+       SETERROR(sparams->utils, "client issued incorrect/nonexistent responses");
+       result = SASL_BADPROT;
+       goto cleanup;
+    }
+
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "client user: %s", authid);
+    if (domain) sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                                   "client domain: %s", domain);
+
+    if (text->sock == -1) {
+       /* verify the response internally */
+
+       sasl_secret_t *password = NULL;
+       size_t pass_len;
+       const char *password_request[] = { SASL_AUX_PASSWORD,
+                                      NULL };
+       struct propval auxprop_values[2];
+       unsigned char hash[NTLM_HASH_LENGTH];
+       unsigned char resp[NTLM_RESP_LENGTH];
+
+       /* fetch user's password */
+       result = sparams->utils->prop_request(sparams->propctx, password_request);
+       if (result != SASL_OK) goto cleanup;
+    
+       /* this will trigger the getting of the aux properties */
+       result = sparams->canon_user(sparams->utils->conn, authid, authid_len,
+                                    SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) goto cleanup;
+
+       result = sparams->utils->prop_getnames(sparams->propctx,
+                                              password_request,
+                                              auxprop_values);
+       if (result < 0 ||
+           (!auxprop_values[0].name || !auxprop_values[0].values)) {
+           /* We didn't find this username */
+           SETERROR(sparams->utils, "no secret in database");
+           result = sparams->transition ? SASL_TRANS : SASL_NOUSER;
+           goto cleanup;
+       }
+    
+       pass_len = strlen(auxprop_values[0].values[0]);
+       if (pass_len == 0) {
+           SETERROR(sparams->utils, "empty secret");
+           result = SASL_FAIL;
+           goto cleanup;
+       }
+
+       password = sparams->utils->malloc(sizeof(sasl_secret_t) + pass_len);
+       if (!password) {
+           result = SASL_NOMEM;
+           goto cleanup;
+       }
+       
+       password->len = (unsigned) pass_len;
+       strncpy(password->data, auxprop_values[0].values[0], pass_len + 1);
+
+       /* erase the plaintext password */
+       sparams->utils->prop_erase(sparams->propctx, password_request[0]);
+
+       /* calculate our own response(s) and compare with client's */
+       result = SASL_OK;
+       if (nt_resp && (nt_resp_len > NTLM_RESP_LENGTH)) {
+           /* Try NTv2 response */
+           sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                               "calculating NTv2 response");
+           V2(resp, password, authid, domain, text->nonce,
+              lm_resp + MD5_DIGEST_LENGTH, nt_resp_len - MD5_DIGEST_LENGTH,
+              sparams->utils, &text->out_buf, &text->out_buf_len,
+              &result);
+
+           /* No need to compare the blob */
+           if (memcmp(nt_resp, resp, MD5_DIGEST_LENGTH)) {
+               SETERROR(sparams->utils, "incorrect NTLMv2 response");
+               result = SASL_BADAUTH;
+           }
+       }
+       else if (nt_resp) {
+           /* Try NT response */
+           sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                               "calculating NT response");
+           P24(resp, P21(hash, password, P16_nt, sparams->utils,
+                         &text->out_buf, &text->out_buf_len, &result),
+               text->nonce);
+           if (memcmp(nt_resp, resp, NTLM_RESP_LENGTH)) {
+               SETERROR(sparams->utils, "incorrect NTLM response");
+               result = SASL_BADAUTH;
+           }
+       }
+       else if (lm_resp) {
+           /* Try LMv2 response */
+           sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                               "calculating LMv2 response");
+           V2(resp, password, authid, domain, text->nonce,
+              lm_resp + MD5_DIGEST_LENGTH, lm_resp_len - MD5_DIGEST_LENGTH,
+              sparams->utils, &text->out_buf, &text->out_buf_len,
+              &result);
+               
+           /* No need to compare the blob */
+           if (memcmp(lm_resp, resp, MD5_DIGEST_LENGTH)) {
+               /* Try LM response */
+               sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                                   "calculating LM response");
+               P24(resp, P21(hash, password, P16_lm, sparams->utils,
+                             &text->out_buf, &text->out_buf_len, &result),
+                   text->nonce);
+               if (memcmp(lm_resp, resp, NTLM_RESP_LENGTH)) {
+                   SETERROR(sparams->utils, "incorrect LMv1/v2 response");
+                   result = SASL_BADAUTH;
+               }
+           }
+       }
+
+       _plug_free_secret(sparams->utils, &password);
+
+       if (result != SASL_OK) goto cleanup;
+    }
+    else {
+       /* proxy the response */
+       result = smb_session_setup(sparams->utils, text, authid, domain,
+                                  lm_resp, lm_resp_len, nt_resp, nt_resp_len);
+       if (result != SASL_OK) goto cleanup;
+
+       result = sparams->canon_user(sparams->utils->conn, authid, authid_len,
+                                    SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) goto cleanup;
+    }
+
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+
+    result = SASL_OK;
+
+  cleanup:
+    if (lm_resp) sparams->utils->free(lm_resp);
+    if (nt_resp) sparams->utils->free(nt_resp);
+    if (domain) sparams->utils->free(domain);
+    if (authid) sparams->utils->free(authid);
+
+    return result;
+}
+
+static int ntlm_server_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)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                      "NTLM server step %d\n", text->state);
+
+    switch (text->state) {
+       
+    case 1:
+       return ntlm_server_mech_step1(text, sparams, clientin, clientinlen,
+                                     serverout, serveroutlen, oparams);
+       
+    case 2:
+       return ntlm_server_mech_step2(text, sparams, clientin, clientinlen,
+                                     serverout, serveroutlen, oparams);
+       
+    default:
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid NTLM server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void ntlm_server_mech_dispose(void *conn_context,
+                                    const sasl_utils_t *utils)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    if (text->sock != -1) closesocket(text->sock);
+
+    utils->free(text);
+}
+
+static sasl_server_plug_t ntlm_server_plugins[] = 
+{
+    {
+       "NTLM",                         /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST,    /* features */
+       NULL,                           /* glob_context */
+       &ntlm_server_mech_new,          /* mech_new */
+       &ntlm_server_mech_step,         /* mech_step */
+       &ntlm_server_mech_dispose,      /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int ntlm_server_plug_init(sasl_utils_t *utils,
+                         int maxversion,
+                         int *out_version,
+                         sasl_server_plug_t **pluglist,
+                         int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "NTLM version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = ntlm_server_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    int state;
+
+    /* per-step mem management */
+    char *out_buf;
+    unsigned out_buf_len;
+
+} client_context_t;
+
+/*
+ * Create a client request (type 1) consisting of:
+ *
+ * signature (8 bytes)
+ * message type (uint32)
+ * flags (uint32)
+ * domain (buffer)
+ * workstation (buffer)
+ * data
+ */
+static int create_request(const sasl_utils_t *utils,
+                         char **buf, unsigned *buflen,
+                         const char *domain, const char *wkstn,
+                         unsigned *outlen)
+{
+    uint32 flags = ( NTLM_USE_UNICODE | NTLM_USE_ASCII |
+                    NTLM_ASK_TARGET | NTLM_AUTH_NTLM );
+    uint32 offset = NTLM_TYPE1_DATA_OFFSET;
+    u_char *base;
+
+    *outlen = offset + xstrlen(domain) + xstrlen(wkstn);
+    if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) {
+       SETERROR(utils, "cannot allocate NTLM request");
+       return SASL_NOMEM;
+    }
+
+    base = *buf;
+    memset(base, 0, *outlen);
+    memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));
+    htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_REQUEST);
+    htoil(base + NTLM_TYPE1_FLAGS_OFFSET, flags);
+    load_buffer(base + NTLM_TYPE1_DOMAIN_OFFSET,
+               domain, (uint16) xstrlen(domain), 0, base, &offset);
+    load_buffer(base + NTLM_TYPE1_WORKSTN_OFFSET,
+               wkstn, (uint16) xstrlen(wkstn), 0, base, &offset);
+
+    return SASL_OK;
+}
+
+/*
+ * Create a client response (type 3) consisting of:
+ *
+ * signature (8 bytes)
+ * message type (uint32)
+ * LM/LMv2 response (buffer)
+ * NTLM/NTLMv2 response (buffer)
+ * domain (buffer)
+ * user name (buffer)
+ * workstation (buffer)
+ * session key (buffer)
+ * flags (uint32)
+ * data
+ */
+static int create_response(const sasl_utils_t *utils,
+                          char **buf, unsigned *buflen,
+                          const u_char *lm_resp, const u_char *nt_resp,
+                          const char *domain, const char *user,
+                          const char *wkstn, const u_char *key,
+                          uint32 flags, unsigned *outlen)
+{
+    uint32 offset = NTLM_TYPE3_DATA_OFFSET;
+    u_char *base;
+
+    if (!lm_resp && !nt_resp) {
+       SETERROR(utils, "need at least one NT/LM response");
+       return SASL_FAIL;
+    }
+
+    *outlen = offset + (flags & NTLM_USE_UNICODE ? 2 : 1) * 
+       (xstrlen(domain) + xstrlen(user) + xstrlen(wkstn));
+    if (lm_resp) *outlen += NTLM_RESP_LENGTH;
+    if (nt_resp) *outlen += NTLM_RESP_LENGTH;
+    if (key) *outlen += NTLM_SESSKEY_LENGTH;
+
+    if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) {
+       SETERROR(utils, "cannot allocate NTLM response");
+       return SASL_NOMEM;
+    }
+
+    base = *buf;
+    memset(base, 0, *outlen);
+    memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));
+    htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_RESPONSE);
+    load_buffer(base + NTLM_TYPE3_LMRESP_OFFSET,
+               lm_resp, lm_resp ? NTLM_RESP_LENGTH : 0, 0, base, &offset);
+    load_buffer(base + NTLM_TYPE3_NTRESP_OFFSET,
+               nt_resp, nt_resp ? NTLM_RESP_LENGTH : 0, 0, base, &offset);
+    load_buffer(base + NTLM_TYPE3_DOMAIN_OFFSET,
+               ucase(domain, 0), (uint16) xstrlen(domain), flags & NTLM_USE_UNICODE,
+               base, &offset);
+    load_buffer(base + NTLM_TYPE3_USER_OFFSET,
+               user, (uint16) xstrlen(user), flags & NTLM_USE_UNICODE, base, &offset);
+    load_buffer(base + NTLM_TYPE3_WORKSTN_OFFSET,
+               ucase(wkstn, 0), (uint16) xstrlen(wkstn), flags & NTLM_USE_UNICODE,
+               base, &offset);
+    load_buffer(base + NTLM_TYPE3_SESSIONKEY_OFFSET,
+               key, key ? NTLM_SESSKEY_LENGTH : 0, 0, base, &offset);
+    htoil(base + NTLM_TYPE3_FLAGS_OFFSET, flags);
+
+    return SASL_OK;
+}
+
+static int ntlm_client_mech_new(void *glob_context __attribute__((unused)),
+                              sasl_client_params_t *params,
+                              void **conn_context)
+{
+    client_context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR( params->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int ntlm_client_mech_step1(client_context_t *text,
+                                 sasl_client_params_t *params,
+                                 const char *serverin __attribute__((unused)),
+                                 unsigned serverinlen __attribute__((unused)),
+                                 sasl_interact_t **prompt_need __attribute__((unused)),
+                                 const char **clientout,
+                                 unsigned *clientoutlen,
+                                 sasl_out_params_t *oparams __attribute__((unused)))
+{
+    int result;
+    
+    /* check if sec layer strong enough */
+    if (params->props.min_ssf > params->external_ssf) {
+       SETERROR(params->utils, "SSF requested of NTLM plugin");
+       return SASL_TOOWEAK;
+    }
+
+    /* we don't care about domain or wkstn */
+    result = create_request(params->utils, &text->out_buf, &text->out_buf_len,
+                           NULL, NULL, clientoutlen);
+    if (result != SASL_OK) return result;
+
+    *clientout = text->out_buf;
+    
+    text->state = 2;
+    
+    return SASL_CONTINUE;
+}
+
+static int ntlm_client_mech_step2(client_context_t *text,
+                                 sasl_client_params_t *params,
+                                 const char *serverin,
+                                 unsigned serverinlen,
+                                 sasl_interact_t **prompt_need,
+                                 const char **clientout,
+                                 unsigned *clientoutlen,
+                                 sasl_out_params_t *oparams)
+{
+    const char *authid = NULL;
+    sasl_secret_t *password = NULL;
+    unsigned int free_password; /* set if we need to free password */
+    char *domain = NULL;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    uint32 flags = 0;
+    unsigned char hash[NTLM_HASH_LENGTH];
+    unsigned char resp[NTLM_RESP_LENGTH], *lm_resp = NULL, *nt_resp = NULL;
+    int result;
+    const char *sendv2;
+
+    if (!serverin || serverinlen < NTLM_TYPE2_MINSIZE ||
+       memcmp(serverin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) ||
+       itohl(serverin + NTLM_TYPE_OFFSET) != NTLM_TYPE_CHALLENGE) {
+       SETERROR(params->utils, "server didn't issue valid NTLM challenge");
+       return SASL_BADPROT;
+    }
+
+    /* try to get the authid */
+    if (oparams->authid == NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }
+    
+    /* try to get the password */
+    if (password == NULL) {
+       pass_result = _plug_get_password(params->utils, &password,
+                                        &free_password, prompt_need);
+       
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              NULL, NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) goto cleanup;
+       
+       return SASL_INTERACT;
+    }
+    
+    result = params->canon_user(params->utils->conn, authid, 0,
+                               SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) goto cleanup;
+
+    flags = itohl(serverin + NTLM_TYPE2_FLAGS_OFFSET);
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "server flags: %x", flags);
+
+    flags &= NTLM_FLAGS_MASK; /* mask off the bits we don't support */
+
+    result = unload_buffer(params->utils, serverin + NTLM_TYPE2_TARGET_OFFSET,
+                          (u_char **) &domain, NULL,
+                          flags & NTLM_USE_UNICODE,
+                          (u_char *) serverin, serverinlen);
+    if (result != SASL_OK) goto cleanup;
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "server domain: %s", domain);
+
+    /* should we send a NTLMv2 response? */
+    params->utils->getopt(params->utils->getopt_context,
+                         "NTLM", "ntlm_v2", &sendv2, NULL);
+    if (sendv2 &&
+       (*sendv2 == '1' || *sendv2 == 'y' ||
+        (*sendv2 == 'o' && *sendv2 == 'n') || *sendv2 == 't')) {
+
+       /* put the cnonce in place after the LMv2 HMAC */
+       char *cnonce = resp + MD5_DIGEST_LENGTH;
+
+       params->utils->log(NULL, SASL_LOG_DEBUG,
+                          "calculating LMv2 response");
+
+       params->utils->rand(params->utils->rpool, cnonce, NTLM_NONCE_LENGTH);
+
+       V2(resp, password, oparams->authid, domain,
+          serverin + NTLM_TYPE2_CHALLENGE_OFFSET, cnonce, NTLM_NONCE_LENGTH,
+          params->utils, &text->out_buf, &text->out_buf_len, &result);
+
+       lm_resp = resp;
+    }
+    else if (flags & NTLM_AUTH_NTLM) {
+       params->utils->log(NULL, SASL_LOG_DEBUG,
+                          "calculating NT response");
+       P24(resp, P21(hash, password, P16_nt, params->utils,
+                     &text->out_buf, &text->out_buf_len, &result),
+           (unsigned char *) serverin + NTLM_TYPE2_CHALLENGE_OFFSET);
+       nt_resp = resp;
+    }
+    else {
+       params->utils->log(NULL, SASL_LOG_DEBUG,
+                          "calculating LM response");
+       P24(resp, P21(hash, password, P16_lm, params->utils,
+                     &text->out_buf, &text->out_buf_len, &result),
+           (unsigned char *) serverin + NTLM_TYPE2_CHALLENGE_OFFSET);
+       lm_resp = resp;
+    }
+    if (result != SASL_OK) goto cleanup;
+
+    /* we don't care about workstn or session key */
+    result = create_response(params->utils, &text->out_buf, &text->out_buf_len,
+                            lm_resp, nt_resp, domain, oparams->authid,
+                            NULL, NULL, flags, clientoutlen);
+    if (result != SASL_OK) goto cleanup;
+
+    *clientout = text->out_buf;
+
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    result = SASL_OK;
+
+  cleanup:
+    if (domain) params->utils->free(domain);
+    if (free_password) _plug_free_secret(params->utils, &password);
+
+    return result;
+}
+
+static int ntlm_client_mech_step(void *conn_context,
+                               sasl_client_params_t *params,
+                               const char *serverin,
+                               unsigned serverinlen,
+                               sasl_interact_t **prompt_need,
+                               const char **clientout,
+                               unsigned *clientoutlen,
+                               sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "NTLM client step %d\n", text->state);
+
+    switch (text->state) {
+       
+    case 1:
+       return ntlm_client_mech_step1(text, params, serverin, serverinlen,
+                                     prompt_need, clientout, clientoutlen,
+                                     oparams);
+       
+    case 2:
+       return ntlm_client_mech_step2(text, params, serverin, serverinlen,
+                                     prompt_need, clientout, clientoutlen,
+                                     oparams);
+       
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid NTLM client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void ntlm_client_mech_dispose(void *conn_context,
+                                   const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static sasl_client_plug_t ntlm_client_plugins[] = 
+{
+    {
+       "NTLM",                         /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST,    /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &ntlm_client_mech_new,          /* mech_new */
+       &ntlm_client_mech_step,         /* mech_step */
+       &ntlm_client_mech_dispose,      /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int ntlm_client_plug_init(sasl_utils_t *utils,
+                        int maxversion,
+                        int *out_version,
+                        sasl_client_plug_t **pluglist,
+                        int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "NTLM version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = ntlm_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/ntlm_init.c b/plugins/ntlm_init.c
new file mode 100644 (file)
index 0000000..a336fda
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_ntlm_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( ntlm )
+SASL_SERVER_PLUG_INIT( ntlm )
+
diff --git a/plugins/otp.c b/plugins/otp.c
new file mode 100644 (file)
index 0000000..0a249c2
--- /dev/null
@@ -0,0 +1,1830 @@
+/* OTP SASL plugin
+ * Ken Murchison
+ * $Id: otp.c,v 1.36 2004/06/23 18:43:37 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <errno.h>
+#include <string.h> 
+#include <ctype.h>
+#include <assert.h>
+
+#include <openssl/evp.h>
+#include <openssl/md5.h> /* XXX hack for OpenBSD/OpenSSL cruftiness */
+
+#include <sasl.h>
+#define MD5_H  /* suppress internal MD5 */
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh 
+#include <sasl_otp_plugin_decl.h> 
+#endif 
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: otp.c,v 1.36 2004/06/23 18:43:37 rjs3 Exp $";
+
+#define OTP_SEQUENCE_MAX       9999
+#define OTP_SEQUENCE_DEFAULT   499
+#define OTP_SEQUENCE_REINIT    490
+#define OTP_SEED_MIN           1
+#define OTP_SEED_MAX           16
+#define OTP_HASH_SIZE          8               /* 64 bits */
+#define OTP_CHALLENGE_MAX      100
+#define OTP_RESPONSE_MAX       100
+#define OTP_HEX_TYPE           "hex:"
+#define OTP_WORD_TYPE          "word:"
+#define OTP_INIT_HEX_TYPE      "init-hex:"
+#define OTP_INIT_WORD_TYPE     "init-word:"
+
+typedef struct algorithm_option_s {
+    const char *name;          /* name used in challenge/response */
+    int swab;                  /* number of bytes to swab (0, 1, 2, 4, 8) */
+    const char *evp_name;      /* name used for lookup in EVP table */
+} algorithm_option_t;
+
+static algorithm_option_t algorithm_options[] = {
+    {"md4",    0,      "md4"},
+    {"md5",    0,      "md5"},
+    {"sha1",   4,      "sha1"},
+    {NULL,     0,      NULL}
+};
+
+/* Convert the binary data into ASCII hex */
+void bin2hex(unsigned char *bin, int binlen, char *hex)
+{
+    int i;
+    unsigned char c;
+    
+    for (i = 0; i < binlen; i++) {
+       c = (bin[i] >> 4) & 0xf;
+       hex[i*2] = (c > 9) ? ('a' + c - 10) : ('0' + c);
+       c = bin[i] & 0xf;
+       hex[i*2+1] = (c > 9) ? ('a' + c - 10) : ('0' + c);
+    }
+    hex[i*2] = '\0';
+}
+
+/*
+ * Hash the data using the given algorithm and fold it into 64 bits,
+ * swabbing bytes if necessary.
+ */
+static void otp_hash(const EVP_MD *md, char *in, int inlen,
+                    unsigned char *out, int swab)
+{
+    EVP_MD_CTX mdctx;
+    char hash[EVP_MAX_MD_SIZE];
+    int i, j, hashlen;
+    
+    EVP_DigestInit(&mdctx, md);
+    EVP_DigestUpdate(&mdctx, in, inlen);
+    EVP_DigestFinal(&mdctx, hash, &hashlen);
+    
+    /* Fold the result into 64 bits */
+    for (i = OTP_HASH_SIZE; i < hashlen; i++) {
+       hash[i % OTP_HASH_SIZE] ^= hash[i];
+    }
+    
+    /* Swab bytes */
+    if (swab) {
+       for (i = 0; i < OTP_HASH_SIZE;) {
+           for (j = swab-1; j > -swab; i++, j-=2)
+               out[i] = hash[i+j];
+       }
+    }
+    else
+       memcpy(out, hash, OTP_HASH_SIZE);
+}
+
+static int generate_otp(const sasl_utils_t *utils,
+                       algorithm_option_t *alg, unsigned seq, char *seed,
+                       char *secret, char *otp)
+{
+    const EVP_MD *md;
+    char *key;
+    
+    if (!(md = EVP_get_digestbyname(alg->evp_name))) {
+       utils->seterror(utils->conn, 0,
+                       "OTP algorithm %s is not available", alg->evp_name);
+       return SASL_FAIL;
+    }
+    
+    if ((key = utils->malloc(strlen(seed) + strlen(secret) + 1)) == NULL) {
+       SETERROR(utils, "cannot allocate OTP key");
+       return SASL_NOMEM;
+    }
+    
+    /* initial step */
+    strcpy(key, seed);
+    strcat(key, secret);
+    otp_hash(md, key, strlen(key), otp, alg->swab);
+    
+    /* computation step */
+    while (seq-- > 0)
+       otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab);
+    
+    utils->free(key);
+    
+    return SASL_OK;
+}
+
+static int parse_challenge(const sasl_utils_t *utils,
+                          char *chal, algorithm_option_t **alg,
+                          unsigned *seq, char *seed, int is_init)
+{
+    char *c;
+    algorithm_option_t *opt;
+    int n;
+    
+    c = chal;
+    
+    /* eat leading whitespace */
+    while (*c && isspace((int) *c)) c++;
+    
+    if (!is_init) {
+       /* check the prefix */
+       if (!*c || strncmp(c, "otp-", 4)) {
+           SETERROR(utils, "not a OTP challenge");
+           return SASL_BADPROT;
+       }
+       
+       /* skip the prefix */
+       c += 4;
+    }
+    
+    /* find the algorithm */
+    opt = algorithm_options;
+    while (opt->name) {
+       if (!strncmp(c, opt->name, strlen(opt->name))) {
+           break;
+       }
+       opt++;
+    }
+    
+    /* didn't find the algorithm in our list */
+    if (!opt->name) {
+       utils->seterror(utils->conn, 0, "OTP algorithm '%s' not supported", c);
+       return SASL_BADPROT;
+    }
+    
+    /* skip algorithm name */
+    c += strlen(opt->name);
+    *alg = opt;
+    
+    /* eat whitespace */
+    if (!isspace((int) *c)) {
+       SETERROR(utils, "no whitespace between OTP algorithm and sequence");
+       return SASL_BADPROT;
+    }
+    while (*c && isspace((int) *c)) c++;
+    
+    /* grab the sequence */
+    if ((*seq = strtoul(c, &c, 10)) > OTP_SEQUENCE_MAX) {
+       utils->seterror(utils->conn, 0, "sequence > %u", OTP_SEQUENCE_MAX);
+       return SASL_BADPROT;
+    }
+    
+    /* eat whitespace */
+    if (!isspace((int) *c)) {
+       SETERROR(utils, "no whitespace between OTP sequence and seed");
+       return SASL_BADPROT;
+    }
+    while (*c && isspace((int) *c)) c++;
+    
+    /* grab the seed, converting to lowercase as we go */
+    n = 0;
+    while (*c && isalnum((int) *c) && (n < OTP_SEED_MAX))
+       seed[n++] = tolower((int) *c++);
+    if (n > OTP_SEED_MAX) {
+       utils->seterror(utils->conn, 0, "OTP seed length > %u", OTP_SEED_MAX);
+       return SASL_BADPROT;
+    }
+    else if (n < OTP_SEED_MIN) {
+       utils->seterror(utils->conn, 0, "OTP seed length < %u", OTP_SEED_MIN);
+       return SASL_BADPROT;
+    }
+    seed[n] = '\0';
+    
+    if (!is_init) {
+       /* eat whitespace */
+       if (!isspace((int) *c)) {
+           SETERROR(utils, "no whitespace between OTP seed and extensions");
+           return SASL_BADPROT;
+       }
+       while (*c && isspace((int) *c)) c++;
+       
+       /* make sure this is an extended challenge */
+       if (strncmp(c, "ext", 3) ||
+           (*(c+=3) &&
+            !(isspace((int) *c) || (*c == ',') ||
+              (*c == '\r') || (*c == '\n')))) {
+           SETERROR(utils, "not an OTP extended challenge");
+           return SASL_BADPROT;
+       }
+    }
+    
+    return SASL_OK;
+}
+
+static void
+otp_common_mech_free(void *global_context __attribute__((unused)),
+                    const sasl_utils_t *utils __attribute__((unused)))
+{
+    EVP_cleanup();
+}
+
+/*****************************  Server Section  *****************************/
+
+#ifdef  HAVE_OPIE
+#include <opie.h>
+#endif
+
+typedef struct server_context {
+    int state;
+
+    char *authid;
+    int locked;                                /* is the user's secret locked? */
+    algorithm_option_t *alg;
+#ifdef HAVE_OPIE
+    struct opie opie;
+#else
+    char *realm;
+    unsigned seq;
+    char seed[OTP_SEED_MAX+1];
+    unsigned char otp[OTP_HASH_SIZE];
+    time_t timestamp;                  /* time we locked the secret */
+#endif /* HAVE_OPIE */
+
+    char *out_buf;
+    unsigned out_buf_len;
+} server_context_t;
+
+static int otp_server_mech_new(void *glob_context __attribute__((unused)), 
+                              sasl_server_params_t *sparams,
+                              const char *challenge __attribute__((unused)),
+                              unsigned challen __attribute__((unused)),
+                              void **conn_context)
+{
+    server_context_t *text;
+    
+    /* holds state are in */
+    text = sparams->utils->malloc(sizeof(server_context_t));
+    if (text == NULL) {
+       MEMERROR(sparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(server_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+#ifdef HAVE_OPIE
+
+#ifndef OPIE_KEYFILE
+#define OPIE_KEYFILE "/etc/opiekeys"
+#endif
+
+static int opie_server_mech_step(void *conn_context,
+                                sasl_server_params_t *params,
+                                const char *clientin,
+                                unsigned clientinlen,
+                                const char **serverout,
+                                unsigned *serveroutlen,
+                                sasl_out_params_t *oparams)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    switch (text->state) {
+
+    case 1: {
+       const char *authzid;
+       const char *authid;
+       size_t authid_len;
+       unsigned lup = 0;
+       int result;
+       
+       /* should have received authzid NUL authid */
+       
+       /* get authzid */
+       authzid = clientin;
+       while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+       
+       if (lup >= clientinlen) {
+           SETERROR(params->utils, "Can only find OTP authzid (no authid)");
+           return SASL_BADPROT;
+       }
+       
+       /* get authid */
+       ++lup;
+       authid = clientin + lup;
+       while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+       
+       authid_len = clientin + lup - authid;
+       
+       if (lup != clientinlen) {
+           SETERROR(params->utils,
+                    "Got more data than we were expecting in the OTP plugin\n");
+           return SASL_BADPROT;
+       }
+       
+       text->authid = params->utils->malloc(authid_len + 1);    
+       if (text->authid == NULL) {
+           MEMERROR(params->utils);
+           return SASL_NOMEM;
+       }
+       
+       /* we can't assume that authen is null-terminated */
+       strncpy(text->authid, authid, authid_len);
+       text->authid[authid_len] = '\0';
+       
+       result = params->canon_user(params->utils->conn, text->authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+       if (result != SASL_OK) return result;
+       
+       result = params->canon_user(params->utils->conn,
+                                   strlen(authzid) ? authzid : text->authid,
+                                   0, SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+       
+       result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                                &(text->out_buf_len), OTP_CHALLENGE_MAX+1);
+       if (result != SASL_OK) return result;
+       
+       /* create challenge - return sasl_continue on success */
+       result = opiechallenge(&text->opie, text->authid, text->out_buf);
+       
+       switch (result) {
+       case 0:
+           text->locked = 1;
+
+           *serverout = text->out_buf;
+           *serveroutlen = strlen(text->out_buf);
+
+           text->state = 2;
+           return SASL_CONTINUE;
+           
+       case 1:
+           SETERROR(params->utils, "opiechallenge: user not found or locked");
+           return SASL_NOUSER;
+           
+       default:
+           SETERROR(params->utils,
+                    "opiechallenge: system error (file, memory, I/O)");
+           return SASL_FAIL;
+       }
+    }
+    
+    case 2: {
+       char response[OPIE_RESPONSE_MAX+1];
+       int result;
+       
+       /* should have received extended response,
+          but we'll take anything that we can verify */
+       
+       if (clientinlen > OPIE_RESPONSE_MAX) {
+           SETERROR(params->utils, "response too long");
+           return SASL_BADPROT;
+       }
+       
+       /* we can't assume that the response is null-terminated */
+       strncpy(response, clientin, clientinlen);
+       response[clientinlen] = '\0';
+       
+       /* verify response */
+       result = opieverify(&text->opie, response);
+       text->locked = 0;
+       
+       switch (result) {
+       case 0:
+           /* set oparams */
+           oparams->doneflag = 1;
+           oparams->mech_ssf = 0;
+           oparams->maxoutbuf = 0;
+           oparams->encode_context = NULL;
+           oparams->encode = NULL;
+           oparams->decode_context = NULL;
+           oparams->decode = NULL;
+           oparams->param_version = 0;
+
+           return SASL_OK;
+           
+       case 1:
+           SETERROR(params->utils, "opieverify: invalid/incorrect response");
+           return SASL_BADAUTH;
+           
+       default:
+           SETERROR(params->utils,
+                    "opieverify: system error (file, memory, I/O)");
+           return SASL_FAIL;
+       }
+    }
+    
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid OTP server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+
+    return SASL_FAIL; /* should never get here */
+}
+
+static void opie_server_mech_dispose(void *conn_context,
+                                    const sasl_utils_t *utils)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    /* if we created a challenge, but bailed before the verification of the
+       response, do a verify here to release the lock on the user key */
+    if (text->locked) opieverify(&text->opie, "");
+    
+    if (text->authid) _plug_free_string(utils, &(text->authid));
+
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static int opie_mech_avail(void *glob_context __attribute__((unused)),
+                          sasl_server_params_t *sparams,
+                          void **conn_context __attribute__((unused))) 
+{
+    const char *fname;
+    unsigned int len;
+    
+    sparams->utils->getopt(sparams->utils->getopt_context,
+                          "OTP", "opiekeys", &fname, &len);
+    
+    if (!fname) fname = OPIE_KEYFILE;
+    
+    if (access(fname, R_OK|W_OK) != 0) {
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "OTP unavailable because "
+                           "can't read/write key database %s: %m",
+                           fname, errno);
+       return SASL_NOMECH;
+    }
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t otp_server_plugins[] = 
+{
+    {
+       "OTP",
+       0,
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_FORWARD_SECRECY,
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,
+       NULL,
+       &otp_server_mech_new,
+       &opie_server_mech_step,
+       &opie_server_mech_dispose,
+       &otp_common_mech_free,
+       NULL,
+       NULL,
+       NULL,
+       &opie_mech_avail,
+       NULL
+    }
+};
+#else /* HAVE_OPIE */
+
+#include "otp.h"
+
+#define OTP_MDA_DEFAULT                "md5"
+#define OTP_LOCK_TIMEOUT       5 * 60          /* 5 minutes */
+
+/* Convert the ASCII hex into binary data */
+int hex2bin(char *hex, unsigned char *bin, int binlen)
+{
+    int i;
+    char *c;
+    unsigned char msn, lsn;
+    
+    memset(bin, 0, binlen);
+    
+    for (c = hex, i = 0; i < binlen; c++) {
+       /* whitespace */
+       if (isspace((int) *c))
+           continue;
+       /* end of string, or non-hex char */
+       if (!*c || !*(c+1) || !isxdigit((int) *c))
+           break;
+       
+       msn = (*c > '9') ? tolower((int) *c) - 'a' + 10 : *c - '0';
+       c++;
+       lsn = (*c > '9') ? tolower((int) *c) - 'a' + 10 : *c - '0';
+       
+       bin[i++] = (unsigned char) (msn << 4) | lsn;
+    }
+    
+    return (i < binlen) ? SASL_BADAUTH : SASL_OK;
+}
+
+static int make_secret(const sasl_utils_t *utils,
+                      const char *alg, unsigned seq, char *seed, char *otp,
+                      time_t timeout, sasl_secret_t **secret)
+{
+    unsigned sec_len;
+    unsigned char *data;
+    char buf[2*OTP_HASH_SIZE+1];
+    
+    /*
+     * secret is stored as:
+     *
+     * <alg> \t <seq> \t <seed> \t <otp> \t <timeout> \0
+     *
+     * <timeout> is used as a "lock" when an auth is in progress
+     * we just set it to zero here (no lock)
+     */
+    sec_len = strlen(alg)+1+4+1+strlen(seed)+1+2*OTP_HASH_SIZE+1+20+1;
+    *secret = utils->malloc(sizeof(sasl_secret_t)+sec_len);
+    if (!*secret) {
+       return SASL_NOMEM;
+    }
+    
+    (*secret)->len = sec_len;
+    data = (*secret)->data;
+
+    bin2hex(otp, OTP_HASH_SIZE, buf);
+    buf[2*OTP_HASH_SIZE] = '\0';
+    
+    sprintf(data, "%s\t%04d\t%s\t%s\t%020ld",
+           alg, seq, seed, buf, timeout);
+    
+    return SASL_OK;
+}
+
+static int parse_secret(const sasl_utils_t *utils,
+                       char *secret, size_t seclen,
+                       char *alg, unsigned *seq, char *seed,
+                       unsigned char *otp,
+                       time_t *timeout)
+{
+    if (strlen(secret) < seclen) {
+       unsigned char *c;
+       
+       /*
+        * old-style (binary) secret is stored as:
+        *
+        * <alg> \0 <seq> \0 <seed> \0 <otp> <timeout>
+        *
+        */
+       
+       if (seclen < (3+1+1+1+OTP_SEED_MIN+1+OTP_HASH_SIZE+sizeof(time_t))) {
+           SETERROR(utils, "OTP secret too short");
+           return SASL_FAIL;
+       }
+       
+       c = secret;
+       
+       strcpy(alg, (char*) c);
+       c += strlen(alg)+1;
+       
+       *seq = strtoul(c, NULL, 10);
+       c += 5;
+       
+       strcpy(seed, (char*) c);
+       c += strlen(seed)+1;
+       
+       memcpy(otp, c, OTP_HASH_SIZE);
+       c += OTP_HASH_SIZE;
+       
+       memcpy(timeout, c, sizeof(time_t));
+       
+       return SASL_OK;
+    }
+
+    else {
+       char buf[2*OTP_HASH_SIZE+1];
+       
+       /*
+        * new-style (ASCII) secret is stored as:
+        *
+        * <alg> \t <seq> \t <seed> \t <otp> \t <timeout> \0
+        *
+        */
+       
+       if (seclen < (3+1+1+1+OTP_SEED_MIN+1+2*OTP_HASH_SIZE+1+20)) {
+           SETERROR(utils, "OTP secret too short");
+           return SASL_FAIL;
+       }
+       
+       sscanf(secret, "%s\t%04d\t%s\t%s\t%020ld",
+              alg, seq, seed, buf, timeout);
+       
+       hex2bin(buf, otp, OTP_HASH_SIZE);
+       
+       return SASL_OK;
+    }
+}
+
+/* Compare two string pointers */
+static int strptrcasecmp(const void *arg1, const void *arg2)
+{
+    return (strcasecmp(*((char**) arg1), *((char**) arg2)));
+}
+
+/* Convert the 6 words into binary data */
+static int word2bin(const sasl_utils_t *utils,
+                   char *words, unsigned char *bin, const EVP_MD *md)
+{
+    int i, j;
+    char *c, *word, buf[OTP_RESPONSE_MAX+1];
+    void *base;
+    int nmemb;
+    long x = 0;
+    unsigned char bits[OTP_HASH_SIZE+1]; /* 1 for checksum */
+    unsigned char chksum;
+    int bit, fbyte, lbyte;
+    const char **str_ptr;
+    int alt_dict = 0;
+    
+    /* this is a destructive operation, so make a work copy */
+    strcpy(buf, words);
+    memset(bits, 0, 9);
+    
+    for (c = buf, bit = 0, i = 0; i < 6; i++, c++, bit+=11) {
+       while (*c && isspace((int) *c)) c++;
+       word = c;
+       while (*c && isalpha((int) *c)) c++;
+       if (!*c && i < 5) break;
+       *c = '\0';
+       if (strlen(word) < 1 || strlen(word) > 4) {
+           utils->log(NULL, SASL_LOG_DEBUG,
+                      "incorrect word length '%s'", word);
+           return SASL_BADAUTH;
+       }
+       
+       /* standard dictionary */
+       if (!alt_dict) {
+           if (strlen(word) < 4) {
+               base = otp_std_dict;
+               nmemb = OTP_4LETTER_OFFSET;
+           }
+           else {
+               base = otp_std_dict + OTP_4LETTER_OFFSET;
+               nmemb = OTP_STD_DICT_SIZE - OTP_4LETTER_OFFSET;
+           }
+           
+           str_ptr = (const char**) bsearch((void*) &word, base, nmemb,
+                                            sizeof(const char*),
+                                            strptrcasecmp);
+           if (str_ptr) {
+               x = str_ptr - otp_std_dict;
+           }
+           else if (i == 0) {
+               /* couldn't find first word, try alternate dictionary */
+               alt_dict = 1;
+           }
+           else {
+               utils->log(NULL, SASL_LOG_DEBUG,
+                          "word '%s' not found in dictionary", word);
+               return SASL_BADAUTH;
+           }
+       }
+       
+       /* alternate dictionary */
+       if (alt_dict) {
+           EVP_MD_CTX mdctx;
+           char hash[EVP_MAX_MD_SIZE];
+           int hashlen;
+           
+           EVP_DigestInit(&mdctx, md);
+           EVP_DigestUpdate(&mdctx, word, strlen(word));
+           EVP_DigestFinal(&mdctx, hash, &hashlen);
+           
+           /* use lowest 11 bits */
+           x = ((hash[hashlen-2] & 0x7) << 8) | hash[hashlen-1];
+       }
+       
+       /* left align 11 bits on byte boundary */
+       x <<= (8 - ((bit+11) % 8));
+       /* first output byte containing some of our 11 bits */
+       fbyte = bit / 8;
+       /* last output byte containing some of our 11 bits */
+       lbyte = (bit+11) / 8;
+       /* populate the output bytes with the 11 bits */
+       for (j = lbyte; j >= fbyte; j--, x >>= 8)
+           bits[j] |= (unsigned char) (x & 0xff);
+    }
+    
+    if (i < 6) {
+       utils->log(NULL, SASL_LOG_DEBUG, "not enough words (%d)", i);
+       return SASL_BADAUTH;
+    }
+    
+    /* see if the 2-bit checksum is correct */
+    for (chksum = 0, i = 0; i < 8; i++) {
+       for (j = 0; j < 4; j++) {
+           chksum += ((bits[i] >> (2 * j)) & 0x3);
+       }
+    }
+    chksum <<= 6;
+    
+    if (chksum != bits[8]) {
+       utils->log(NULL, SASL_LOG_DEBUG, "incorrect parity");
+       return SASL_BADAUTH;
+    }
+    
+    memcpy(bin, bits, OTP_HASH_SIZE);
+    
+    return SASL_OK;
+}
+
+static int verify_response(server_context_t *text, const sasl_utils_t *utils,
+                          char *response)
+{
+    const EVP_MD *md;
+    char *c;
+    int do_init = 0;
+    unsigned char cur_otp[OTP_HASH_SIZE], prev_otp[OTP_HASH_SIZE];
+    int r;
+    
+    /* find the MDA */
+    if (!(md = EVP_get_digestbyname(text->alg->evp_name))) {
+       utils->seterror(utils->conn, 0,
+                       "OTP algorithm %s is not available",
+                       text->alg->evp_name);
+       return SASL_FAIL;
+    }
+    
+    /* eat leading whitespace */
+    c = response;
+    while (isspace((int) *c)) c++;
+    
+    if (strchr(c, ':')) {
+       if (!strncasecmp(c, OTP_HEX_TYPE, strlen(OTP_HEX_TYPE))) {
+           r = hex2bin(c+strlen(OTP_HEX_TYPE), cur_otp, OTP_HASH_SIZE);
+       }
+       else if (!strncasecmp(c, OTP_WORD_TYPE, strlen(OTP_WORD_TYPE))) {
+           r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md);
+       }
+       else if (!strncasecmp(c, OTP_INIT_HEX_TYPE,
+                             strlen(OTP_INIT_HEX_TYPE))) {
+           do_init = 1;
+           r = hex2bin(c+strlen(OTP_INIT_HEX_TYPE), cur_otp, OTP_HASH_SIZE);
+       }
+       else if (!strncasecmp(c, OTP_INIT_WORD_TYPE,
+                             strlen(OTP_INIT_WORD_TYPE))) {
+           do_init = 1;
+           r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md);
+       }
+       else {
+           SETERROR(utils, "unknown OTP extended response type");
+           r = SASL_BADAUTH;
+       }
+    }
+    else {
+       /* standard response, try word first, and then hex */
+       r = word2bin(utils, c, cur_otp, md);
+       if (r != SASL_OK)
+           r = hex2bin(c, cur_otp, OTP_HASH_SIZE);
+    }
+    
+    if (r == SASL_OK) {
+       /* do one more hash (previous otp) and compare to stored otp */
+       otp_hash(md, cur_otp, OTP_HASH_SIZE, prev_otp, text->alg->swab);
+       
+       if (!memcmp(prev_otp, text->otp, OTP_HASH_SIZE)) {
+           /* update the secret with this seq/otp */
+           memcpy(text->otp, cur_otp, OTP_HASH_SIZE);
+           text->seq--;
+           r = SASL_OK;
+       }
+       else
+           r = SASL_BADAUTH;
+    }
+    
+    /* if this is an init- attempt, let's check it out */
+    if (r == SASL_OK && do_init) {
+       char *new_chal = NULL, *new_resp = NULL;
+       algorithm_option_t *alg;
+       unsigned seq;
+       char seed[OTP_SEED_MAX+1];
+       unsigned char new_otp[OTP_HASH_SIZE];
+       
+       /* find the challenge and response fields */
+       new_chal = strchr(c+strlen(OTP_INIT_WORD_TYPE), ':');
+       if (new_chal) {
+           *new_chal++ = '\0';
+           new_resp = strchr(new_chal, ':');
+           if (new_resp)
+               *new_resp++ = '\0';
+       }
+       
+       if (!(new_chal && new_resp))
+           return SASL_BADAUTH;
+       
+       if ((r = parse_challenge(utils, new_chal, &alg, &seq, seed, 1))
+           != SASL_OK) {
+           return r;
+       }
+       
+       if (seq < 1 || !strcasecmp(seed, text->seed))
+           return SASL_BADAUTH;
+       
+       /* find the MDA */
+       if (!(md = EVP_get_digestbyname(alg->evp_name))) {
+           utils->seterror(utils->conn, 0,
+                           "OTP algorithm %s is not available",
+                           alg->evp_name);
+           return SASL_BADAUTH;
+       }
+       
+       if (!strncasecmp(c, OTP_INIT_HEX_TYPE, strlen(OTP_INIT_HEX_TYPE))) {
+           r = hex2bin(new_resp, new_otp, OTP_HASH_SIZE);
+       }
+       else if (!strncasecmp(c, OTP_INIT_WORD_TYPE,
+                             strlen(OTP_INIT_WORD_TYPE))) {
+           r = word2bin(utils, new_resp, new_otp, md);
+       }
+       
+       if (r == SASL_OK) {
+           /* setup for new secret */
+           text->alg = alg;
+           text->seq = seq;
+           strcpy(text->seed, seed);
+           memcpy(text->otp, new_otp, OTP_HASH_SIZE);
+       }
+    }
+    
+    return r;
+}
+
+static int otp_server_mech_step1(server_context_t *text,
+                                sasl_server_params_t *params,
+                                const char *clientin,
+                                unsigned clientinlen,
+                                const char **serverout,
+                                unsigned *serveroutlen,
+                                sasl_out_params_t *oparams)
+{
+    const char *authzid;
+    const char *authidp;
+    size_t authid_len;
+    unsigned lup = 0;
+    int result, n;
+    const char *lookup_request[] = { "*cmusaslsecretOTP",
+                                    NULL };
+    const char *store_request[] = { "cmusaslsecretOTP",
+                                   NULL };
+    struct propval auxprop_values[2];
+    char mda[10];
+    time_t timeout;
+    sasl_secret_t *sec = NULL;
+    struct propctx *propctx = NULL;
+    
+    /* should have received authzid NUL authid */
+    
+    /* get authzid */
+    authzid = clientin;
+    while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+    
+    if (lup >= clientinlen) {
+       SETERROR(params->utils, "Can only find OTP authzid (no authid)");
+       return SASL_BADPROT;
+    }
+    
+    /* get authid */
+    ++lup;
+    authidp = clientin + lup;
+    while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+    
+    authid_len = clientin + lup - authidp;
+    
+    if (lup != clientinlen) {
+       SETERROR(params->utils,
+                "Got more data than we were expecting in the OTP plugin\n");
+       return SASL_BADPROT;
+    }
+    
+    text->authid = params->utils->malloc(authid_len + 1);    
+    if (text->authid == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    /* we can't assume that authid is null-terminated */
+    strncpy(text->authid, authidp, authid_len);
+    text->authid[authid_len] = '\0';
+
+    n = 0;
+    do {
+       /* Get user secret */
+       result = params->utils->prop_request(params->propctx,
+                                            lookup_request);
+       if (result != SASL_OK) return result;
+
+       /* this will trigger the getting of the aux properties.
+          Must use the fully qualified authid here */
+       result = params->canon_user(params->utils->conn, text->authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+       if (result != SASL_OK) return result;
+       
+       result = params->canon_user(params->utils->conn,
+                                   strlen(authzid) ? authzid : text->authid,
+                                   0, SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+       
+       result = params->utils->prop_getnames(params->propctx,
+                                             lookup_request,
+                                             auxprop_values);
+       if (result < 0 ||
+           (!auxprop_values[0].name || !auxprop_values[0].values)) {
+           /* We didn't find this username */
+           params->utils->seterror(params->utils->conn,0,
+                                   "no OTP secret in database");
+           result = params->transition ? SASL_TRANS : SASL_NOUSER;
+           return (result);
+       }
+       
+       if (auxprop_values[0].name && auxprop_values[0].values) {
+           result = parse_secret(params->utils,
+                                 (char*) auxprop_values[0].values[0],
+                                 auxprop_values[0].valsize,
+                                 mda, &text->seq, text->seed, text->otp,
+                                 &timeout);
+           
+           if (result != SASL_OK) return result;
+       } else {
+           params->utils->seterror(params->utils->conn, 0,
+                                   "don't have a OTP secret");
+           return SASL_FAIL;
+       }
+       
+       text->timestamp = time(0);
+    }
+    /*
+     * check lock timeout
+     *
+     * we try 10 times in 1 second intervals in order to give the other
+     * auth attempt time to finish
+     */
+    while ((text->timestamp < timeout) && (n++ < 10) && !sleep(1));
+    
+    if (text->timestamp < timeout) {
+       SETERROR(params->utils,
+                "simultaneous OTP authentications not permitted");
+       return SASL_TRYAGAIN;
+    }
+    
+    /* check sequence number */
+    if (text->seq <= 1) {
+       SETERROR(params->utils, "OTP has expired (sequence <= 1)");
+       return SASL_EXPIRED;
+    }
+    
+    /* find algorithm */
+    text->alg = algorithm_options;
+    while (text->alg->name) {
+       if (!strcasecmp(text->alg->name, mda))
+           break;
+       
+       text->alg++;
+    }
+    
+    if (!text->alg->name) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "unknown OTP algorithm '%s'", mda);
+       return SASL_FAIL;
+    }
+    
+    /* remake the secret with a timeout */
+    result = make_secret(params->utils, text->alg->name, text->seq,
+                        text->seed, text->otp,
+                        text->timestamp + OTP_LOCK_TIMEOUT, &sec);
+    if (result != SASL_OK) {
+       SETERROR(params->utils, "error making OTP secret");
+       return result;
+    }
+    
+    /* do the store */
+    propctx = params->utils->prop_new(0);
+    if (!propctx)
+       result = SASL_FAIL;
+    if (result == SASL_OK)
+       result = params->utils->prop_request(propctx, store_request);
+    if (result == SASL_OK)
+       result = params->utils->prop_set(propctx, "cmusaslsecretOTP",
+                                        sec->data, sec->len);
+    if (result == SASL_OK)
+       result = params->utils->auxprop_store(params->utils->conn,
+                                             propctx, text->authid);
+    if (propctx)
+       params->utils->prop_dispose(&propctx);
+
+    if (sec) params->utils->free(sec);
+    
+    if (result != SASL_OK) {
+       SETERROR(params->utils, "Error putting OTP secret");
+       return result;
+    }
+    
+    text->locked = 1;
+    
+    result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                            &(text->out_buf_len), OTP_CHALLENGE_MAX+1);
+    if (result != SASL_OK) return result;
+    
+    /* create challenge */
+    sprintf(text->out_buf, "otp-%s %u %s ext",
+           text->alg->name, text->seq-1, text->seed);
+    
+    *serverout = text->out_buf;
+    *serveroutlen = strlen(text->out_buf);
+    
+    text->state = 2;
+    
+    return SASL_CONTINUE;
+}
+
+static int
+otp_server_mech_step2(server_context_t *text,
+                     sasl_server_params_t *params,
+                     const char *clientin,
+                     unsigned clientinlen,
+                     const char **serverout __attribute__((unused)),
+                     unsigned *serveroutlen __attribute__((unused)),
+                     sasl_out_params_t *oparams)
+{
+    char response[OTP_RESPONSE_MAX+1];
+    int result;
+    sasl_secret_t *sec = NULL;
+    struct propctx *propctx = NULL;
+    const char *store_request[] = { "cmusaslsecretOTP",
+                                    NULL };
+    
+    if (clientinlen > OTP_RESPONSE_MAX) {
+       SETERROR(params->utils, "OTP response too long");
+       return SASL_BADPROT;
+    }
+    
+    /* we can't assume that the response is null-terminated */
+    strncpy(response, clientin, clientinlen);
+    response[clientinlen] = '\0';
+    
+    /* check timeout */
+    if (time(0) > text->timestamp + OTP_LOCK_TIMEOUT) {
+       SETERROR(params->utils, "OTP: server timed out");
+       return SASL_UNAVAIL;
+    }
+    
+    /* verify response */
+    result = verify_response(text, params->utils, response);
+    if (result != SASL_OK) return result;
+    
+    /* make the new secret */
+    result = make_secret(params->utils, text->alg->name, text->seq,
+                        text->seed, text->otp, 0, &sec);
+    if (result != SASL_OK) {
+       SETERROR(params->utils, "error making OTP secret");
+    }
+    
+    /* do the store */
+    propctx = params->utils->prop_new(0);
+    if (!propctx)
+       result = SASL_FAIL;
+    if (result == SASL_OK)
+       result = params->utils->prop_request(propctx, store_request);
+    if (result == SASL_OK)
+       result = params->utils->prop_set(propctx, "cmusaslsecretOTP",
+                                        sec->data, sec->len);
+    if (result == SASL_OK)
+       result = params->utils->auxprop_store(params->utils->conn,
+                                             propctx, text->authid);
+    if (propctx)
+       params->utils->prop_dispose(&propctx);
+
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error putting OTP secret");
+    }
+    
+    text->locked = 0;
+    
+    if (sec) _plug_free_secret(params->utils, &sec);
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return result;
+}
+
+static int otp_server_mech_step(void *conn_context,
+                               sasl_server_params_t *params,
+                               const char *clientin,
+                               unsigned clientinlen,
+                               const char **serverout,
+                               unsigned *serveroutlen,
+                               sasl_out_params_t *oparams)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    switch (text->state) {
+       
+    case 1:
+       return otp_server_mech_step1(text, params, clientin, clientinlen,
+                                    serverout, serveroutlen, oparams);
+       
+    case 2:
+       return otp_server_mech_step2(text, params, clientin, clientinlen,
+                                    serverout, serveroutlen, oparams);
+       
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid OTP server step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void otp_server_mech_dispose(void *conn_context,
+                                   const sasl_utils_t *utils)
+{
+    server_context_t *text = (server_context_t *) conn_context;
+    sasl_secret_t *sec;
+    struct propctx *propctx = NULL;
+    const char *store_request[] = { "cmusaslsecretOTP",
+                                    NULL };
+    int r;
+    
+    if (!text) return;
+    
+    /* if we created a challenge, but bailed before the verification of the
+       response, release the lock on the user key */
+    if (text->locked && (time(0) < text->timestamp + OTP_LOCK_TIMEOUT)) {
+       r = make_secret(utils, text->alg->name, text->seq,
+                       text->seed, text->otp, 0, &sec);
+       if (r != SASL_OK) {
+           SETERROR(utils, "error making OTP secret");
+           if (sec) utils->free(sec);
+           sec = NULL;
+       }
+       
+       /* do the store */
+       propctx = utils->prop_new(0);
+       if (!propctx)
+           r = SASL_FAIL;
+       if (!r)
+           r = utils->prop_request(propctx, store_request);
+       if (!r)
+           r = utils->prop_set(propctx, "cmusaslsecretOTP",
+                               (sec ? sec->data : NULL),
+                               (sec ? sec->len : 0));
+       if (!r)
+           r = utils->auxprop_store(utils->conn, propctx, text->authid);
+       if (propctx)
+           utils->prop_dispose(&propctx);
+
+       if (r) {
+           SETERROR(utils, "Error putting OTP secret");
+       }
+       
+       if (sec) _plug_free_secret(utils, &sec);
+    }
+    
+    if (text->authid) _plug_free_string(utils, &(text->authid));
+    if (text->realm) _plug_free_string(utils, &(text->realm));
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static int otp_setpass(void *glob_context __attribute__((unused)),
+                      sasl_server_params_t *sparams,
+                      const char *userstr,
+                      const char *pass,
+                      unsigned passlen __attribute__((unused)),
+                      const char *oldpass __attribute__((unused)),
+                      unsigned oldpasslen __attribute__((unused)),
+                      unsigned flags)
+{
+    int r;
+    char *user = NULL;
+    char *user_only = NULL;
+    char *realm = NULL;
+    sasl_secret_t *sec;
+    struct propctx *propctx = NULL;
+    const char *store_request[] = { "cmusaslsecretOTP",
+                                    NULL };
+    
+    /* Do we have a backend that can store properties? */
+    if (!sparams->utils->auxprop_store ||
+       sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) {
+       SETERROR(sparams->utils, "OTP: auxprop backend can't store properties");
+       return SASL_NOMECH;
+    }
+    
+    r = _plug_parseuser(sparams->utils, &user_only, &realm, sparams->user_realm,
+                       sparams->serverFQDN, userstr);
+    if (r) {
+       sparams->utils->seterror(sparams->utils->conn, 0, 
+                                "OTP: Error parsing user");
+       return r;
+    }
+
+    r = _plug_make_fulluser(sparams->utils, &user, user_only, realm);
+    if (r) {
+       goto cleanup;
+    }
+
+    if ((flags & SASL_SET_DISABLE) || pass == NULL) {
+       sec = NULL;
+    } else {
+       algorithm_option_t *algs;
+       const char *mda;
+       unsigned int len;
+       unsigned short randnum;
+       char seed[OTP_SEED_MAX+1];
+       char otp[OTP_HASH_SIZE];
+       
+       sparams->utils->getopt(sparams->utils->getopt_context,
+                              "OTP", "otp_mda", &mda, &len);
+       if (!mda) mda = OTP_MDA_DEFAULT;
+       
+       algs = algorithm_options;
+       while (algs->name) {
+           if (!strcasecmp(algs->name, mda) ||
+               !strcasecmp(algs->evp_name, mda))
+               break;
+           
+           algs++;
+       }
+       
+       if (!algs->name) {
+           sparams->utils->seterror(sparams->utils->conn, 0,
+                                    "unknown OTP algorithm '%s'", mda);
+           r = SASL_FAIL;
+           goto cleanup;
+       }
+       
+       sparams->utils->rand(sparams->utils->rpool,
+                            (char*) &randnum, sizeof(randnum));
+       sprintf(seed, "%.2s%04u", sparams->serverFQDN, (randnum % 9999) + 1);
+       
+       r = generate_otp(sparams->utils, algs, OTP_SEQUENCE_DEFAULT,
+                        seed, (char*) pass, otp);
+       if (r != SASL_OK) {
+           /* generate_otp() takes care of error message */
+           goto cleanup;
+       }
+       
+       r = make_secret(sparams->utils, algs->name, OTP_SEQUENCE_DEFAULT,
+                       seed, otp, 0, &sec);
+       if (r != SASL_OK) {
+           SETERROR(sparams->utils, "error making OTP secret");
+           goto cleanup;
+       }
+    }
+    
+    /* do the store */
+    propctx = sparams->utils->prop_new(0);
+    if (!propctx)
+       r = SASL_FAIL;
+    if (!r)
+       r = sparams->utils->prop_request(propctx, store_request);
+    if (!r)
+       r = sparams->utils->prop_set(propctx, "cmusaslsecretOTP",
+                                    (sec ? sec->data : NULL),
+                                    (sec ? sec->len : 0));
+    if (!r)
+       r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user);
+    if (propctx)
+       sparams->utils->prop_dispose(&propctx);
+    
+    if (r) {
+       sparams->utils->seterror(sparams->utils->conn, 0, 
+                                "Error putting OTP secret");
+       goto cleanup;
+    }
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG, "Setpass for OTP successful\n");
+    
+  cleanup:
+    
+    if (user)  _plug_free_string(sparams->utils, &user);
+    if (user_only)     _plug_free_string(sparams->utils, &user_only);
+    if (realm)         _plug_free_string(sparams->utils, &realm);
+    if (sec)    _plug_free_secret(sparams->utils, &sec);
+    
+    return r;
+}
+
+static int otp_mech_avail(void *glob_context __attribute__((unused)),
+                         sasl_server_params_t *sparams,
+                         void **conn_context __attribute__((unused))) 
+{
+    /* Do we have a backend that can store properties? */
+    if (!sparams->utils->auxprop_store ||
+       sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) {
+       SETERROR(sparams->utils, "OTP: auxprop backend can't store properties");
+       return SASL_NOMECH;
+    }
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t otp_server_plugins[] = 
+{
+    {
+       "OTP",                          /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_FORWARD_SECRECY,     /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &otp_server_mech_new,           /* mech_new */
+       &otp_server_mech_step,          /* mech_step */
+       &otp_server_mech_dispose,       /* mech_dispose */
+       &otp_common_mech_free,          /* mech_free */
+       &otp_setpass,                   /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       &otp_mech_avail,                /* mech avail */
+       NULL                            /* spare */
+    }
+};
+#endif /* HAVE_OPIE */
+
+int otp_server_plug_init(const sasl_utils_t *utils,
+                        int maxversion,
+                        int *out_version,
+                        sasl_server_plug_t **pluglist,
+                        int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "OTP version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = otp_server_plugins;
+    *plugcount = 1;  
+    
+    /* Add all digests */
+    OpenSSL_add_all_digests();
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    int state;
+
+    sasl_secret_t *password;
+    unsigned int free_password; /* set if we need to free password */
+
+    const char *otpassword;
+
+    char *out_buf;
+    unsigned out_buf_len;
+} client_context_t;
+
+static int otp_client_mech_new(void *glob_context __attribute__((unused)),
+                              sasl_client_params_t *params,
+                              void **conn_context)
+{
+    client_context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR( params->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    text->state = 1;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int otp_client_mech_step1(client_context_t *text,
+                                sasl_client_params_t *params,
+                                const char *serverin __attribute__((unused)),
+                                unsigned serverinlen __attribute__((unused)),
+                                sasl_interact_t **prompt_need,
+                                const char **clientout,
+                                unsigned *clientoutlen,
+                                sasl_out_params_t *oparams)
+{
+    const char *user = NULL, *authid = NULL;
+    int user_result = SASL_OK;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    sasl_chalprompt_t *echo_cb;
+    void *echo_context;
+    int result;
+    
+    /* check if sec layer strong enough */
+    if (params->props.min_ssf > params->external_ssf) {
+       SETERROR( params->utils, "SSF requested of OTP plugin");
+       return SASL_TOOWEAK;
+    }
+    
+    /* try to get the authid */    
+    if (oparams->authid == NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }
+    
+    /* try to get the userid */
+    if (oparams->user == NULL) {
+       user_result = _plug_get_userid(params->utils, &user, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
+           return user_result;
+    }
+    
+    /* try to get the secret pass-phrase if we don't have a chalprompt */
+    if ((params->utils->getcallback(params->utils->conn, SASL_CB_ECHOPROMPT,
+                                   &echo_cb, &echo_context) == SASL_FAIL) &&
+       (text->password == NULL)) {
+       pass_result = _plug_get_password(params->utils, &text->password,
+                                        &text->free_password, prompt_need);
+       
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) ||
+       (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your secret pass-phrase" : NULL,
+                              NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) return result;
+       
+       return SASL_INTERACT;
+    }
+    
+    if (!user || !*user) {
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    }
+    else {
+       result = params->canon_user(params->utils->conn, user, 0,
+                                   SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) return result;
+
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+    }
+    if (result != SASL_OK) return result;
+    
+    /* send authorized id NUL authentication id */
+    *clientoutlen = oparams->ulen + 1 + oparams->alen;
+    
+    /* remember the extra NUL on the end for stupid clients */
+    result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                            &(text->out_buf_len), *clientoutlen + 1);
+    if (result != SASL_OK) return result;
+    
+    memset(text->out_buf, 0, *clientoutlen + 1);
+    memcpy(text->out_buf, oparams->user, oparams->ulen);
+    memcpy(text->out_buf+oparams->ulen+1, oparams->authid, oparams->alen);
+    *clientout = text->out_buf;
+    
+    text->state = 2;
+    
+    return SASL_CONTINUE;
+}
+
+static int otp_client_mech_step2(client_context_t *text,
+                                sasl_client_params_t *params,
+                                const char *serverin,
+                                unsigned serverinlen,
+                                sasl_interact_t **prompt_need,
+                                const char **clientout,
+                                unsigned *clientoutlen,
+                                sasl_out_params_t *oparams)
+{
+    int echo_result = SASL_OK;
+    char challenge[OTP_CHALLENGE_MAX+1];
+    int result;
+    
+    if (serverinlen > OTP_CHALLENGE_MAX) {
+       SETERROR(params->utils, "OTP challenge too long");
+       return SASL_BADPROT;
+    }
+    
+    /* we can't assume that challenge is null-terminated */
+    strncpy(challenge, serverin, serverinlen);
+    challenge[serverinlen] = '\0';
+    
+    /* try to get the one-time password if we don't ave the secret */
+    if ((text->password == NULL) && (text->otpassword == NULL)) {
+       echo_result = _plug_challenge_prompt(params->utils, SASL_CB_ECHOPROMPT,
+                                            challenge,
+                                            "Please enter your one-time password",
+                                            &text->otpassword, prompt_need);
+       
+       if ((echo_result != SASL_OK) && (echo_result != SASL_INTERACT))
+           return echo_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if (echo_result == SASL_INTERACT) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              NULL, NULL,
+                              NULL, NULL,
+                              NULL, NULL,
+                              challenge, echo_result == SASL_INTERACT ?
+                              "Please enter your one-time password" : NULL,
+                              NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) return result;
+       
+       return SASL_INTERACT;
+    }
+    
+    /* the application provided us with a one-time password so use it */
+    if (text->otpassword) {
+       *clientout = text->otpassword;
+       *clientoutlen = strlen(text->otpassword);
+    }
+    
+    /* generate our own response using the user's secret pass-phrase */
+    else {
+       algorithm_option_t *alg;
+       unsigned seq;
+       char seed[OTP_SEED_MAX+1];
+       char otp[OTP_HASH_SIZE];
+       int init_done = 0;
+       
+       /* parse challenge */
+       result = parse_challenge(params->utils,
+                                challenge, &alg, &seq, seed, 0);
+       if (result != SASL_OK) return result;
+       
+       if (!text->password) {
+           PARAMERROR(params->utils);
+           return SASL_BADPARAM;
+       }
+       
+       if (seq < 1) {
+           SETERROR(params->utils, "OTP has expired (sequence < 1)");
+           return SASL_EXPIRED;
+       }
+       
+       /* generate otp */
+       result = generate_otp(params->utils, alg, seq, seed,
+                             text->password->data, otp);
+       if (result != SASL_OK) return result;
+       
+       result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                                &(text->out_buf_len), OTP_RESPONSE_MAX+1);
+       if (result != SASL_OK) return result;
+       
+       if (seq < OTP_SEQUENCE_REINIT) {
+           unsigned short randnum;
+           char new_seed[OTP_SEED_MAX+1];
+           char new_otp[OTP_HASH_SIZE];
+           
+           /* try to reinitialize */
+           
+           /* make sure we have a different seed */
+           do {
+               params->utils->rand(params->utils->rpool,
+                                   (char*) &randnum, sizeof(randnum));
+               sprintf(new_seed, "%.2s%04u", params->serverFQDN,
+                       (randnum % 9999) + 1);
+           } while (!strcasecmp(seed, new_seed));
+           
+           result = generate_otp(params->utils, alg, OTP_SEQUENCE_DEFAULT,
+                                 new_seed, text->password->data, new_otp);
+           
+           if (result == SASL_OK) {
+               /* create an init-hex response */
+               strcpy(text->out_buf, OTP_INIT_HEX_TYPE);
+               bin2hex(otp, OTP_HASH_SIZE,
+                       text->out_buf+strlen(text->out_buf));
+               sprintf(text->out_buf+strlen(text->out_buf), ":%s %u %s:",
+                       alg->name, OTP_SEQUENCE_DEFAULT, new_seed);
+               bin2hex(new_otp, OTP_HASH_SIZE,
+                       text->out_buf+strlen(text->out_buf));
+               init_done = 1;
+           }
+           else {
+               /* just do a regular response */
+           }
+       }
+       
+       if (!init_done) {
+           /* created hex response */
+           strcpy(text->out_buf, OTP_HEX_TYPE);
+           bin2hex(otp, OTP_HASH_SIZE, text->out_buf+strlen(text->out_buf));
+       }
+       
+       *clientout = text->out_buf;
+       *clientoutlen = strlen(text->out_buf);
+    }
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return SASL_OK;
+}
+
+static int otp_client_mech_step(void *conn_context,
+                               sasl_client_params_t *params,
+                               const char *serverin,
+                               unsigned serverinlen,
+                               sasl_interact_t **prompt_need,
+                               const char **clientout,
+                               unsigned *clientoutlen,
+                               sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    switch (text->state) {
+       
+    case 1:
+       return otp_client_mech_step1(text, params, serverin, serverinlen,
+                                    prompt_need, clientout, clientoutlen,
+                                    oparams);
+       
+    case 2:
+       return otp_client_mech_step2(text, params, serverin, serverinlen,
+                                    prompt_need, clientout, clientoutlen,
+                                    oparams);
+       
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid OTP client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static void otp_client_mech_dispose(void *conn_context,
+                                   const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->free_password) _plug_free_secret(utils, &(text->password));
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static sasl_client_plug_t otp_client_plugins[] = 
+{
+    {
+       "OTP",                          /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_FORWARD_SECRECY,     /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &otp_client_mech_new,           /* mech_new */
+       &otp_client_mech_step,          /* mech_step */
+       &otp_client_mech_dispose,       /* mech_dispose */
+       &otp_common_mech_free,          /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int otp_client_plug_init(sasl_utils_t *utils,
+                        int maxversion,
+                        int *out_version,
+                        sasl_client_plug_t **pluglist,
+                        int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "OTP version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = otp_client_plugins;
+    *plugcount = 1;
+    
+    /* Add all digests */
+    OpenSSL_add_all_digests();
+    
+    return SASL_OK;
+}
diff --git a/plugins/otp.h b/plugins/otp.h
new file mode 100644 (file)
index 0000000..722aca2
--- /dev/null
@@ -0,0 +1,311 @@
+/* OTP SASL plugin
+ * Ken Murchison
+ * $Id: otp.h,v 1.2 2003/02/13 19:56:04 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 _OTP_H_
+#define _OTP_H_
+
+/* Standard dictionary from RFC2289 */
+#define OTP_STD_DICT_SIZE 2048
+#define OTP_4LETTER_OFFSET 571
+
+static const char *otp_std_dict[OTP_STD_DICT_SIZE] =
+{        "A",     "ABE",   "ACE",   "ACT",   "AD",    "ADA",   "ADD",
+"AGO",   "AID",   "AIM",   "AIR",   "ALL",   "ALP",   "AM",    "AMY",
+"AN",    "ANA",   "AND",   "ANN",   "ANT",   "ANY",   "APE",   "APS",
+"APT",   "ARC",   "ARE",   "ARK",   "ARM",   "ART",   "AS",    "ASH",
+"ASK",   "AT",    "ATE",   "AUG",   "AUK",   "AVE",   "AWE",   "AWK",
+"AWL",   "AWN",   "AX",    "AYE",   "BAD",   "BAG",   "BAH",   "BAM",
+"BAN",   "BAR",   "BAT",   "BAY",   "BE",    "BED",   "BEE",   "BEG",
+"BEN",   "BET",   "BEY",   "BIB",   "BID",   "BIG",   "BIN",   "BIT",
+"BOB",   "BOG",   "BON",   "BOO",   "BOP",   "BOW",   "BOY",   "BUB",
+"BUD",   "BUG",   "BUM",   "BUN",   "BUS",   "BUT",   "BUY",   "BY",
+"BYE",   "CAB",   "CAL",   "CAM",   "CAN",   "CAP",   "CAR",   "CAT",
+"CAW",   "COD",   "COG",   "COL",   "CON",   "COO",   "COP",   "COT",
+"COW",   "COY",   "CRY",   "CUB",   "CUE",   "CUP",   "CUR",   "CUT",
+"DAB",   "DAD",   "DAM",   "DAN",   "DAR",   "DAY",   "DEE",   "DEL",
+"DEN",   "DES",   "DEW",   "DID",   "DIE",   "DIG",   "DIN",   "DIP",
+"DO",    "DOE",   "DOG",   "DON",   "DOT",   "DOW",   "DRY",   "DUB",
+"DUD",   "DUE",   "DUG",   "DUN",   "EAR",   "EAT",   "ED",    "EEL",
+"EGG",   "EGO",   "ELI",   "ELK",   "ELM",   "ELY",   "EM",    "END",
+"EST",   "ETC",   "EVA",   "EVE",   "EWE",   "EYE",   "FAD",   "FAN",
+"FAR",   "FAT",   "FAY",   "FED",   "FEE",   "FEW",   "FIB",   "FIG",
+"FIN",   "FIR",   "FIT",   "FLO",   "FLY",   "FOE",   "FOG",   "FOR",
+"FRY",   "FUM",   "FUN",   "FUR",   "GAB",   "GAD",   "GAG",   "GAL",
+"GAM",   "GAP",   "GAS",   "GAY",   "GEE",   "GEL",   "GEM",   "GET",
+"GIG",   "GIL",   "GIN",   "GO",    "GOT",   "GUM",   "GUN",   "GUS",
+"GUT",   "GUY",   "GYM",   "GYP",   "HA",    "HAD",   "HAL",   "HAM",
+"HAN",   "HAP",   "HAS",   "HAT",   "HAW",   "HAY",   "HE",    "HEM",
+"HEN",   "HER",   "HEW",   "HEY",   "HI",    "HID",   "HIM",   "HIP",
+"HIS",   "HIT",   "HO",    "HOB",   "HOC",   "HOE",   "HOG",   "HOP",
+"HOT",   "HOW",   "HUB",   "HUE",   "HUG",   "HUH",   "HUM",   "HUT",
+"I",     "ICY",   "IDA",   "IF",    "IKE",   "ILL",   "INK",   "INN",
+"IO",    "ION",   "IQ",    "IRA",   "IRE",   "IRK",   "IS",    "IT",
+"ITS",   "IVY",   "JAB",   "JAG",   "JAM",   "JAN",   "JAR",   "JAW",
+"JAY",   "JET",   "JIG",   "JIM",   "JO",    "JOB",   "JOE",   "JOG",
+"JOT",   "JOY",   "JUG",   "JUT",   "KAY",   "KEG",   "KEN",   "KEY",
+"KID",   "KIM",   "KIN",   "KIT",   "LA",    "LAB",   "LAC",   "LAD",
+"LAG",   "LAM",   "LAP",   "LAW",   "LAY",   "LEA",   "LED",   "LEE",
+"LEG",   "LEN",   "LEO",   "LET",   "LEW",   "LID",   "LIE",   "LIN",
+"LIP",   "LIT",   "LO",    "LOB",   "LOG",   "LOP",   "LOS",   "LOT",
+"LOU",   "LOW",   "LOY",   "LUG",   "LYE",   "MA",    "MAC",   "MAD",
+"MAE",   "MAN",   "MAO",   "MAP",   "MAT",   "MAW",   "MAY",   "ME",
+"MEG",   "MEL",   "MEN",   "MET",   "MEW",   "MID",   "MIN",   "MIT",
+"MOB",   "MOD",   "MOE",   "MOO",   "MOP",   "MOS",   "MOT",   "MOW",
+"MUD",   "MUG",   "MUM",   "MY",    "NAB",   "NAG",   "NAN",   "NAP",
+"NAT",   "NAY",   "NE",    "NED",   "NEE",   "NET",   "NEW",   "NIB",
+"NIL",   "NIP",   "NIT",   "NO",    "NOB",   "NOD",   "NON",   "NOR",
+"NOT",   "NOV",   "NOW",   "NU",    "NUN",   "NUT",   "O",     "OAF",
+"OAK",   "OAR",   "OAT",   "ODD",   "ODE",   "OF",    "OFF",   "OFT",
+"OH",    "OIL",   "OK",    "OLD",   "ON",    "ONE",   "OR",    "ORB",
+"ORE",   "ORR",   "OS",    "OTT",   "OUR",   "OUT",   "OVA",   "OW",
+"OWE",   "OWL",   "OWN",   "OX",    "PA",    "PAD",   "PAL",   "PAM",
+"PAN",   "PAP",   "PAR",   "PAT",   "PAW",   "PAY",   "PEA",   "PEG",
+"PEN",   "PEP",   "PER",   "PET",   "PEW",   "PHI",   "PI",    "PIE",
+"PIN",   "PIT",   "PLY",   "PO",    "POD",   "POE",   "POP",   "POT",
+"POW",   "PRO",   "PRY",   "PUB",   "PUG",   "PUN",   "PUP",   "PUT",
+"QUO",   "RAG",   "RAM",   "RAN",   "RAP",   "RAT",   "RAW",   "RAY",
+"REB",   "RED",   "REP",   "RET",   "RIB",   "RID",   "RIG",   "RIM",
+"RIO",   "RIP",   "ROB",   "ROD",   "ROE",   "RON",   "ROT",   "ROW",
+"ROY",   "RUB",   "RUE",   "RUG",   "RUM",   "RUN",   "RYE",   "SAC",
+"SAD",   "SAG",   "SAL",   "SAM",   "SAN",   "SAP",   "SAT",   "SAW",
+"SAY",   "SEA",   "SEC",   "SEE",   "SEN",   "SET",   "SEW",   "SHE",
+"SHY",   "SIN",   "SIP",   "SIR",   "SIS",   "SIT",   "SKI",   "SKY",
+"SLY",   "SO",    "SOB",   "SOD",   "SON",   "SOP",   "SOW",   "SOY",
+"SPA",   "SPY",   "SUB",   "SUD",   "SUE",   "SUM",   "SUN",   "SUP",
+"TAB",   "TAD",   "TAG",   "TAN",   "TAP",   "TAR",   "TEA",   "TED",
+"TEE",   "TEN",   "THE",   "THY",   "TIC",   "TIE",   "TIM",   "TIN",
+"TIP",   "TO",    "TOE",   "TOG",   "TOM",   "TON",   "TOO",   "TOP",
+"TOW",   "TOY",   "TRY",   "TUB",   "TUG",   "TUM",   "TUN",   "TWO",
+"UN",    "UP",    "US",    "USE",   "VAN",   "VAT",   "VET",   "VIE",
+"WAD",   "WAG",   "WAR",   "WAS",   "WAY",   "WE",    "WEB",   "WED",
+"WEE",   "WET",   "WHO",   "WHY",   "WIN",   "WIT",   "WOK",   "WON",
+"WOO",   "WOW",   "WRY",   "WU",    "YAM",   "YAP",   "YAW",   "YE",
+"YEA",   "YES",   "YET",   "YOU",   "ABED",  "ABEL",  "ABET",  "ABLE",
+"ABUT",  "ACHE",  "ACID",  "ACME",  "ACRE",  "ACTA",  "ACTS",  "ADAM",
+"ADDS",  "ADEN",  "AFAR",  "AFRO",  "AGEE",  "AHEM",  "AHOY",  "AIDA",
+"AIDE",  "AIDS",  "AIRY",  "AJAR",  "AKIN",  "ALAN",  "ALEC",  "ALGA",
+"ALIA",  "ALLY",  "ALMA",  "ALOE",  "ALSO",  "ALTO",  "ALUM",  "ALVA",
+"AMEN",  "AMES",  "AMID",  "AMMO",  "AMOK",  "AMOS",  "AMRA",  "ANDY",
+"ANEW",  "ANNA",  "ANNE",  "ANTE",  "ANTI",  "AQUA",  "ARAB",  "ARCH",
+"AREA",  "ARGO",  "ARID",  "ARMY",  "ARTS",  "ARTY",  "ASIA",  "ASKS",
+"ATOM",  "AUNT",  "AURA",  "AUTO",  "AVER",  "AVID",  "AVIS",  "AVON",
+"AVOW",  "AWAY",  "AWRY",  "BABE",  "BABY",  "BACH",  "BACK",  "BADE",
+"BAIL",  "BAIT",  "BAKE",  "BALD",  "BALE",  "BALI",  "BALK",  "BALL",
+"BALM",  "BAND",  "BANE",  "BANG",  "BANK",  "BARB",  "BARD",  "BARE",
+"BARK",  "BARN",  "BARR",  "BASE",  "BASH",  "BASK",  "BASS",  "BATE",
+"BATH",  "BAWD",  "BAWL",  "BEAD",  "BEAK",  "BEAM",  "BEAN",  "BEAR",
+"BEAT",  "BEAU",  "BECK",  "BEEF",  "BEEN",  "BEER",  "BEET",  "BELA",
+"BELL",  "BELT",  "BEND",  "BENT",  "BERG",  "BERN",  "BERT",  "BESS",
+"BEST",  "BETA",  "BETH",  "BHOY",  "BIAS",  "BIDE",  "BIEN",  "BILE",
+"BILK",  "BILL",  "BIND",  "BING",  "BIRD",  "BITE",  "BITS",  "BLAB",
+"BLAT",  "BLED",  "BLEW",  "BLOB",  "BLOC",  "BLOT",  "BLOW",  "BLUE",
+"BLUM",  "BLUR",  "BOAR",  "BOAT",  "BOCA",  "BOCK",  "BODE",  "BODY",
+"BOGY",  "BOHR",  "BOIL",  "BOLD",  "BOLO",  "BOLT",  "BOMB",  "BONA",
+"BOND",  "BONE",  "BONG",  "BONN",  "BONY",  "BOOK",  "BOOM",  "BOON",
+"BOOT",  "BORE",  "BORG",  "BORN",  "BOSE",  "BOSS",  "BOTH",  "BOUT",
+"BOWL",  "BOYD",  "BRAD",  "BRAE",  "BRAG",  "BRAN",  "BRAY",  "BRED",
+"BREW",  "BRIG",  "BRIM",  "BROW",  "BUCK",  "BUDD",  "BUFF",  "BULB",
+"BULK",  "BULL",  "BUNK",  "BUNT",  "BUOY",  "BURG",  "BURL",  "BURN",
+"BURR",  "BURT",  "BURY",  "BUSH",  "BUSS",  "BUST",  "BUSY",  "BYTE",
+"CADY",  "CAFE",  "CAGE",  "CAIN",  "CAKE",  "CALF",  "CALL",  "CALM",
+"CAME",  "CANE",  "CANT",  "CARD",  "CARE",  "CARL",  "CARR",  "CART",
+"CASE",  "CASH",  "CASK",  "CAST",  "CAVE",  "CEIL",  "CELL",  "CENT",
+"CERN",  "CHAD",  "CHAR",  "CHAT",  "CHAW",  "CHEF",  "CHEN",  "CHEW",
+"CHIC",  "CHIN",  "CHOU",  "CHOW",  "CHUB",  "CHUG",  "CHUM",  "CITE",
+"CITY",  "CLAD",  "CLAM",  "CLAN",  "CLAW",  "CLAY",  "CLOD",  "CLOG",
+"CLOT",  "CLUB",  "CLUE",  "COAL",  "COAT",  "COCA",  "COCK",  "COCO",
+"CODA",  "CODE",  "CODY",  "COED",  "COIL",  "COIN",  "COKE",  "COLA",
+"COLD",  "COLT",  "COMA",  "COMB",  "COME",  "COOK",  "COOL",  "COON",
+"COOT",  "CORD",  "CORE",  "CORK",  "CORN",  "COST",  "COVE",  "COWL",
+"CRAB",  "CRAG",  "CRAM",  "CRAY",  "CREW",  "CRIB",  "CROW",  "CRUD",
+"CUBA",  "CUBE",  "CUFF",  "CULL",  "CULT",  "CUNY",  "CURB",  "CURD",
+"CURE",  "CURL",  "CURT",  "CUTS",  "DADE",  "DALE",  "DAME",  "DANA",
+"DANE",  "DANG",  "DANK",  "DARE",  "DARK",  "DARN",  "DART",  "DASH",
+"DATA",  "DATE",  "DAVE",  "DAVY",  "DAWN",  "DAYS",  "DEAD",  "DEAF",
+"DEAL",  "DEAN",  "DEAR",  "DEBT",  "DECK",  "DEED",  "DEEM",  "DEER",
+"DEFT",  "DEFY",  "DELL",  "DENT",  "DENY",  "DESK",  "DIAL",  "DICE",
+"DIED",  "DIET",  "DIME",  "DINE",  "DING",  "DINT",  "DIRE",  "DIRT",
+"DISC",  "DISH",  "DISK",  "DIVE",  "DOCK",  "DOES",  "DOLE",  "DOLL",
+"DOLT",  "DOME",  "DONE",  "DOOM",  "DOOR",  "DORA",  "DOSE",  "DOTE",
+"DOUG",  "DOUR",  "DOVE",  "DOWN",  "DRAB",  "DRAG",  "DRAM",  "DRAW",
+"DREW",  "DRUB",  "DRUG",  "DRUM",  "DUAL",  "DUCK",  "DUCT",  "DUEL",
+"DUET",  "DUKE",  "DULL",  "DUMB",  "DUNE",  "DUNK",  "DUSK",  "DUST",
+"DUTY",  "EACH",  "EARL",  "EARN",  "EASE",  "EAST",  "EASY",  "EBEN",
+"ECHO",  "EDDY",  "EDEN",  "EDGE",  "EDGY",  "EDIT",  "EDNA",  "EGAN",
+"ELAN",  "ELBA",  "ELLA",  "ELSE",  "EMIL",  "EMIT",  "EMMA",  "ENDS",
+"ERIC",  "EROS",  "EVEN",  "EVER",  "EVIL",  "EYED",  "FACE",  "FACT",
+"FADE",  "FAIL",  "FAIN",  "FAIR",  "FAKE",  "FALL",  "FAME",  "FANG",
+"FARM",  "FAST",  "FATE",  "FAWN",  "FEAR",  "FEAT",  "FEED",  "FEEL",
+"FEET",  "FELL",  "FELT",  "FEND",  "FERN",  "FEST",  "FEUD",  "FIEF",
+"FIGS",  "FILE",  "FILL",  "FILM",  "FIND",  "FINE",  "FINK",  "FIRE",
+"FIRM",  "FISH",  "FISK",  "FIST",  "FITS",  "FIVE",  "FLAG",  "FLAK",
+"FLAM",  "FLAT",  "FLAW",  "FLEA",  "FLED",  "FLEW",  "FLIT",  "FLOC",
+"FLOG",  "FLOW",  "FLUB",  "FLUE",  "FOAL",  "FOAM",  "FOGY",  "FOIL",
+"FOLD",  "FOLK",  "FOND",  "FONT",  "FOOD",  "FOOL",  "FOOT",  "FORD",
+"FORE",  "FORK",  "FORM",  "FORT",  "FOSS",  "FOUL",  "FOUR",  "FOWL",
+"FRAU",  "FRAY",  "FRED",  "FREE",  "FRET",  "FREY",  "FROG",  "FROM",
+"FUEL",  "FULL",  "FUME",  "FUND",  "FUNK",  "FURY",  "FUSE",  "FUSS",
+"GAFF",  "GAGE",  "GAIL",  "GAIN",  "GAIT",  "GALA",  "GALE",  "GALL",
+"GALT",  "GAME",  "GANG",  "GARB",  "GARY",  "GASH",  "GATE",  "GAUL",
+"GAUR",  "GAVE",  "GAWK",  "GEAR",  "GELD",  "GENE",  "GENT",  "GERM",
+"GETS",  "GIBE",  "GIFT",  "GILD",  "GILL",  "GILT",  "GINA",  "GIRD",
+"GIRL",  "GIST",  "GIVE",  "GLAD",  "GLEE",  "GLEN",  "GLIB",  "GLOB",
+"GLOM",  "GLOW",  "GLUE",  "GLUM",  "GLUT",  "GOAD",  "GOAL",  "GOAT",
+"GOER",  "GOES",  "GOLD",  "GOLF",  "GONE",  "GONG",  "GOOD",  "GOOF",
+"GORE",  "GORY",  "GOSH",  "GOUT",  "GOWN",  "GRAB",  "GRAD",  "GRAY",
+"GREG",  "GREW",  "GREY",  "GRID",  "GRIM",  "GRIN",  "GRIT",  "GROW",
+"GRUB",  "GULF",  "GULL",  "GUNK",  "GURU",  "GUSH",  "GUST",  "GWEN",
+"GWYN",  "HAAG",  "HAAS",  "HACK",  "HAIL",  "HAIR",  "HALE",  "HALF",
+"HALL",  "HALO",  "HALT",  "HAND",  "HANG",  "HANK",  "HANS",  "HARD",
+"HARK",  "HARM",  "HART",  "HASH",  "HAST",  "HATE",  "HATH",  "HAUL",
+"HAVE",  "HAWK",  "HAYS",  "HEAD",  "HEAL",  "HEAR",  "HEAT",  "HEBE",
+"HECK",  "HEED",  "HEEL",  "HEFT",  "HELD",  "HELL",  "HELM",  "HERB",
+"HERD",  "HERE",  "HERO",  "HERS",  "HESS",  "HEWN",  "HICK",  "HIDE",
+"HIGH",  "HIKE",  "HILL",  "HILT",  "HIND",  "HINT",  "HIRE",  "HISS",
+"HIVE",  "HOBO",  "HOCK",  "HOFF",  "HOLD",  "HOLE",  "HOLM",  "HOLT",
+"HOME",  "HONE",  "HONK",  "HOOD",  "HOOF",  "HOOK",  "HOOT",  "HORN",
+"HOSE",  "HOST",  "HOUR",  "HOVE",  "HOWE",  "HOWL",  "HOYT",  "HUCK",
+"HUED",  "HUFF",  "HUGE",  "HUGH",  "HUGO",  "HULK",  "HULL",  "HUNK",
+"HUNT",  "HURD",  "HURL",  "HURT",  "HUSH",  "HYDE",  "HYMN",  "IBIS",
+"ICON",  "IDEA",  "IDLE",  "IFFY",  "INCA",  "INCH",  "INTO",  "IONS",
+"IOTA",  "IOWA",  "IRIS",  "IRMA",  "IRON",  "ISLE",  "ITCH",  "ITEM",
+"IVAN",  "JACK",  "JADE",  "JAIL",  "JAKE",  "JANE",  "JAVA",  "JEAN",
+"JEFF",  "JERK",  "JESS",  "JEST",  "JIBE",  "JILL",  "JILT",  "JIVE",
+"JOAN",  "JOBS",  "JOCK",  "JOEL",  "JOEY",  "JOHN",  "JOIN",  "JOKE",
+"JOLT",  "JOVE",  "JUDD",  "JUDE",  "JUDO",  "JUDY",  "JUJU",  "JUKE",
+"JULY",  "JUNE",  "JUNK",  "JUNO",  "JURY",  "JUST",  "JUTE",  "KAHN",
+"KALE",  "KANE",  "KANT",  "KARL",  "KATE",  "KEEL",  "KEEN",  "KENO",
+"KENT",  "KERN",  "KERR",  "KEYS",  "KICK",  "KILL",  "KIND",  "KING",
+"KIRK",  "KISS",  "KITE",  "KLAN",  "KNEE",  "KNEW",  "KNIT",  "KNOB",
+"KNOT",  "KNOW",  "KOCH",  "KONG",  "KUDO",  "KURD",  "KURT",  "KYLE",
+"LACE",  "LACK",  "LACY",  "LADY",  "LAID",  "LAIN",  "LAIR",  "LAKE",
+"LAMB",  "LAME",  "LAND",  "LANE",  "LANG",  "LARD",  "LARK",  "LASS",
+"LAST",  "LATE",  "LAUD",  "LAVA",  "LAWN",  "LAWS",  "LAYS",  "LEAD",
+"LEAF",  "LEAK",  "LEAN",  "LEAR",  "LEEK",  "LEER",  "LEFT",  "LEND",
+"LENS",  "LENT",  "LEON",  "LESK",  "LESS",  "LEST",  "LETS",  "LIAR",
+"LICE",  "LICK",  "LIED",  "LIEN",  "LIES",  "LIEU",  "LIFE",  "LIFT",
+"LIKE",  "LILA",  "LILT",  "LILY",  "LIMA",  "LIMB",  "LIME",  "LIND",
+"LINE",  "LINK",  "LINT",  "LION",  "LISA",  "LIST",  "LIVE",  "LOAD",
+"LOAF",  "LOAM",  "LOAN",  "LOCK",  "LOFT",  "LOGE",  "LOIS",  "LOLA",
+"LONE",  "LONG",  "LOOK",  "LOON",  "LOOT",  "LORD",  "LORE",  "LOSE",
+"LOSS",  "LOST",  "LOUD",  "LOVE",  "LOWE",  "LUCK",  "LUCY",  "LUGE",
+"LUKE",  "LULU",  "LUND",  "LUNG",  "LURA",  "LURE",  "LURK",  "LUSH",
+"LUST",  "LYLE",  "LYNN",  "LYON",  "LYRA",  "MACE",  "MADE",  "MAGI",
+"MAID",  "MAIL",  "MAIN",  "MAKE",  "MALE",  "MALI",  "MALL",  "MALT",
+"MANA",  "MANN",  "MANY",  "MARC",  "MARE",  "MARK",  "MARS",  "MART",
+"MARY",  "MASH",  "MASK",  "MASS",  "MAST",  "MATE",  "MATH",  "MAUL",
+"MAYO",  "MEAD",  "MEAL",  "MEAN",  "MEAT",  "MEEK",  "MEET",  "MELD",
+"MELT",  "MEMO",  "MEND",  "MENU",  "MERT",  "MESH",  "MESS",  "MICE",
+"MIKE",  "MILD",  "MILE",  "MILK",  "MILL",  "MILT",  "MIMI",  "MIND",
+"MINE",  "MINI",  "MINK",  "MINT",  "MIRE",  "MISS",  "MIST",  "MITE",
+"MITT",  "MOAN",  "MOAT",  "MOCK",  "MODE",  "MOLD",  "MOLE",  "MOLL",
+"MOLT",  "MONA",  "MONK",  "MONT",  "MOOD",  "MOON",  "MOOR",  "MOOT",
+"MORE",  "MORN",  "MORT",  "MOSS",  "MOST",  "MOTH",  "MOVE",  "MUCH",
+"MUCK",  "MUDD",  "MUFF",  "MULE",  "MULL",  "MURK",  "MUSH",  "MUST",
+"MUTE",  "MUTT",  "MYRA",  "MYTH",  "NAGY",  "NAIL",  "NAIR",  "NAME",
+"NARY",  "NASH",  "NAVE",  "NAVY",  "NEAL",  "NEAR",  "NEAT",  "NECK",
+"NEED",  "NEIL",  "NELL",  "NEON",  "NERO",  "NESS",  "NEST",  "NEWS",
+"NEWT",  "NIBS",  "NICE",  "NICK",  "NILE",  "NINA",  "NINE",  "NOAH",
+"NODE",  "NOEL",  "NOLL",  "NONE",  "NOOK",  "NOON",  "NORM",  "NOSE",
+"NOTE",  "NOUN",  "NOVA",  "NUDE",  "NULL",  "NUMB",  "OATH",  "OBEY",
+"OBOE",  "ODIN",  "OHIO",  "OILY",  "OINT",  "OKAY",  "OLAF",  "OLDY",
+"OLGA",  "OLIN",  "OMAN",  "OMEN",  "OMIT",  "ONCE",  "ONES",  "ONLY",
+"ONTO",  "ONUS",  "ORAL",  "ORGY",  "OSLO",  "OTIS",  "OTTO",  "OUCH",
+"OUST",  "OUTS",  "OVAL",  "OVEN",  "OVER",  "OWLY",  "OWNS",  "QUAD",
+"QUIT",  "QUOD",  "RACE",  "RACK",  "RACY",  "RAFT",  "RAGE",  "RAID",
+"RAIL",  "RAIN",  "RAKE",  "RANK",  "RANT",  "RARE",  "RASH",  "RATE",
+"RAVE",  "RAYS",  "READ",  "REAL",  "REAM",  "REAR",  "RECK",  "REED",
+"REEF",  "REEK",  "REEL",  "REID",  "REIN",  "RENA",  "REND",  "RENT",
+"REST",  "RICE",  "RICH",  "RICK",  "RIDE",  "RIFT",  "RILL",  "RIME",
+"RING",  "RINK",  "RISE",  "RISK",  "RITE",  "ROAD",  "ROAM",  "ROAR",
+"ROBE",  "ROCK",  "RODE",  "ROIL",  "ROLL",  "ROME",  "ROOD",  "ROOF",
+"ROOK",  "ROOM",  "ROOT",  "ROSA",  "ROSE",  "ROSS",  "ROSY",  "ROTH",
+"ROUT",  "ROVE",  "ROWE",  "ROWS",  "RUBE",  "RUBY",  "RUDE",  "RUDY",
+"RUIN",  "RULE",  "RUNG",  "RUNS",  "RUNT",  "RUSE",  "RUSH",  "RUSK",
+"RUSS",  "RUST",  "RUTH",  "SACK",  "SAFE",  "SAGE",  "SAID",  "SAIL",
+"SALE",  "SALK",  "SALT",  "SAME",  "SAND",  "SANE",  "SANG",  "SANK",
+"SARA",  "SAUL",  "SAVE",  "SAYS",  "SCAN",  "SCAR",  "SCAT",  "SCOT",
+"SEAL",  "SEAM",  "SEAR",  "SEAT",  "SEED",  "SEEK",  "SEEM",  "SEEN",
+"SEES",  "SELF",  "SELL",  "SEND",  "SENT",  "SETS",  "SEWN",  "SHAG",
+"SHAM",  "SHAW",  "SHAY",  "SHED",  "SHIM",  "SHIN",  "SHOD",  "SHOE",
+"SHOT",  "SHOW",  "SHUN",  "SHUT",  "SICK",  "SIDE",  "SIFT",  "SIGH",
+"SIGN",  "SILK",  "SILL",  "SILO",  "SILT",  "SINE",  "SING",  "SINK",
+"SIRE",  "SITE",  "SITS",  "SITU",  "SKAT",  "SKEW",  "SKID",  "SKIM",
+"SKIN",  "SKIT",  "SLAB",  "SLAM",  "SLAT",  "SLAY",  "SLED",  "SLEW",
+"SLID",  "SLIM",  "SLIT",  "SLOB",  "SLOG",  "SLOT",  "SLOW",  "SLUG",
+"SLUM",  "SLUR",  "SMOG",  "SMUG",  "SNAG",  "SNOB",  "SNOW",  "SNUB",
+"SNUG",  "SOAK",  "SOAR",  "SOCK",  "SODA",  "SOFA",  "SOFT",  "SOIL",
+"SOLD",  "SOME",  "SONG",  "SOON",  "SOOT",  "SORE",  "SORT",  "SOUL",
+"SOUR",  "SOWN",  "STAB",  "STAG",  "STAN",  "STAR",  "STAY",  "STEM",
+"STEW",  "STIR",  "STOW",  "STUB",  "STUN",  "SUCH",  "SUDS",  "SUIT",
+"SULK",  "SUMS",  "SUNG",  "SUNK",  "SURE",  "SURF",  "SWAB",  "SWAG",
+"SWAM",  "SWAN",  "SWAT",  "SWAY",  "SWIM",  "SWUM",  "TACK",  "TACT",
+"TAIL",  "TAKE",  "TALE",  "TALK",  "TALL",  "TANK",  "TASK",  "TATE",
+"TAUT",  "TEAL",  "TEAM",  "TEAR",  "TECH",  "TEEM",  "TEEN",  "TEET",
+"TELL",  "TEND",  "TENT",  "TERM",  "TERN",  "TESS",  "TEST",  "THAN",
+"THAT",  "THEE",  "THEM",  "THEN",  "THEY",  "THIN",  "THIS",  "THUD",
+"THUG",  "TICK",  "TIDE",  "TIDY",  "TIED",  "TIER",  "TILE",  "TILL",
+"TILT",  "TIME",  "TINA",  "TINE",  "TINT",  "TINY",  "TIRE",  "TOAD",
+"TOGO",  "TOIL",  "TOLD",  "TOLL",  "TONE",  "TONG",  "TONY",  "TOOK",
+"TOOL",  "TOOT",  "TORE",  "TORN",  "TOTE",  "TOUR",  "TOUT",  "TOWN",
+"TRAG",  "TRAM",  "TRAY",  "TREE",  "TREK",  "TRIG",  "TRIM",  "TRIO",
+"TROD",  "TROT",  "TROY",  "TRUE",  "TUBA",  "TUBE",  "TUCK",  "TUFT",
+"TUNA",  "TUNE",  "TUNG",  "TURF",  "TURN",  "TUSK",  "TWIG",  "TWIN",
+"TWIT",  "ULAN",  "UNIT",  "URGE",  "USED",  "USER",  "USES",  "UTAH",
+"VAIL",  "VAIN",  "VALE",  "VARY",  "VASE",  "VAST",  "VEAL",  "VEDA",
+"VEIL",  "VEIN",  "VEND",  "VENT",  "VERB",  "VERY",  "VETO",  "VICE",
+"VIEW",  "VINE",  "VISE",  "VOID",  "VOLT",  "VOTE",  "WACK",  "WADE",
+"WAGE",  "WAIL",  "WAIT",  "WAKE",  "WALE",  "WALK",  "WALL",  "WALT",
+"WAND",  "WANE",  "WANG",  "WANT",  "WARD",  "WARM",  "WARN",  "WART",
+"WASH",  "WAST",  "WATS",  "WATT",  "WAVE",  "WAVY",  "WAYS",  "WEAK",
+"WEAL",  "WEAN",  "WEAR",  "WEED",  "WEEK",  "WEIR",  "WELD",  "WELL",
+"WELT",  "WENT",  "WERE",  "WERT",  "WEST",  "WHAM",  "WHAT",  "WHEE",
+"WHEN",  "WHET",  "WHOA",  "WHOM",  "WICK",  "WIFE",  "WILD",  "WILL",
+"WIND",  "WINE",  "WING",  "WINK",  "WINO",  "WIRE",  "WISE",  "WISH",
+"WITH",  "WOLF",  "WONT",  "WOOD",  "WOOL",  "WORD",  "WORE",  "WORK",
+"WORM",  "WORN",  "WOVE",  "WRIT",  "WYNN",  "YALE",  "YANG",  "YANK",
+"YARD",  "YARN",  "YAWL",  "YAWN",  "YEAH",  "YEAR",  "YELL",  "YOGA",
+"YOKE"   };
+
+#endif /* _OTP_H_ */
diff --git a/plugins/otp_init.c b/plugins/otp_init.c
new file mode 100644 (file)
index 0000000..cd11684
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_otp_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( otp )
+SASL_SERVER_PLUG_INIT( otp )
+
diff --git a/plugins/passdss.c b/plugins/passdss.c
new file mode 100644 (file)
index 0000000..8f3f2b7
--- /dev/null
@@ -0,0 +1,1680 @@
+/* PASSDSS-3DES-1 SASL plugin
+ * Ken Murchison
+ * $Id: passdss.c,v 1.4 2006/04/24 19:21:44 mel Exp $
+ */
+/* 
+ * Copyright (c) 1998-2004 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.
+ */
+
+/*
+ * Notes:
+ *
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+/* check OpenSSL version */
+#include <openssl/opensslv.h>
+#if (OPENSSL_VERSION_NUMBER < 0x0090700f)
+#error OpenSSL 0.9.7 or later is required
+#endif
+
+/* for big number support */
+#include <openssl/bn.h>
+
+/* for Diffie-Hellman support */
+#include <openssl/dh.h>
+
+/* for digest and cipher support */
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <openssl/dsa.h>
+
+#include <sasl.h>
+#define MD5_H  /* suppress internal MD5 */
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh 
+#include <sasl_passdss_plugin_decl.h> 
+#endif 
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: passdss.c,v 1.4 2006/04/24 19:21:44 mel Exp $";
+
+const char g[] = "2";
+const char N[] = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF";
+
+#define NO_LAYER_FLAG          (1<<0)
+#define INTEGRITY_LAYER_FLAG   (1<<1)
+#define PRIVACY_LAYER_FLAG     (1<<2)
+
+#define NO_LAYER_SSF           0
+#define INTEGRITY_LAYER_SSF    1
+#define PRIVACY_LAYER_SSF      112
+
+typedef struct context {
+    int state;
+
+    char *authid;              /* authentication id (server) */
+    char *userid;              /* authorization id (server) */
+    sasl_secret_t *password;   /* user secret (client) */
+    unsigned int free_password;        /* set if we need to free password */
+
+    DH *dh;                    /* Diffie-Hellman parameters */
+
+    /* copy of utils from the params structures */
+    const sasl_utils_t *utils;
+    
+    /* per-step mem management */
+    char *out_buf;
+    unsigned out_buf_len;
+
+    /* security layer foo */
+    unsigned char secmask;     /* bitmask of enabled security layers */
+    unsigned char padding[EVP_MAX_BLOCK_LENGTH];  /* block of NULs */
+
+    HMAC_CTX hmac_send_ctx;
+    HMAC_CTX hmac_recv_ctx;
+
+    unsigned char send_integrity_key[4 + EVP_MAX_MD_SIZE]; /* +4 for pktnum */
+    unsigned char recv_integrity_key[4 + EVP_MAX_MD_SIZE]; /* +4 for pktnum */
+    unsigned char *cs_integrity_key;  /* ptr to bare key in send/recv key */
+    unsigned char *sc_integrity_key;  /* ptr to bare key in send/recv key */
+
+    EVP_CIPHER_CTX cipher_enc_ctx;
+    EVP_CIPHER_CTX cipher_dec_ctx;
+    unsigned blk_siz;
+    
+    unsigned char cs_encryption_iv[EVP_MAX_MD_SIZE];
+    unsigned char sc_encryption_iv[EVP_MAX_MD_SIZE];
+    unsigned char cs_encryption_key[2 * EVP_MAX_MD_SIZE];
+    unsigned char sc_encryption_key[2 * EVP_MAX_MD_SIZE];
+
+    /* replay detection sequence numbers */
+    uint32_t pktnum_out;
+    uint32_t pktnum_in;
+    
+    /* for encoding/decoding mem management */
+    char           *encode_buf, *decode_buf, *decode_pkt_buf;
+    unsigned       encode_buf_len, decode_buf_len, decode_pkt_buf_len;
+    
+    /* layers buffering */
+    decode_context_t decode_context;
+    
+} context_t;
+
+
+static int passdss_encode(void *context,
+                         const struct iovec *invec,
+                         unsigned numiov,
+                         const char **output,
+                         unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    unsigned long inputlen;
+    unsigned char hmac[EVP_MAX_MD_SIZE];
+    unsigned i, hmaclen;
+    uint32_t tmpnum;
+    int ret;
+    
+    if (!context || !invec || !numiov || !output || !outputlen) {
+       PARAMERROR( text->utils );
+       return SASL_BADPARAM;
+    }
+
+    /* calculate total size of input */
+    for (i = 0, inputlen = 0; i < numiov; i++)
+       inputlen += invec[i].iov_len;
+
+    /* allocate a buffer for the output */
+    ret = _plug_buf_alloc(text->utils, &text->encode_buf,
+                         &text->encode_buf_len,
+                         4 +                           /* length */
+                         inputlen +                    /* content */
+                         EVP_MAX_MD_SIZE +             /* HMAC */
+                         EVP_MAX_BLOCK_LENGTH - 1);    /* padding */
+    if (ret != SASL_OK) return ret;
+
+    *outputlen = 4; /* skip length */
+
+    /* prepend packet number to integrity key */
+    tmpnum = htonl(text->pktnum_out++);
+    memcpy(text->send_integrity_key, &tmpnum, 4);
+
+    /* key the HMAC */
+    HMAC_Init_ex(&text->hmac_send_ctx, text->send_integrity_key,
+                4+SHA_DIGEST_LENGTH, EVP_sha1(), NULL);
+
+    /* operate on each iovec */
+    for (i = 0; i < numiov; i++) {
+       /* hash the content */
+       HMAC_Update(&text->hmac_send_ctx, invec[i].iov_base, invec[i].iov_len);
+
+       if (text->secmask & PRIVACY_LAYER_FLAG) {
+           unsigned enclen;
+
+           /* encrypt the data into the output buffer */
+           EVP_EncryptUpdate(&text->cipher_enc_ctx,
+                             text->encode_buf + *outputlen, &enclen,
+                             invec[i].iov_base, invec[i].iov_len);
+           *outputlen += enclen;
+       }
+       else {
+           /* copy the raw input to the output */
+           memcpy(text->encode_buf + *outputlen, invec[i].iov_base,
+                  invec[i].iov_len);
+           *outputlen += invec[i].iov_len;
+       }
+    }
+
+    /* calculate the HMAC */
+    HMAC_Final(&text->hmac_send_ctx, hmac, &hmaclen);
+
+    if (text->secmask & PRIVACY_LAYER_FLAG) {
+       unsigned enclen;
+       unsigned char padlen;
+
+       /* encrypt the HMAC into the output buffer */
+       EVP_EncryptUpdate(&text->cipher_enc_ctx,
+                         text->encode_buf + *outputlen, &enclen,
+                         hmac, hmaclen);
+       *outputlen += enclen;
+
+       /* pad output buffer to multiple of blk_siz
+          with padlen-1 as last octet */
+       padlen = text->blk_siz - ((inputlen + hmaclen) % text->blk_siz) - 1;
+       EVP_EncryptUpdate(&text->cipher_enc_ctx,
+                         text->encode_buf + *outputlen, &enclen,
+                         text->padding, padlen);
+       *outputlen += enclen;
+       EVP_EncryptUpdate(&text->cipher_enc_ctx,
+                         text->encode_buf + *outputlen, &enclen,
+                         &padlen, 1);
+       *outputlen += enclen;
+
+       /* encrypt the last block of data into the output buffer */
+       EVP_EncryptFinal_ex(&text->cipher_enc_ctx,
+                           text->encode_buf + *outputlen, &enclen);
+       *outputlen += enclen;
+    }
+    else {
+       /* copy the HMAC to the output */
+       memcpy(text->encode_buf + *outputlen, hmac, hmaclen);
+       *outputlen += hmaclen;
+    }
+
+    /* prepend the length of the output */
+    tmpnum = *outputlen - 4;
+    tmpnum = htonl(tmpnum);
+    memcpy(text->encode_buf, &tmpnum, 4);
+
+    *output = text->encode_buf;
+    
+    return SASL_OK;
+}
+
+/* Decode a single PASSDSS packet */
+static int passdss_decode_packet(void *context,
+                                const char *input,
+                                unsigned inputlen,
+                                char **output,
+                                unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    uint32_t tmpnum;
+    unsigned char hmac[EVP_MAX_MD_SIZE];
+    unsigned hmaclen;
+    int ret;
+
+    if (text->secmask & PRIVACY_LAYER_FLAG) {
+       unsigned declen, padlen;
+
+       /* allocate a buffer for the output */
+       ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf),
+                             &(text->decode_pkt_buf_len), inputlen);
+       if (ret != SASL_OK) return ret;
+
+       /* decrypt the data into the output buffer */
+       ret = EVP_DecryptUpdate(&text->cipher_dec_ctx,
+                               text->decode_pkt_buf, &declen,
+                               (char *) input, inputlen);
+       if (ret)
+           EVP_DecryptFinal_ex(&text->cipher_dec_ctx,  /* should be no output */
+                               text->decode_pkt_buf + declen, &declen);
+       if (!ret) {
+           SETERROR(text->utils, "Error decrypting input");
+           return SASL_BADPROT;
+       }
+       input = text->decode_pkt_buf;
+
+       /* trim padding */
+       padlen = text->decode_pkt_buf[inputlen - 1] + 1;
+       inputlen -= padlen;
+    }
+
+    /* trim HMAC */
+    inputlen -= SHA_DIGEST_LENGTH;
+
+    /* prepend packet number to integrity key */
+    tmpnum = htonl(text->pktnum_in++);
+    memcpy(text->recv_integrity_key, &tmpnum, 4);
+
+    /* calculate the HMAC */
+    HMAC(EVP_sha1(), text->recv_integrity_key, 4+SHA_DIGEST_LENGTH,
+        input, inputlen, hmac, &hmaclen);
+
+    /* verify HMAC */
+    if (memcmp(hmac, input+inputlen, hmaclen)) {
+       SETERROR(text->utils, "HMAC is incorrect\n");
+       return SASL_BADMAC;
+    }
+
+    *output = (char *) input;
+    *outputlen = inputlen;
+
+    return SASL_OK;
+}
+
+/* Decode and concatenate multiple PASSDSS packets */
+static int passdss_decode(void *context,
+                     const char *input, unsigned inputlen,
+                     const char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+    
+    ret = _plug_decode(&text->decode_context, input, inputlen,
+                      &text->decode_buf, &text->decode_buf_len, outputlen,
+                      passdss_decode_packet, text);
+    
+    *output = text->decode_buf;
+    
+    return ret;
+}
+
+#define MAX_MPI_LEN 2147483643
+#define MAX_UTF8_LEN 2147483643
+
+/*
+ * Create/append to a PASSDSS buffer from the data specified by the fmt string.
+ */
+static int MakeBuffer(const sasl_utils_t *utils, char **buf, unsigned offset,
+                     unsigned *buflen, unsigned *outlen, const char *fmt, ...)
+{
+    va_list ap;
+    char *p, *out = NULL, *lptr = NULL;
+    int r, alloclen, len = -1, argc = 0;
+    BIGNUM *mpi;
+    char *os, *str;
+    uint32_t u, nl;
+
+    /* first pass to calculate size of buffer */
+    va_start(ap, fmt);
+    for (p = (char *) fmt, alloclen = offset; *p; p++) {
+       if (*p != '%') {
+           alloclen++;
+           continue;
+       }
+
+       /* check for length prefix ('a', 'o', 'u', and 's' only) */
+       if (*++p == '*') {
+           /* arg is length of next arg */
+           len = va_arg(ap, int);
+           p++;
+       }
+       else if (isdigit((int) *p)) {
+           len = 0;
+           while (isdigit((int) *p)) len = 10 * len + *p++ - '0';
+       }
+
+       switch (*p) {
+       case 'a':
+           /* insert total length of next N args */
+           alloclen += 4;
+           break;
+
+       case 'm':
+           /* MPI */
+           mpi = va_arg(ap, BIGNUM *);
+           len = BN_num_bytes(mpi);
+           if (len > MAX_MPI_LEN) {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "String too long to create mpi string\n");
+               r = SASL_FAIL;
+               goto done;
+           }
+           alloclen += len + 4;
+           break;
+
+       case 'o':
+           /* octet sequence (len given by prefix) */
+           alloclen += len;
+           os = va_arg(ap, char *);
+           break;
+
+       case 's':
+           /* string */
+           str = va_arg(ap, char *);
+           if (len == -1) len = strlen(str);
+           if (len > MAX_UTF8_LEN) {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "String too long to create utf8 string\n");
+               r = SASL_FAIL;
+               goto done;
+           }
+           alloclen += len + 4;
+           break;
+
+       case 'u':
+           /* unsigned int */
+           u = va_arg(ap, uint32_t);
+           if (len == -1) len = 4;
+           alloclen += len;
+           break;
+
+       default:
+           alloclen++;
+           break;
+       }
+
+       len = -1;
+    }
+    va_end(ap);
+
+    r = _plug_buf_alloc(utils, buf, buflen, alloclen);
+    if (r != SASL_OK) return r;
+
+    out = *buf + offset;
+
+    /* second pass to fill buffer */
+    va_start(ap, fmt);
+    for (p = (char *) fmt; *p; p++) {
+       if (*p != '%') {
+           *out = *p;
+           out++;
+           continue;
+       }
+
+       /* check for length prefix ('a', 'o', 'u', and 's' only) */
+       if (*++p == '*') {
+           /* arg is length of next arg */
+           len = va_arg(ap, int);
+           p++;
+       }
+       else if (isdigit((int) *p)) {
+           len = 0;
+           while (isdigit((int) *p)) len = 10 * len + *p++ - '0';
+       }
+
+       switch (*p) {
+       case 'a':
+           /* total length of next N args */
+           argc = len;
+           len = -1;
+           lptr = out;
+           out += 4;
+           continue;
+           break;
+
+       case 'm':
+           /* MPI */
+           mpi = va_arg(ap, BIGNUM *);
+           len = BN_bn2bin(mpi, out+4);
+           nl = htonl(len);
+           memcpy(out, &nl, 4);        /* add 4 byte len (network order) */
+           out += len + 4;
+           break;
+
+       case 'o':
+           /* octet sequence (len given by prefix) */
+           os = va_arg(ap, char *);
+           memcpy(out, os, len);       /* add data */
+           out += len;
+           break;
+
+       case 's':
+           /* string (len possibly given by prefix) */
+           str = va_arg(ap, char *);
+           /* xxx do actual utf8 conversion */
+           if (len == -1) len = strlen(str);
+           nl = htonl(len);
+           memcpy(out, &nl, 4);        /* add 4 byte len (network order) */
+           memcpy(out+4, str, len);    /* add string */
+           out += len + 4;
+           break;
+
+       case 'u':
+           /* unsigned int */
+           u = va_arg(ap, uint32_t);
+           nl = htonl(u);
+           if (len == -1) len = 4;
+           memcpy(out, &nl + 4 - len, len);
+           out += len;
+           break;
+
+       default:
+           *out = *p;
+           out++;
+           break;
+       }
+
+       /* see if we're done counting args */
+       if (lptr && !--argc) {
+           len = out - lptr - 4;
+           nl = htonl(len);
+           memcpy(lptr, &nl, 4);       /* insert 4 byte len (network order) */
+           lptr = NULL;
+       }
+
+       len = -1;
+    }
+  done:
+    va_end(ap);
+
+    *outlen = out - *buf;
+
+    return r;
+}
+
+/* 
+ * Extract a PASSDSS buffer into the data specified by the fmt string.
+ */
+static int UnBuffer(const sasl_utils_t *utils, const char *buf,
+                   unsigned buflen, const char *fmt, ...)
+{
+    va_list ap;
+    char *p;
+    BIGNUM **mpi;
+    char **os, **str;
+    uint32_t *u, nl;
+    unsigned len;
+    enum { OCTET_REFERENCE,    /* just point to the data (reference it) */
+          OCTET_COPY,          /* copy the data into the given buffer */
+          OCTET_ALLOC          /* alloc space for the data, then copy */
+    } octet_flag;
+    int r = SASL_OK;
+
+    va_start(ap, fmt);
+    for (p = (char *) fmt; *p; p++) {
+       if (*p != '%') {
+           if (*buf != *p) {
+               r = SASL_BADPROT;
+               goto done;
+           }
+           buf++;
+           buflen--;
+           continue;
+       }
+       p++;
+
+       /* check for octet flags */
+       octet_flag = OCTET_COPY;
+       if (*p == '-') {
+           octet_flag = OCTET_REFERENCE;
+           p++;
+       }
+       else if (*p == '+') {
+           octet_flag = OCTET_ALLOC;
+           p++;
+       }
+
+       /* check for length prefix ('o', 'u', and 'p' only) */
+       len = 0;
+       if (*p == '*') {
+           /* arg is length of next arg */
+           len = va_arg(ap, int);
+           p++;
+       }
+       else if (isdigit((int) *p)) {
+           len = 0;
+           while (isdigit((int) *p)) len = 10 * len + *p++ - '0';
+       }
+
+       switch (*p) {
+       case 'm':
+           /* MPI */
+           mpi = va_arg(ap, BIGNUM **);
+
+           if (buflen < 4) {
+               SETERROR(utils, "Buffer is not big enough to be PASSDSS MPI\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+    
+           /* get the length */
+           memcpy(&nl, buf, 4);
+           len = ntohl(nl);
+           buf += 4;
+           buflen -= 4;
+    
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this PASSDSS MPI\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           if (mpi) {
+               if (!*mpi) *mpi = BN_new();
+               BN_init(*mpi);
+               BN_bin2bn(buf, len, *mpi);
+           }
+           break;
+
+       case 'o':
+           /* octet sequence (len given by prefix) */
+           os = va_arg(ap, char **);
+
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this PASSDSS os\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           if (os) {
+               if (octet_flag == OCTET_REFERENCE)
+                   *os = (char *) buf;
+               else {
+                   if (octet_flag == OCTET_ALLOC &&
+                       (*os = (char *) utils->malloc(len)) == NULL) {
+                       r = SASL_NOMEM;
+                       goto done;
+                   }
+    
+                   memcpy(*os, buf, len);
+               }
+           }
+           break;
+
+       case 'p':
+           /* padding (max len given by prefix) */
+
+           if (buflen < len) len = buflen;
+           break;
+
+       case 's':
+           /* string */
+           str = va_arg(ap, char **);
+           if (str) *str = NULL;
+
+           if (buflen < 4) {
+               SETERROR(utils, "Buffer is not big enough to be PASSDSS string\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+    
+           /* get the length */
+           memcpy(&nl, buf, 4);
+           len = ntohl(nl);
+           buf += 4;
+           buflen -= 4;
+    
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this PASSDSS string\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           if (str) {
+               *str = (char *) utils->malloc(len+1); /* +1 for NUL */
+               if (!*str) {
+                   r = SASL_NOMEM;
+                   goto done;
+               }
+    
+               memcpy(*str, buf, len);
+               (*str)[len] = '\0';
+           }
+           break;
+
+       case 'u':
+           /* unsigned int */
+           u = va_arg(ap, uint32_t*);
+
+           if (!len) len = 4;
+           if (buflen < len) {
+               SETERROR(utils, "Buffer is not big enough to be PASSDSS uint32\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+
+           if (u) {
+               memset(u, 0, 4);
+               memcpy(u + 4 - len, buf, len);
+               *u = ntohl(*u);
+           }
+           break;
+
+       default:
+           len = 1;
+           if (*buf != *p) {
+               r = SASL_BADPROT;
+               goto done;
+           }
+           break;
+       }
+
+       buf += len;
+       buflen -= len;
+    }
+
+    if (buflen != 0) {
+       SETERROR(utils, "Extra data in PASSDSS buffer\n");
+       r = SASL_BADPROT;
+    }
+
+  done:
+    va_end(ap);
+
+    return r;
+}
+
+#define DOHASH(out, in1, len1, in2, len2, in3, len3)   \
+    EVP_DigestInit(&mdctx, EVP_sha1());                        \
+    EVP_DigestUpdate(&mdctx, in1, len1);               \
+    EVP_DigestUpdate(&mdctx, in2, len2);               \
+    EVP_DigestUpdate(&mdctx, in3, len3);               \
+    EVP_DigestFinal(&mdctx, out, NULL)
+
+void CalcLayerParams(context_t *text, char *K, unsigned Klen,
+                    char *hash, unsigned hashlen)
+{
+    EVP_MD_CTX mdctx;
+
+    DOHASH(text->cs_encryption_iv, K, Klen, "A", 1, hash, hashlen);
+    DOHASH(text->sc_encryption_iv, K, Klen, "B", 1, hash, hashlen);
+    DOHASH(text->cs_encryption_key, K, Klen, "C", 1, hash, hashlen);
+    DOHASH(text->cs_encryption_key + hashlen, K, Klen, "", 0,
+          text->cs_encryption_key, hashlen);
+    DOHASH(text->sc_encryption_key, K, Klen, "D", 1, hash, hashlen);
+    DOHASH(text->sc_encryption_key + hashlen, K, Klen, "", 0,
+          text->sc_encryption_key, hashlen);
+    DOHASH(text->cs_integrity_key, K, Klen, "E", 1, hash, hashlen);
+    DOHASH(text->sc_integrity_key, K, Klen, "F", 1, hash, hashlen);
+}
+
+/*
+ * Dispose of a PASSDSS context (could be server or client)
+ */ 
+static void passdss_common_mech_dispose(void *conn_context,
+                                       const sasl_utils_t *utils)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->authid)          utils->free(text->authid);
+    if (text->userid)          utils->free(text->userid);
+    if (text->free_password)   _plug_free_secret(utils, &(text->password));
+
+    if (text->dh)              DH_free(text->dh);
+
+    HMAC_CTX_cleanup(&text->hmac_send_ctx);
+    HMAC_CTX_cleanup(&text->hmac_recv_ctx);
+
+    EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx);
+    EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx);
+    
+    _plug_decode_free(&text->decode_context);
+
+    if (text->encode_buf)      utils->free(text->encode_buf);
+    if (text->decode_buf)      utils->free(text->decode_buf);
+    if (text->decode_pkt_buf)  utils->free(text->decode_pkt_buf);
+    if (text->out_buf)         utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+/*****************************  Server Section  *****************************/
+
+static int passdss_server_mech_new(void *glob_context __attribute__((unused)), 
+                                sasl_server_params_t *sparams,
+                                const char *challenge __attribute__((unused)),
+                                unsigned challen __attribute__((unused)),
+                                void **conn_context)
+{
+    context_t *text;
+
+    /* holds state are in */
+    text = sparams->utils->malloc(sizeof(context_t));
+    if (text == NULL) {
+       MEMERROR(sparams->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(context_t));
+    
+    text->state = 1;
+    text->utils = sparams->utils;
+    text->cs_integrity_key = text->recv_integrity_key + 4;
+    text->sc_integrity_key = text->send_integrity_key + 4;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int
+passdss_server_mech_step1(context_t *text,
+                         sasl_server_params_t *params,
+                         const char *clientin,
+                         unsigned clientinlen,
+                         const char **serverout,
+                         unsigned *serveroutlen,
+                         sasl_out_params_t *oparams __attribute__((unused)))
+{
+    BIGNUM *X = NULL;
+    DSA *dsa = NULL;
+    unsigned char *K = NULL;
+    unsigned Klen, hashlen;
+    int need, musthave;
+    EVP_MD_CTX mdctx;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    DSA_SIG *sig = NULL;
+    int result;
+    
+    /* Expect:
+     *
+     * (1) string azname       ; authorization name
+     * (2) string authname     ; authentication name
+     * (3) mpint  X            ; Diffie-Hellman parameter X
+     */
+    
+    result = UnBuffer(params->utils, clientin, clientinlen,
+                     "%s%s%m", &text->userid, &text->authid, &X);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 1");
+       goto cleanup;
+    }
+
+    /* Fetch DSA (XXX create one for now) */
+    dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL);
+    if (!dsa) {
+       result = SASL_FAIL;
+       goto cleanup;
+    }
+    DSA_generate_key(dsa);
+
+    /* Create Diffie-Hellman parameters */
+    text->dh = DH_new();
+    BN_hex2bn(&text->dh->p, N);
+    BN_hex2bn(&text->dh->g, g);
+    DH_generate_key(text->dh);
+
+    /* Alloc space for shared secret K as mpint */
+    K = text->utils->malloc(DH_size(text->dh) + 4);
+    if (!K) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error allocing K\n");
+       result = SASL_NOMEM;
+       goto cleanup;
+    }
+
+    /* Calculate DH shared secret (leave space at head for length) */
+    Klen = DH_compute_key(K+4, X, text->dh);
+
+    /* Prepend length in network byte order (make it a mpint) */
+    *((uint32_t *) K) = htonl(Klen);
+    Klen += 4;
+
+    /* Which layers can we support? */
+    if (params->props.maxbufsize < 32) {
+       need = musthave = 0;
+    } else {
+       need = params->props.max_ssf - params->external_ssf;
+       musthave = params->props.min_ssf - params->external_ssf;
+    }
+
+    if (musthave <= NO_LAYER_SSF)
+       text->secmask |= NO_LAYER_FLAG;
+    if ((musthave <= INTEGRITY_LAYER_SSF) && (INTEGRITY_LAYER_SSF <= need))
+       text->secmask |= INTEGRITY_LAYER_FLAG;
+    if ((musthave <= PRIVACY_LAYER_SSF) && (PRIVACY_LAYER_SSF <= need))
+       text->secmask |= PRIVACY_LAYER_FLAG;
+
+
+    /* Send out:
+     *
+     * (4) uint32   pklength   ; length of SSH-style DSA server public key
+     *       string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+     *       mpint  p          ; DSA public key parameters
+     *       mpint  q
+     *       mpint  g
+     *       mpint  y
+     * (5) mpint    Y          ; Diffie-Hellman parameter Y
+     * (6) OCTET    ssecmask   ; SASL security layers offered
+     * (7) 3 OCTET  sbuflen    ; maximum server security layer block size
+     * (8) uint32   siglength  ; length of SSH-style dss signature
+     *       string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+     *       mpint  r          ; DSA signature parameters
+     *       mpint  s
+     */
+
+    /* Items (4) - (7) */
+    result = MakeBuffer(text->utils, &text->out_buf, 0, &text->out_buf_len,
+                       serveroutlen, "%5a%s%m%m%m%m%m%1o%3u",
+                       "ssh-dss", dsa->p, dsa->q, dsa->g, dsa->pub_key,
+                       text->dh->pub_key, &text->secmask,
+                       (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                       params->props.maxbufsize);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+
+    /* Hash (1) - (7) and K */
+    EVP_DigestInit(&mdctx, EVP_sha1());
+    /* (1) - (3) */
+    EVP_DigestUpdate(&mdctx, clientin, clientinlen);
+    /* (4) - (7) */
+    EVP_DigestUpdate(&mdctx, text->out_buf, *serveroutlen);
+    /* K */
+    EVP_DigestUpdate(&mdctx, K, Klen);
+    EVP_DigestFinal(&mdctx, hash, &hashlen);
+
+    /* Calculate security layer params */
+    CalcLayerParams(text, K, Klen, hash, hashlen);
+
+    /* Start cli-hmac */
+    HMAC_CTX_init(&text->hmac_recv_ctx);
+    HMAC_Init_ex(&text->hmac_recv_ctx, text->cs_integrity_key,
+                SHA_DIGEST_LENGTH, EVP_sha1(), NULL);
+    /* (1) - (3) */
+    HMAC_Update(&text->hmac_recv_ctx, clientin, clientinlen);
+    /* (4) - (7) */
+    HMAC_Update(&text->hmac_recv_ctx, text->out_buf, *serveroutlen);
+
+    /* Sign the hash */
+    sig = DSA_do_sign(hash, hashlen, dsa);
+    if (!sig) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error calculating DSS signature\n");
+       result = SASL_FAIL;
+       goto cleanup;
+    }
+
+    /* Item (8) */
+    result = MakeBuffer(text->utils, &text->out_buf, *serveroutlen,
+                       &text->out_buf_len, serveroutlen,
+                       "%3a%s%m%m", "ssh-dss", sig->r, sig->s);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+    *serverout = text->out_buf;
+
+    text->state = 2;
+    result = SASL_CONTINUE;
+
+  cleanup:
+    if (X) BN_free(X);
+    if (K) text->utils->free(K);
+    if (dsa) DSA_free(dsa);
+    if (sig) DSA_SIG_free(sig);
+
+    return result;
+}
+
+static int
+passdss_server_mech_step2(context_t *text,
+                         sasl_server_params_t *params,
+                         const char *clientin,
+                         unsigned clientinlen,
+                         const char **serverout __attribute__((unused)),
+                         unsigned *serveroutlen __attribute__((unused)),
+                         sasl_out_params_t *oparams)
+{
+    char *password = NULL;
+    unsigned declen, hmaclen;
+    unsigned char *csecmask, *cli_hmac, hmac[EVP_MAX_MD_SIZE];
+    uint32_t cbufsiz;
+    int r, result = SASL_OK;
+    
+    /* Expect (3DES encrypted):
+     *
+     * (9) OCTET    csecmask   ; SASL security layer selection
+     *     3 OCTET  cbuflen    ; maximum client block size
+     *     string   passphrase ; the user's passphrase
+     *     20 OCTET cli-hmac   ; a client HMAC-SHA-1 signature
+     */
+
+    /* Alloc space for the decrypted input */
+    result = _plug_buf_alloc(text->utils, &text->decode_pkt_buf,
+                            &text->decode_pkt_buf_len, clientinlen);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error allocating decrypt buffer in step 2\n");
+       goto cleanup;
+    }
+
+    /* Initialize decrypt cipher */
+    EVP_CIPHER_CTX_init(&text->cipher_dec_ctx);
+    EVP_DecryptInit_ex(&text->cipher_dec_ctx, EVP_des_ede3_cbc(), NULL,
+                      text->cs_encryption_key, text->cs_encryption_iv);
+    EVP_CIPHER_CTX_set_padding(&text->cipher_dec_ctx, 0);
+    text->blk_siz = EVP_CIPHER_CTX_block_size(&text->cipher_dec_ctx);
+
+    /* Decrypt the blob */
+    r = EVP_DecryptUpdate(&text->cipher_dec_ctx, text->decode_pkt_buf, &declen,
+                         clientin, clientinlen);
+    if (r)
+       r = EVP_DecryptFinal_ex(&text->cipher_dec_ctx,  /* should be no output */
+                               text->decode_pkt_buf + declen, &declen);
+    if (!r) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error decrypting input in step 2");
+       result = SASL_BADPROT;
+       goto cleanup;
+    }
+    clientin = text->decode_pkt_buf;
+
+    result = UnBuffer(params->utils, clientin, clientinlen,
+                     "%-1o%3u%s%-*o%*p", &csecmask, &cbufsiz, &password,
+                     SHA_DIGEST_LENGTH, &cli_hmac, text->blk_siz - 1);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 2");
+       goto cleanup;
+    }
+
+    /* Finish cli-hmac */
+    /* (1) - (7) hashed in step 1 */
+    /* 1st 4 bytes of (9) */
+    HMAC_Update(&text->hmac_recv_ctx, clientin, 4);
+    HMAC_Final(&text->hmac_recv_ctx, hmac, &hmaclen);
+
+    /* Verify cli-hmac */
+    if (memcmp(cli_hmac, hmac, hmaclen)) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Client HMAC verification failed");
+       result = SASL_BADMAC;
+       goto cleanup;
+    }
+
+    /* Canonicalize authentication ID first, so that password verification
+     * is only against the canonical id */
+    result = params->canon_user(params->utils->conn,
+                               text->authid, 0, SASL_CU_AUTHID, oparams);
+    if (result != SASL_OK) {
+       return result;
+    }
+    
+    /* Verify password - return sasl_ok on success */
+    result = params->utils->checkpass(params->utils->conn,
+                                     oparams->authid, oparams->alen,
+                                     password, strlen(password));
+        
+    if (result != SASL_OK) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Password verification failed");
+       goto cleanup;
+    }
+
+    /* Canonicalize and store the authorization ID */
+    /* We need to do this after calling verify_user just in case verify_user
+     * needed to get auxprops itself */
+    result = params->canon_user(params->utils->conn,
+                               *text->userid ? text->userid : text->authid, 0,
+                               SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) return result;
+
+    /* See which layer the client selected */
+    text->secmask &= *csecmask;
+    if (text->secmask & PRIVACY_LAYER_FLAG) {
+       oparams->mech_ssf = PRIVACY_LAYER_SSF;
+    } else if (text->secmask & INTEGRITY_LAYER_FLAG) {
+       oparams->mech_ssf = INTEGRITY_LAYER_SSF;
+    } else if (text->secmask & NO_LAYER_FLAG) {
+       oparams->mech_ssf = NO_LAYER_SSF;
+    } else {
+       /* Mark that we tried */
+       oparams->mech_ssf = 2;
+       SETERROR(params->utils,
+                "unable to agree on layers with server");
+       return SASL_BADPROT;
+    }
+
+    /* Set oparams */
+    oparams->doneflag = 1;
+    oparams->param_version = 0;
+
+    if (oparams->mech_ssf > 0) {
+       oparams->encode = &passdss_encode;
+       oparams->decode = &passdss_decode;
+       oparams->maxoutbuf = cbufsiz - 4 - SHA_DIGEST_LENGTH; /* -len -HMAC */
+
+       HMAC_CTX_init(&text->hmac_send_ctx);
+
+       if (oparams->mech_ssf > 1) {
+           oparams->maxoutbuf -= text->blk_siz-1; /* padding */
+
+           /* Initialize encrypt cipher */
+           EVP_CIPHER_CTX_init(&text->cipher_enc_ctx);
+           EVP_EncryptInit_ex(&text->cipher_enc_ctx, EVP_des_ede3_cbc(), NULL,
+                              text->sc_encryption_key, text->sc_encryption_iv);
+           EVP_CIPHER_CTX_set_padding(&text->cipher_enc_ctx, 0);
+       }
+
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         params->props.maxbufsize);
+    }
+    else {
+       oparams->encode = NULL;
+       oparams->decode = NULL;
+       oparams->maxoutbuf = 0;
+    }
+
+    result = SASL_OK;
+    
+  cleanup:
+    if (password) _plug_free_string(params->utils, &password);
+
+    return result;
+}
+
+static int passdss_server_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)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    if (!sparams
+       || !serverout
+       || !serveroutlen
+       || !oparams)
+       return SASL_BADPARAM;
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "PASSDSS server step %d\n", text->state);
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+       
+    switch (text->state) {
+
+    case 1:
+       return passdss_server_mech_step1(text, sparams, clientin, clientinlen,
+                                        serverout, serveroutlen, oparams);
+
+    case 2:
+       return passdss_server_mech_step2(text, sparams, clientin, clientinlen,
+                                        serverout, serveroutlen, oparams);
+
+    default:
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "Invalid PASSDSS server step %d", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+static sasl_server_plug_t passdss_server_plugins[] = 
+{
+    {
+       "PASSDSS-3DES-1",               /* mech_name */
+       112,                            /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NODICTIONARY
+       | SASL_SEC_FORWARD_SECRECY
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &passdss_server_mech_new,       /* mech_new */
+       &passdss_server_mech_step,      /* mech_step */
+       &passdss_common_mech_dispose,   /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int passdss_server_plug_init(const sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_server_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "PASSDSS version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = passdss_server_plugins;
+    *plugcount = 1;  
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+static int passdss_client_mech_new(void *glob_context __attribute__((unused)),
+                                sasl_client_params_t *params,
+                                void **conn_context)
+{
+    context_t *text;
+
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(context_t));
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(context_t));
+    
+    text->state = 1;
+    text->utils = params->utils;
+    text->cs_integrity_key = text->send_integrity_key + 4;
+    text->sc_integrity_key = text->recv_integrity_key + 4;
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int
+passdss_client_mech_step1(context_t *text,
+                         sasl_client_params_t *params,
+                         const char *serverin __attribute__((unused)),
+                         unsigned serverinlen __attribute__((unused)),
+                         sasl_interact_t **prompt_need,
+                         const char **clientout,
+                         unsigned *clientoutlen,
+                         sasl_out_params_t *oparams)
+{
+    const char *user = NULL, *authid = NULL;
+    int user_result = SASL_OK;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    int result;
+
+    /* Expect: absolutely nothing */
+    if (serverinlen > 0) {
+       SETERROR(params->utils, "Invalid input to first step of PASSDSS\n");
+       return SASL_BADPROT;
+    }
+
+    /* check if security layer is strong enough */
+    if (params->props.min_ssf > PRIVACY_LAYER_SSF + params->external_ssf) {
+       SETERROR(params->utils,
+                "minimum ssf too strong for PASSDSS");
+       return SASL_TOOWEAK;
+    }
+
+    /* try to get the authid */    
+    if (oparams->authid == NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }          
+    
+    /* try to get the userid */
+    if (oparams->user == NULL) {
+       user_result = _plug_get_userid(params->utils, &user, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
+           return user_result;
+    }
+    
+    /* try to get the password */
+    if (text->password == NULL) {
+       pass_result = _plug_get_password(params->utils, &text->password,
+                                        &text->free_password, prompt_need);
+       
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) ||
+       (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) goto cleanup;
+       
+       return SASL_INTERACT;
+    }
+    
+    if (!text->password) {
+       PARAMERROR(params->utils);
+       return SASL_BADPARAM;
+    }
+
+    if (!user || !*user) {
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    }
+    else {
+       result = params->canon_user(params->utils->conn, user, 0,
+                                   SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) goto cleanup;
+       
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+    }
+    if (result != SASL_OK) goto cleanup;
+
+    /* create Diffie-Hellman parameters */
+    text->dh = DH_new();
+    BN_hex2bn(&text->dh->p, N);
+    BN_hex2bn(&text->dh->g, g);
+    DH_generate_key(text->dh);
+
+
+    /* Send out:
+     *
+     * (1) string azname       ; authorization name
+     * (2) string authname     ; authentication name
+     * (3) mpint  X            ; Diffie-Hellman parameter X
+     */
+    
+    result = MakeBuffer(text->utils, &text->out_buf, 0, &text->out_buf_len,
+                       clientoutlen, "%s%s%m",
+                       (user && *user) ? (char *) oparams->user : "",
+                       (char *) oparams->authid, text->dh->pub_key);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+    *clientout = text->out_buf;
+    
+    text->state = 2;
+    result = SASL_CONTINUE;
+
+  cleanup:
+    
+    return result;
+}
+
+static int
+passdss_client_mech_step2(context_t *text,
+                         sasl_client_params_t *params,
+                         const char *serverin,
+                         unsigned serverinlen,
+                         sasl_interact_t **prompt_need __attribute__((unused)),
+                         const char **clientout,
+                         unsigned *clientoutlen,
+                         sasl_out_params_t *oparams)
+{
+    DSA *dsa = DSA_new();
+    DSA_SIG *sig = DSA_SIG_new();
+    BIGNUM *Y = NULL;
+    uint32_t siglen;
+    unsigned char *K = NULL;
+    unsigned Klen, hashlen, enclen;
+    unsigned char *ssecmask;
+    uint32_t sbufsiz;
+    EVP_MD_CTX mdctx;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    int need, musthave;
+    int result, r;
+    
+    /* Expect:
+     *
+     * (4) uint32   pklength   ; length of SSH-style DSA server public key
+     *       string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+     *       mpint  p          ; DSA public key parameters
+     *       mpint  q
+     *       mpint  g
+     *       mpint  y
+     * (5) mpint    Y          ; Diffie-Hellman parameter Y
+     * (6) OCTET    ssecmask   ; SASL security layers offered
+     * (7) 3 OCTET  sbuflen    ; maximum server security layer block size
+     * (8) uint32   siglength  ; length of SSH-style dss signature
+     *       string "ssh-dss"  ; constant string "ssh-dss" (lower case)
+     *       mpint  r          ; DSA signature parameters
+     *       mpint  s
+     */
+
+    result = UnBuffer(params->utils, serverin, serverinlen,
+                     "%u%3p\7ssh-dss%m%m%m%m%m%-1o%3u%u%3p\7ssh-dss%m%m",
+                     NULL, &dsa->p, &dsa->q, &dsa->g, &dsa->pub_key,
+                     &Y, &ssecmask, &sbufsiz, &siglen, &sig->r, &sig->s);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 2");
+       goto cleanup;
+    }
+
+    /* XXX  Validate server DSA public key */
+
+    /* Alloc space for shared secret K as mpint */
+    K = text->utils->malloc(DH_size(text->dh) + 4);
+    if (!K) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error allocing K\n");
+       result = SASL_NOMEM;
+       goto cleanup;
+    }
+
+    /* Calculate DH shared secret (leave space at head for length) */
+    Klen = DH_compute_key(K+4, Y, text->dh);
+
+    /* Prepend length in network byte order (make it a mpint) */
+    *((uint32_t *) K) = htonl(Klen);
+    Klen += 4;
+
+    /* Hash (1) - (7) and K */
+    EVP_DigestInit(&mdctx, EVP_sha1());
+    /* (1) - (3) (output from step 1 still in buffer) */
+    EVP_DigestUpdate(&mdctx, text->out_buf, text->out_buf_len);
+    /* (4) - (7) */
+    EVP_DigestUpdate(&mdctx, serverin, serverinlen - siglen - 4);
+    /* K */
+    EVP_DigestUpdate(&mdctx, K, Klen);
+    EVP_DigestFinal(&mdctx, hash, &hashlen);
+
+    /* Verify signature on the hash */
+    result = DSA_do_verify(hash, hashlen, sig, dsa);
+    if (result != 1) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          (result == 0) ? "Incorrect DSS signature\n" :
+                          "Error verifying DSS signature\n");
+       result = (result == 0) ? SASL_BADPROT : SASL_FAIL;
+       goto cleanup;
+    }
+
+    /* Calculate security layer params */
+    CalcLayerParams(text, K, Klen, hash, hashlen);
+
+    /* Initialize encrypt cipher */
+    EVP_CIPHER_CTX_init(&text->cipher_enc_ctx);
+    EVP_EncryptInit_ex(&text->cipher_enc_ctx, EVP_des_ede3_cbc(), NULL,
+                      text->cs_encryption_key, text->cs_encryption_iv);
+    EVP_CIPHER_CTX_set_padding(&text->cipher_enc_ctx, 0);
+    text->blk_siz = EVP_CIPHER_CTX_block_size(&text->cipher_enc_ctx);
+
+    /* pick a layer */
+    if (params->props.maxbufsize < 32) {
+       need = musthave = 0;
+    } else {
+       need = params->props.max_ssf - params->external_ssf;
+       musthave = params->props.min_ssf - params->external_ssf;
+    }
+
+    if ((*ssecmask & PRIVACY_LAYER_FLAG) &&
+       (need >= PRIVACY_LAYER_SSF) && (musthave <= PRIVACY_LAYER_SSF)) {
+       text->secmask = PRIVACY_LAYER_FLAG;
+       oparams->mech_ssf = PRIVACY_LAYER_SSF;
+    } else if ((*ssecmask & INTEGRITY_LAYER_FLAG) &&
+              (need >= INTEGRITY_LAYER_SSF) &&
+              (musthave <= INTEGRITY_LAYER_SSF)) {
+       text->secmask =INTEGRITY_LAYER_FLAG;
+       oparams->mech_ssf = INTEGRITY_LAYER_SSF;
+    } else if ((*ssecmask & NO_LAYER_FLAG) && (musthave <= NO_LAYER_SSF)) {
+       text->secmask = NO_LAYER_FLAG;
+       oparams->mech_ssf = NO_LAYER_SSF;
+    } else {
+       /* Mark that we tried */
+       oparams->mech_ssf = 2;
+       SETERROR(params->utils,
+                "unable to agree on layers with server");
+       return SASL_BADPROT;
+    }
+
+    /* Start cli-hmac */
+    HMAC_CTX_init(&text->hmac_send_ctx);
+    HMAC_Init_ex(&text->hmac_send_ctx, text->cs_integrity_key,
+                SHA_DIGEST_LENGTH, EVP_sha1(), NULL);
+    /* (1) - (3) (output from step 1 still in buffer) */
+    HMAC_Update(&text->hmac_send_ctx, text->out_buf, text->out_buf_len);
+    /* (4) - (7) */
+    HMAC_Update(&text->hmac_send_ctx, serverin, serverinlen - siglen - 4);
+
+
+    /* Send out (3DES encrypted):
+     *
+     * (9) OCTET    csecmask   ; SASL security layer selection
+     *     3 OCTET  cbuflen    ; maximum client block size
+     *     string   passphrase ; the user's passphrase
+     *     20 OCTET cli-hmac   ; a client HMAC-SHA-1 signature
+     */
+
+    result = MakeBuffer(text->utils, &text->out_buf, 0,
+                       &text->out_buf_len, clientoutlen, "%1o%3u%*s",
+                       &text->secmask,
+                       (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                       params->props.maxbufsize,
+                       text->password->len, text->password->data);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+
+    /* Finish cli-hmac */
+    /* 1st 4 bytes of (9) */
+    HMAC_Update(&text->hmac_send_ctx, text->out_buf, 4);
+    HMAC_Final(&text->hmac_send_ctx, hash, &hashlen);
+
+    /* Add HMAC and pad to fill no more than current block */
+    result = MakeBuffer(text->utils, &text->out_buf, *clientoutlen,
+                       &text->out_buf_len, clientoutlen, "%*o%*o",
+                       hashlen, hash, text->blk_siz - 1, text->padding);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+
+    /* Alloc space for the encrypted output */
+    result = _plug_buf_alloc(text->utils, &text->encode_buf,
+                            &text->encode_buf_len, *clientoutlen);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error allocating encrypt buffer in step 2\n");
+       goto cleanup;
+    }
+
+    /* Encrypt (9) (here we calculate the exact number of full blocks) */
+    r = EVP_EncryptUpdate(&text->cipher_enc_ctx, text->encode_buf,
+                         clientoutlen, text->out_buf,
+                         text->blk_siz * (*clientoutlen / text->blk_siz));
+    if (r)
+       r = EVP_EncryptFinal_ex(&text->cipher_enc_ctx,  /* should be no output */
+                               text->encode_buf + *clientoutlen, &enclen);
+    if (!r) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error encrypting output in step 2");
+       result = SASL_FAIL;
+       goto cleanup;
+    }
+    *clientout = text->encode_buf;
+
+    /* Set oparams */
+    oparams->doneflag = 1;
+    oparams->param_version = 0;
+
+    if (oparams->mech_ssf > 0) {
+       oparams->encode = &passdss_encode;
+       oparams->decode = &passdss_decode;
+       oparams->maxoutbuf = sbufsiz - 4 - SHA_DIGEST_LENGTH; /* -len -HMAC */
+
+       HMAC_CTX_init(&text->hmac_recv_ctx);
+
+       if (oparams->mech_ssf > 1) {
+           oparams->maxoutbuf -= text->blk_siz-1; /* padding */
+
+           /* Initialize decrypt cipher */
+           EVP_CIPHER_CTX_init(&text->cipher_dec_ctx);
+           EVP_DecryptInit_ex(&text->cipher_dec_ctx, EVP_des_ede3_cbc(), NULL,
+                              text->sc_encryption_key, text->sc_encryption_iv);
+           EVP_CIPHER_CTX_set_padding(&text->cipher_dec_ctx, 0);
+       }
+
+       _plug_decode_init(&text->decode_context, text->utils,
+                         (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF :
+                         params->props.maxbufsize);
+    }
+    else {
+       oparams->encode = NULL;
+       oparams->decode = NULL;
+       oparams->maxoutbuf = 0;
+    }
+
+    result = SASL_OK;
+ cleanup:
+    if (Y) BN_free(Y);
+    if (K) text->utils->free(K);
+    if (dsa) DSA_free(dsa);
+    if (sig) DSA_SIG_free(sig);
+    
+    return result;
+}
+
+static int passdss_client_mech_step(void *conn_context,
+                                   sasl_client_params_t *params,
+                                   const char *serverin,
+                                   unsigned serverinlen,
+                                   sasl_interact_t **prompt_need,
+                                   const char **clientout,
+                                   unsigned *clientoutlen,
+                                   sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "PASSDSS client step %d\n", text->state);
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    switch (text->state) {
+
+    case 1:
+       return passdss_client_mech_step1(text, params, serverin, serverinlen, 
+                                        prompt_need, clientout, clientoutlen,
+                                        oparams);
+
+    case 2:
+       return passdss_client_mech_step2(text, params, serverin, serverinlen, 
+                                        prompt_need, clientout, clientoutlen,
+                                        oparams);
+
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid PASSDSS client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+
+static sasl_client_plug_t passdss_client_plugins[] = 
+{
+    {
+       "PASSDSS-3DES-1",               /* mech_name */
+       112,                            /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NODICTIONARY
+       | SASL_SEC_FORWARD_SECRECY
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &passdss_client_mech_new,       /* mech_new */
+       &passdss_client_mech_step,      /* mech_step */
+       &passdss_common_mech_dispose,   /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int passdss_client_plug_init(sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_client_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "PASSDSS version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = passdss_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/passdss_init.c b/plugins/passdss_init.c
new file mode 100644 (file)
index 0000000..3a35fb7
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_passdss_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( passdss )
+SASL_SERVER_PLUG_INIT( passdss )
+
diff --git a/plugins/plain.c b/plugins/plain.c
new file mode 100644 (file)
index 0000000..ef3dec8
--- /dev/null
@@ -0,0 +1,448 @@
+/* Plain SASL plugin
+ * Rob Siemborski
+ * Tim Martin 
+ * $Id: plain.c,v 1.64 2004/09/08 11:06:11 mel 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <string.h> 
+#include <sasl.h>
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh 
+#include <sasl_plain_plugin_decl.h> 
+#endif 
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: plain.c,v 1.64 2004/09/08 11:06:11 mel Exp $";
+
+/*****************************  Server Section  *****************************/
+
+static int plain_server_mech_new(void *glob_context __attribute__((unused)), 
+                                sasl_server_params_t *sparams,
+                                const char *challenge __attribute__((unused)),
+                                unsigned challen __attribute__((unused)),
+                                void **conn_context)
+{
+    /* holds state are in */
+    if (!conn_context) {
+       PARAMERROR( sparams->utils );
+       return SASL_BADPARAM;
+    }
+    
+    *conn_context = NULL;
+    
+    return SASL_OK;
+}
+
+static int plain_server_mech_step(void *conn_context __attribute__((unused)),
+                                 sasl_server_params_t *params,
+                                 const char *clientin,
+                                 unsigned clientinlen,
+                                 const char **serverout,
+                                 unsigned *serveroutlen,
+                                 sasl_out_params_t *oparams)
+{
+    const char *author;
+    const char *authen;
+    const char *password;
+    unsigned password_len;
+    unsigned lup=0;
+    int result;
+    char *passcopy; 
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+    
+    /* should have received author-id NUL authen-id NUL password */
+    
+    /* get author */
+    author = clientin;
+    while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+    
+    if (lup >= clientinlen) {
+       SETERROR(params->utils, "Can only find author (no password)");
+       return SASL_BADPROT;
+    }
+    
+    /* get authen */
+    ++lup;
+    authen = clientin + lup;
+    while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+    
+    if (lup >= clientinlen) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Can only find author/en (no password)");
+       return SASL_BADPROT;
+    }
+    
+    /* get password */
+    lup++;
+    password = clientin + lup;
+    while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup;
+    
+    password_len = (unsigned) (clientin + lup - password);
+    
+    if (lup != clientinlen) {
+       SETERROR(params->utils,
+                "Got more data than we were expecting in the PLAIN plugin\n");
+       return SASL_BADPROT;
+    }
+    
+    /* this kinda sucks. we need password to be null terminated
+       but we can't assume there is an allocated byte at the end
+       of password so we have to copy it */
+    passcopy = params->utils->malloc(password_len + 1);    
+    if (passcopy == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    strncpy(passcopy, password, password_len);
+    passcopy[password_len] = '\0';
+   
+    /* Canonicalize userid first, so that password verification is only
+     * against the canonical id */
+    if (!author || !*author)
+       author = authen;
+    
+    result = params->canon_user(params->utils->conn,
+                               authen, 0, SASL_CU_AUTHID, oparams);
+    if (result != SASL_OK) {
+       _plug_free_string(params->utils, &passcopy);
+       return result;
+    }
+    
+    /* verify password - return sasl_ok on success*/
+    result = params->utils->checkpass(params->utils->conn,
+                                     oparams->authid, oparams->alen,
+                                     passcopy, password_len);
+    
+    _plug_free_string(params->utils, &passcopy);
+    
+    if (result != SASL_OK) {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Password verification failed");
+       return result;
+    }
+
+    /* Canonicalize and store the authorization ID */
+    /* We need to do this after calling verify_user just in case verify_user
+     * needed to get auxprops itself */
+    result = params->canon_user(params->utils->conn,
+                               author, 0, SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) return result;
+
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t plain_server_plugins[] = 
+{
+    {
+       "PLAIN",                        /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOANONYMOUS,           /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &plain_server_mech_new,         /* mech_new */
+       &plain_server_mech_step,        /* mech_step */
+       NULL,                           /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* setpass */
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       NULL,                           /* mech_avail */
+       NULL                            /* spare */
+    }
+};
+
+int plain_server_plug_init(const sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_server_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "PLAIN version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = plain_server_plugins;
+    *plugcount = 1;  
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+typedef struct client_context {
+    char *out_buf;
+    unsigned out_buf_len;
+} client_context_t;
+
+static int plain_client_mech_new(void *glob_context __attribute__((unused)),
+                                sasl_client_params_t *params,
+                                void **conn_context)
+{
+    client_context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(client_context_t));
+    if (text == NULL) {
+       MEMERROR( params->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(client_context_t));
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int plain_client_mech_step(void *conn_context,
+                                 sasl_client_params_t *params,
+                                 const char *serverin __attribute__((unused)),
+                                 unsigned serverinlen __attribute__((unused)),
+                                 sasl_interact_t **prompt_need,
+                                 const char **clientout,
+                                 unsigned *clientoutlen,
+                                 sasl_out_params_t *oparams)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    const char *user = NULL, *authid = NULL;
+    sasl_secret_t *password = NULL;
+    unsigned int free_password = 0; /* set if we need to free password */
+    int user_result = SASL_OK;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    int result;
+    char *p;
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    /* doesn't really matter how the server responds */
+    
+    /* check if sec layer strong enough */
+    if (params->props.min_ssf > params->external_ssf) {
+       SETERROR( params->utils, "SSF requested of PLAIN plugin");
+       return SASL_TOOWEAK;
+    }
+    
+    /* try to get the authid */    
+    if (oparams->authid == NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }          
+    
+    /* try to get the userid */
+    if (oparams->user == NULL) {
+       user_result = _plug_get_userid(params->utils, &user, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
+           return user_result;
+    }
+    
+    /* try to get the password */
+    if (password == NULL) {
+       pass_result = _plug_get_password(params->utils, &password,
+                                        &free_password, prompt_need);
+       
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) ||
+       (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) goto cleanup;
+       
+       return SASL_INTERACT;
+    }
+    
+    if (!password) {
+       PARAMERROR(params->utils);
+       return SASL_BADPARAM;
+    }
+
+    if (!user || !*user) {
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    }
+    else {
+       result = params->canon_user(params->utils->conn, user, 0,
+                                   SASL_CU_AUTHZID, oparams);
+       if (result != SASL_OK) goto cleanup;
+       
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+    }
+    if (result != SASL_OK) goto cleanup;
+    
+    /* send authorized id NUL authentication id NUL password */
+    *clientoutlen = ((user && *user ? oparams->ulen : 0) +
+                    1 + oparams->alen +
+                    1 + password->len);
+    
+    /* remember the extra NUL on the end for stupid clients */
+    result = _plug_buf_alloc(params->utils, &(text->out_buf),
+                            &(text->out_buf_len), *clientoutlen + 1);
+    if (result != SASL_OK) goto cleanup;
+    
+    memset(text->out_buf, 0, *clientoutlen + 1);
+    p = text->out_buf;
+    if (user && *user) {
+       memcpy(p, oparams->user, oparams->ulen);
+       p += oparams->ulen;
+    }
+    memcpy(++p, oparams->authid, oparams->alen);
+    p += oparams->alen;
+    memcpy(++p, password->data, password->len);
+    
+    *clientout = text->out_buf;
+    
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->mech_ssf = 0;
+    oparams->maxoutbuf = 0;
+    oparams->encode_context = NULL;
+    oparams->encode = NULL;
+    oparams->decode_context = NULL;
+    oparams->decode = NULL;
+    oparams->param_version = 0;
+    
+    result = SASL_OK;
+
+  cleanup:
+    /* free sensitive info */
+    if (free_password) _plug_free_secret(params->utils, &password);
+    
+    return result;
+}
+
+static void plain_client_mech_dispose(void *conn_context,
+                                     const sasl_utils_t *utils)
+{
+    client_context_t *text = (client_context_t *) conn_context;
+    
+    if (!text) return;
+    
+    if (text->out_buf) utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static sasl_client_plug_t plain_client_plugins[] = 
+{
+    {
+       "PLAIN",                        /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOANONYMOUS,           /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &plain_client_mech_new,         /* mech_new */
+       &plain_client_mech_step,        /* mech_step */
+       &plain_client_mech_dispose,     /* mech_dispose */
+       NULL,                           /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int plain_client_plug_init(sasl_utils_t *utils,
+                          int maxversion,
+                          int *out_version,
+                          sasl_client_plug_t **pluglist,
+                          int *plugcount)
+{
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "PLAIN version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = plain_client_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/plain_init.c b/plugins/plain_init.c
new file mode 100644 (file)
index 0000000..0ca8f58
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_plain_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( plain )
+SASL_SERVER_PLUG_INIT( plain )
+
diff --git a/plugins/plugin_common.c b/plugins/plugin_common.c
new file mode 100644 (file)
index 0000000..c59b027
--- /dev/null
@@ -0,0 +1,924 @@
+/* Generic SASL plugin utility functions
+ * Rob Siemborski
+ * $Id: plugin_common.c,v 1.20 2004/06/23 18:43:37 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.
+ */
+
+#include <config.h>
+#ifndef macintosh
+#ifdef WIN32
+# include <winsock2.h>
+#else
+# include <sys/socket.h>
+# include <netinet/in.h>
+# include <arpa/inet.h>
+# include <netdb.h>
+# include <sys/utsname.h>
+#endif /* WIN32 */
+#endif /* macintosh */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#include "plugin_common.h"
+
+/* translate IPv4 mapped IPv6 address to IPv4 address */
+static void sockaddr_unmapped(
+#ifdef IN6_IS_ADDR_V4MAPPED
+  struct sockaddr *sa, socklen_t *len
+#else
+  struct sockaddr *sa __attribute__((unused)),
+  socklen_t *len __attribute__((unused))
+#endif
+)
+{
+#ifdef IN6_IS_ADDR_V4MAPPED
+    struct sockaddr_in6 *sin6;
+    struct sockaddr_in *sin4;
+    uint32_t addr;
+    int port;
+
+    if (sa->sa_family != AF_INET6)
+       return;
+    sin6 = (struct sockaddr_in6 *)sa;
+    if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr)))
+       return;
+    sin4 = (struct sockaddr_in *)sa;
+    addr = *(uint32_t *)&sin6->sin6_addr.s6_addr[12];
+    port = sin6->sin6_port;
+    memset(sin4, 0, sizeof(struct sockaddr_in));
+    sin4->sin_addr.s_addr = addr;
+    sin4->sin_port = port;
+    sin4->sin_family = AF_INET;
+#ifdef HAVE_SOCKADDR_SA_LEN
+    sin4->sin_len = sizeof(struct sockaddr_in);
+#endif
+    *len = sizeof(struct sockaddr_in);
+#else
+    return;
+#endif
+}
+
+int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr,
+                      struct sockaddr *out, socklen_t outlen) 
+{
+    int i, j;
+    socklen_t len;
+    struct sockaddr_storage ss;
+    struct addrinfo hints, *ai = NULL;
+    char hbuf[NI_MAXHOST];
+    
+    if(!utils || !addr || !out) {
+       if(utils) PARAMERROR( utils );
+       return SASL_BADPARAM;
+    }
+
+    /* Parse the address */
+    for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) {
+       if (i >= NI_MAXHOST) {
+           if(utils) PARAMERROR( utils );
+           return SASL_BADPARAM;
+       }
+       hbuf[i] = addr[i];
+    }
+    hbuf[i] = '\0';
+
+    if (addr[i] == ';')
+       i++;
+    /* XXX/FIXME: Do we need this check? */
+    for (j = i; addr[j] != '\0'; j++)
+       if (!isdigit((int)(addr[j]))) {
+           PARAMERROR( utils );
+           return SASL_BADPARAM;
+       }
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
+
+    if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) {       
+       PARAMERROR( utils );
+       return SASL_BADPARAM;
+    }
+
+    len = ai->ai_addrlen;
+    memcpy(&ss, ai->ai_addr, len);
+    freeaddrinfo(ai);
+    sockaddr_unmapped((struct sockaddr *)&ss, &len);
+    if (outlen < len) {
+       PARAMERROR( utils );
+       return SASL_BUFOVER;
+    }
+
+    memcpy(out, &ss, len);
+
+    return SASL_OK;
+}
+
+int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec,
+                      unsigned numiov, buffer_info_t **output) 
+{
+    unsigned i;
+    int ret;
+    buffer_info_t *out;
+    char *pos;
+
+    if(!utils || !vec || !output) {
+       if(utils) PARAMERROR( utils );
+       return SASL_BADPARAM;
+    }
+    
+    if(!(*output)) {
+       *output = utils->malloc(sizeof(buffer_info_t));
+       if(!*output) {
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+       memset(*output,0,sizeof(buffer_info_t));
+    }
+
+    out = *output;
+    
+    out->curlen = 0;
+    for(i=0; i<numiov; i++)
+       out->curlen += vec[i].iov_len;
+
+    ret = _plug_buf_alloc(utils, &out->data, &out->reallen, out->curlen);
+
+    if(ret != SASL_OK) {
+       MEMERROR(utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(out->data, 0, out->reallen);
+    pos = out->data;
+    
+    for(i=0; i<numiov; i++) {
+       memcpy(pos, vec[i].iov_base, vec[i].iov_len);
+       pos += vec[i].iov_len;
+    }
+
+    return SASL_OK;
+}
+
+/* Basically a conditional call to realloc(), if we need more */
+int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf,
+                   unsigned *curlen, unsigned newlen) 
+{
+    if(!utils || !rwbuf || !curlen) {
+       PARAMERROR(utils);
+       return SASL_BADPARAM;
+    }
+
+    if(!(*rwbuf)) {
+       *rwbuf = utils->malloc(newlen);
+       if (*rwbuf == NULL) {
+           *curlen = 0;
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+       *curlen = newlen;
+    } else if(*rwbuf && *curlen < newlen) {
+       size_t needed = 2*(*curlen);
+
+       while(needed < newlen)
+           needed *= 2;
+
+       *rwbuf = utils->realloc(*rwbuf, needed);
+       if (*rwbuf == NULL) {
+           *curlen = 0;
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+       *curlen = needed;
+    } 
+
+    return SASL_OK;
+}
+
+/* copy a string */
+int _plug_strdup(const sasl_utils_t * utils, const char *in,
+                char **out, int *outlen)
+{
+  size_t len = strlen(in);
+
+  if(!utils || !in || !out) {
+      if(utils) PARAMERROR(utils);
+      return SASL_BADPARAM;
+  }
+
+  *out = utils->malloc(len + 1);
+  if (!*out) {
+      MEMERROR(utils);
+      return SASL_NOMEM;
+  }
+
+  strcpy((char *) *out, in);
+
+  if (outlen)
+      *outlen = len;
+
+  return SASL_OK;
+}
+
+void _plug_free_string(const sasl_utils_t *utils, char **str)
+{
+  size_t len;
+
+  if (!utils || !str || !(*str)) return;
+
+  len = strlen(*str);
+
+  utils->erasebuffer(*str, len);
+  utils->free(*str);
+
+  *str=NULL;
+}
+
+void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret) 
+{
+    if(!utils || !secret || !(*secret)) return;
+
+    utils->erasebuffer((*secret)->data, (*secret)->len);
+    utils->free(*secret);
+    *secret = NULL;
+}
+
+/* 
+ * Trys to find the prompt with the lookingfor id in the prompt list
+ * Returns it if found. NULL otherwise
+ */
+sasl_interact_t *_plug_find_prompt(sasl_interact_t **promptlist,
+                                  unsigned int lookingfor)
+{
+    sasl_interact_t *prompt;
+
+    if (promptlist && *promptlist) {
+       for (prompt = *promptlist; prompt->id != SASL_CB_LIST_END; ++prompt) {
+           if (prompt->id==lookingfor)
+               return prompt;
+       }
+    }
+
+    return NULL;
+}
+
+/*
+ * Retrieve the simple string given by the callback id.
+ */
+int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required,
+                    const char **result, sasl_interact_t **prompt_need)
+{
+
+    int ret = SASL_FAIL;
+    sasl_getsimple_t *simple_cb;
+    void *simple_context;
+    sasl_interact_t *prompt;
+
+    *result = NULL;
+
+    /* see if we were given the result in the prompt */
+    prompt = _plug_find_prompt(prompt_need, id);
+    if (prompt != NULL) {
+       /* We prompted, and got.*/
+       
+       if (required && !prompt->result) {
+           SETERROR(utils, "Unexpectedly missing a prompt result");
+           return SASL_BADPARAM;
+       }
+
+       *result = prompt->result;
+       return SASL_OK;
+    }
+  
+    /* Try to get the callback... */
+    ret = utils->getcallback(utils->conn, id, &simple_cb, &simple_context);
+
+    if (ret == SASL_FAIL && !required)
+       return SASL_OK;
+
+    if (ret == SASL_OK && simple_cb) {
+       ret = simple_cb(simple_context, id, result, NULL);
+       if (ret != SASL_OK)
+           return ret;
+
+       if (required && !*result) {
+           PARAMERROR(utils);
+           return SASL_BADPARAM;
+       }
+    }
+  
+    return ret;
+}
+
+/*
+ * Retrieve the user password.
+ */
+int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **password,
+                      unsigned int *iscopy, sasl_interact_t **prompt_need)
+{
+    int ret = SASL_FAIL;
+    sasl_getsecret_t *pass_cb;
+    void *pass_context;
+    sasl_interact_t *prompt;
+
+    *password = NULL;
+    *iscopy = 0;
+
+    /* see if we were given the password in the prompt */
+    prompt = _plug_find_prompt(prompt_need, SASL_CB_PASS);
+    if (prompt != NULL) {
+       /* We prompted, and got.*/
+       
+       if (!prompt->result) {
+           SETERROR(utils, "Unexpectedly missing a prompt result");
+           return SASL_BADPARAM;
+       }
+      
+       /* copy what we got into a secret_t */
+       *password = (sasl_secret_t *) utils->malloc(sizeof(sasl_secret_t) +
+                                                   prompt->len + 1);
+       if (!*password) {
+           MEMERROR(utils);
+           return SASL_NOMEM;
+       }
+      
+       (*password)->len=prompt->len;
+       memcpy((*password)->data, prompt->result, prompt->len);
+       (*password)->data[(*password)->len]=0;
+
+       *iscopy = 1;
+
+       return SASL_OK;
+    }
+
+    /* Try to get the callback... */
+    ret = utils->getcallback(utils->conn, SASL_CB_PASS,
+                            &pass_cb, &pass_context);
+
+    if (ret == SASL_OK && pass_cb) {
+       ret = pass_cb(utils->conn, pass_context, SASL_CB_PASS, password);
+       if (ret != SASL_OK)
+           return ret;
+
+       if (!*password) {
+           PARAMERROR(utils);
+           return SASL_BADPARAM;
+       }
+    }
+
+    return ret;
+}
+
+/*
+ * Retrieve the string given by the challenge prompt id.
+ */
+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 ret = SASL_FAIL;
+    sasl_chalprompt_t *chalprompt_cb;
+    void *chalprompt_context;
+    sasl_interact_t *prompt;
+
+    *result = NULL;
+
+    /* see if we were given the password in the prompt */
+    prompt = _plug_find_prompt(prompt_need, id);
+    if (prompt != NULL) {
+       /* We prompted, and got.*/
+       
+       if (!prompt->result) {
+           SETERROR(utils, "Unexpectedly missing a prompt result");
+           return SASL_BADPARAM;
+       }
+      
+       *result = prompt->result;
+       return SASL_OK;
+    }
+
+    /* Try to get the callback... */
+    ret = utils->getcallback(utils->conn, id,
+                            &chalprompt_cb, &chalprompt_context);
+
+    if (ret == SASL_OK && chalprompt_cb) {
+       ret = chalprompt_cb(chalprompt_context, id,
+                           challenge, promptstr, NULL, result, NULL);
+       if (ret != SASL_OK)
+           return ret;
+
+       if (!*result) {
+           PARAMERROR(utils);
+           return SASL_BADPARAM;
+       }
+    }
+
+    return ret;
+}
+
+/*
+ * Retrieve the client realm.
+ */
+int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms,
+                   const char **realm, sasl_interact_t **prompt_need)
+{
+    int ret = SASL_FAIL;
+    sasl_getrealm_t *realm_cb;
+    void *realm_context;
+    sasl_interact_t *prompt;
+
+    *realm = NULL;
+
+    /* see if we were given the result in the prompt */
+    prompt = _plug_find_prompt(prompt_need, SASL_CB_GETREALM);
+    if (prompt != NULL) {
+       /* We prompted, and got.*/
+       
+       if (!prompt->result) {
+           SETERROR(utils, "Unexpectedly missing a prompt result");
+           return SASL_BADPARAM;
+       }
+
+       *realm = prompt->result;
+       return SASL_OK;
+    }
+
+    /* Try to get the callback... */
+    ret = utils->getcallback(utils->conn, SASL_CB_GETREALM,
+                            &realm_cb, &realm_context);
+
+    if (ret == SASL_OK && realm_cb) {
+       ret = realm_cb(realm_context, SASL_CB_GETREALM, availrealms, realm);
+       if (ret != SASL_OK)
+           return ret;
+
+       if (!*realm) {
+           PARAMERROR(utils);
+           return SASL_BADPARAM;
+       }
+    }
+  
+    return ret;
+}
+
+/*
+ * Make the requested prompts. (prompt==NULL means we don't want it)
+ */
+int _plug_make_prompts(const sasl_utils_t *utils,
+                      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 num = 1;
+    int alloc_size;
+    sasl_interact_t *prompts;
+
+    if (user_prompt) num++;
+    if (auth_prompt) num++;
+    if (pass_prompt) num++;
+    if (echo_prompt) num++;
+    if (realm_prompt) num++;
+
+    if (num == 1) {
+       SETERROR( utils, "make_prompts() called with no actual prompts" );
+       return SASL_FAIL;
+    }
+
+    alloc_size = sizeof(sasl_interact_t)*num;
+    prompts = utils->malloc(alloc_size);
+    if (!prompts) {
+       MEMERROR( utils );
+       return SASL_NOMEM;
+    }
+    memset(prompts, 0, alloc_size);
+  
+    *prompts_res = prompts;
+
+    if (user_prompt) {
+       (prompts)->id = SASL_CB_USER;
+       (prompts)->challenge = "Authorization Name";
+       (prompts)->prompt = user_prompt;
+       (prompts)->defresult = user_def;
+
+       prompts++;
+    }
+
+    if (auth_prompt) {
+       (prompts)->id = SASL_CB_AUTHNAME;
+       (prompts)->challenge = "Authentication Name";
+       (prompts)->prompt = auth_prompt;
+       (prompts)->defresult = auth_def;
+
+       prompts++;
+    }
+
+    if (pass_prompt) {
+       (prompts)->id = SASL_CB_PASS;
+       (prompts)->challenge = "Password";
+       (prompts)->prompt = pass_prompt;
+       (prompts)->defresult = pass_def;
+
+       prompts++;
+    }
+
+    if (echo_prompt) {
+       (prompts)->id = SASL_CB_ECHOPROMPT;
+       (prompts)->challenge = echo_chal;
+       (prompts)->prompt = echo_prompt;
+       (prompts)->defresult = echo_def;
+
+       prompts++;
+    }
+
+    if (realm_prompt) {
+       (prompts)->id = SASL_CB_GETREALM;
+       (prompts)->challenge = realm_chal;
+       (prompts)->prompt = realm_prompt;
+       (prompts)->defresult = realm_def;
+
+       prompts++;
+    }
+
+    /* add the ending one */
+    (prompts)->id = SASL_CB_LIST_END;
+    (prompts)->challenge = NULL;
+    (prompts)->prompt = NULL;
+    (prompts)->defresult = NULL;
+
+    return SASL_OK;
+}
+
+void _plug_decode_init(decode_context_t *text,
+                      const sasl_utils_t *utils, unsigned int in_maxbuf)
+{
+    memset(text, 0, sizeof(decode_context_t));
+
+    text->utils = utils;
+    text->needsize = 4;
+    text->in_maxbuf = in_maxbuf;
+}
+
+/*
+ * Decode as much of the input as possible (possibly none),
+ * using decode_pkt() to decode individual packets.
+ */
+int _plug_decode(decode_context_t *text,
+                const char *input, unsigned inputlen,
+                char **output,         /* output buffer */
+                unsigned *outputsize,  /* current size of output buffer */
+                unsigned *outputlen,   /* length of data in output buffer */
+                int (*decode_pkt)(void *rock,
+                                  const char *input, unsigned inputlen,
+                                  char **output, unsigned *outputlen),
+                void *rock)
+{
+    unsigned int tocopy;
+    unsigned diff;
+    char *tmp;
+    unsigned tmplen;
+    int ret;
+    
+    *outputlen = 0;
+
+    while (inputlen) { /* more input */
+       if (text->needsize) { /* need to get the rest of the 4-byte size */
+
+           /* copy as many bytes (up to 4) as we have into size buffer */
+           tocopy = (inputlen > text->needsize) ? text->needsize : inputlen;
+           memcpy(text->sizebuf + 4 - text->needsize, input, tocopy);
+           text->needsize -= tocopy;
+       
+           input += tocopy;
+           inputlen -= tocopy;
+       
+           if (!text->needsize) { /* we have the entire 4-byte size */
+               memcpy(&(text->size), text->sizebuf, 4);
+               text->size = ntohl(text->size);
+       
+               if (!text->size) /* should never happen */
+                   return SASL_FAIL;
+           
+               if (text->size > text->in_maxbuf) {
+                   text->utils->log(NULL, SASL_LOG_ERR, 
+                                    "encoded packet size too big (%d > %d)",
+                                    text->size, text->in_maxbuf);
+                   return SASL_FAIL;
+               }
+           
+               if (!text->buffer)
+                   text->buffer = text->utils->malloc(text->in_maxbuf);
+               if (text->buffer == NULL) return SASL_NOMEM;
+
+               text->cursize = 0;
+           } else {
+               /* We do NOT have the entire 4-byte size...
+                * wait for more data */
+               return SASL_OK;
+           }
+       }
+
+       diff = text->size - text->cursize; /* bytes needed for full packet */
+
+       if (inputlen < diff) {  /* not a complete packet, need more input */
+           memcpy(text->buffer + text->cursize, input, inputlen);
+           text->cursize += inputlen;
+           return SASL_OK;
+       }
+
+       /* copy the rest of the packet */
+       memcpy(text->buffer + text->cursize, input, diff);
+       input += diff;
+       inputlen -= diff;
+
+       /* decode the packet (no need to free tmp) */
+       ret = decode_pkt(rock, text->buffer, text->size, &tmp, &tmplen);
+       if (ret != SASL_OK) return ret;
+
+       /* append the decoded packet to the output */
+       ret = _plug_buf_alloc(text->utils, output, outputsize,
+                             *outputlen + tmplen + 1); /* +1 for NUL */
+       if (ret != SASL_OK) return ret;
+
+       memcpy(*output + *outputlen, tmp, tmplen);
+       *outputlen += tmplen;
+
+       /* protect stupid clients */
+       *(*output + *outputlen) = '\0';
+
+       /* reset for the next packet */
+       text->needsize = 4;
+    }
+
+    return SASL_OK;    
+}
+
+void _plug_decode_free(decode_context_t *text)
+{
+    if (text->buffer) text->utils->free(text->buffer);
+}
+
+/* returns the realm we should pretend to be in */
+int _plug_parseuser(const sasl_utils_t *utils,
+                   char **user, char **realm, const char *user_realm, 
+                   const char *serverFQDN, const char *input)
+{
+    int ret;
+    char *r;
+
+    if(!user || !serverFQDN) {
+       PARAMERROR( utils );
+       return SASL_BADPARAM;
+    }
+
+    r = strchr(input, '@');
+    if (!r) {
+       /* hmmm, the user didn't specify a realm */
+       if(user_realm && user_realm[0]) {
+           ret = _plug_strdup(utils, user_realm, realm, NULL);
+       } else {
+           /* Default to serverFQDN */
+           ret = _plug_strdup(utils, serverFQDN, realm, NULL);
+       }
+       
+       if (ret == SASL_OK) {
+           ret = _plug_strdup(utils, input, user, NULL);
+       }
+    } else {
+       r++;
+       ret = _plug_strdup(utils, r, realm, NULL);
+       *--r = '\0';
+       *user = utils->malloc(r - input + 1);
+       if (*user) {
+           strncpy(*user, input, r - input +1);
+       } else {
+           MEMERROR( utils );
+           ret = SASL_NOMEM;
+       }
+       *r = '@';
+    }
+
+    return ret;
+}
+
+int _plug_make_fulluser(const sasl_utils_t *utils,
+                       char **fulluser,
+                       const char * useronly,
+                       const char *realm)
+{
+    if(!fulluser || !useronly || !realm) {
+       PARAMERROR( utils );
+       return (SASL_BADPARAM);
+    }
+
+    *fulluser = utils->malloc (strlen(useronly) + strlen(realm) + 2);
+    if (*fulluser == NULL) {
+       MEMERROR( utils );
+       return (SASL_NOMEM);
+    }
+
+    strcpy (*fulluser, useronly);
+    strcat (*fulluser, "@");
+    strcat (*fulluser, realm);
+
+    return (SASL_OK);
+}
+
+char * _plug_get_error_message (const sasl_utils_t *utils,
+#ifdef WIN32
+                               DWORD error
+#else
+                               int error
+#endif
+                               )
+{
+    char * return_value;
+#ifdef WIN32
+    LPVOID lpMsgBuf;
+
+    FormatMessage( 
+       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+       FORMAT_MESSAGE_FROM_SYSTEM | 
+       FORMAT_MESSAGE_IGNORE_INSERTS,
+       NULL,
+       error,
+       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+       (LPTSTR) &lpMsgBuf,
+       0,
+       NULL 
+    );
+
+    if (_plug_strdup (utils, lpMsgBuf, &return_value, NULL) != SASL_OK) {
+       return_value = NULL;
+    }
+
+    LocalFree( lpMsgBuf );
+#else /* !WIN32 */
+    if (_plug_strdup (utils, strerror(error), &return_value, NULL) != SASL_OK) {
+       return_value = NULL;
+    }
+#endif /* WIN32 */
+    return (return_value);
+}
+
+void _plug_snprintf_os_info (char * osbuf, int osbuf_len)
+{
+#ifdef WIN32
+    OSVERSIONINFOEX versioninfo;
+    char *sysname;
+
+/* :
+  DWORD dwOSVersionInfoSize; 
+  DWORD dwMajorVersion; 
+  DWORD dwMinorVersion; 
+  DWORD dwBuildNumber; 
+  TCHAR szCSDVersion[ 128 ];
+//Only NT SP 6 and later
+  WORD wServicePackMajor;
+  WORD wServicePackMinor;
+  WORD wSuiteMask;
+  BYTE wProductType;
+ */
+
+    versioninfo.dwOSVersionInfoSize = sizeof (versioninfo);
+    sysname = "Unknown Windows";
+
+    if (GetVersionEx ((OSVERSIONINFO *) &versioninfo) == FALSE) {
+       snprintf(osbuf, osbuf_len, "%s", sysname);
+       goto SKIP_OS_INFO;
+    }
+
+    switch (versioninfo.dwPlatformId) {
+       case VER_PLATFORM_WIN32s: /* Win32s on Windows 3.1 */
+           sysname = "Win32s on Windows 3.1";
+/* I can't test if dwBuildNumber has any meaning on Win32s */
+           break;
+
+       case VER_PLATFORM_WIN32_WINDOWS: /* 95/98/ME */
+           switch (versioninfo.dwMinorVersion) {
+               case 0:
+                   sysname = "Windows 95";
+                   break;
+               case 10:
+                   sysname = "Windows 98";
+                   break;
+               case 90:
+                   sysname = "Windows Me";
+                   break;
+               default:
+                   sysname = "Unknown Windows 9X/ME series";
+                   break;
+           }
+/* Clear the high order word, as it contains major/minor version */
+           versioninfo.dwBuildNumber &= 0xFFFF;
+           break;
+
+       case VER_PLATFORM_WIN32_NT: /* NT/2000/XP/.NET */
+           if (versioninfo.dwMinorVersion > 99) {
+           } else {
+               switch (versioninfo.dwMajorVersion * 100 + versioninfo.dwMinorVersion) {
+                   case 351:
+                       sysname = "Windows NT 3.51";
+                       break;
+                   case 400:
+                       sysname = "Windows NT 4.0";
+                       break;
+                   case 500:
+                       sysname = "Windows 2000";
+                       break;
+                   case 501:
+                       sysname = "Windows XP/.NET"; /* or Windows .NET Server */
+                       break;
+                   default:
+                       sysname = "Unknown Windows NT series";
+                       break;
+               }
+           }
+           break;
+
+       default:
+           break;
+    }
+
+    snprintf(osbuf, osbuf_len,
+            "%s %s (Build %u)",
+            sysname,
+            versioninfo.szCSDVersion,
+            versioninfo.dwBuildNumber
+            );
+
+SKIP_OS_INFO:
+    ;
+
+#else /* !WIN32 */
+    struct utsname os;
+
+    uname(&os);
+    snprintf(osbuf, osbuf_len, "%s %s", os.sysname, os.release);
+#endif /* WIN32 */
+}
+
+#if defined(WIN32)
+unsigned int plug_sleep (unsigned int seconds)
+{
+    long dwSec = seconds*1000;
+    Sleep (dwSec);
+    return 0;
+}
+#endif
diff --git a/plugins/plugin_common.h b/plugins/plugin_common.h
new file mode 100644 (file)
index 0000000..0f75897
--- /dev/null
@@ -0,0 +1,222 @@
+
+/* Generic SASL plugin utility functions
+ * Rob Siemborski
+ * $Id: plugin_common.h,v 1.21 2006/01/17 12:18:21 mel 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 <winsock2.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
+#define MEMERROR( utils ) \
+    (utils)->seterror( (utils)->conn, 0, \
+                       "Out of Memory in " __FILE__ " near line %d", __LINE__ )
+#endif
+
+#ifndef PARAMERROR
+#define PARAMERROR( utils ) \
+    (utils)->seterror( (utils)->conn, 0, \
+                       "Parameter Error in " __FILE__ " near line %d", __LINE__ )
+#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
+
+#ifdef __cplusplus
+extern "C" {
+#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,
+                      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);
+
+typedef struct decode_context {
+    const sasl_utils_t *utils;
+    unsigned int needsize;     /* How much of the 4-byte size do we need? */
+    char sizebuf[4];           /* Buffer to accumulate the 4-byte size */
+    unsigned int size;         /* Absolute size of the encoded packet */
+    char *buffer;              /* Buffer to accumulate an encoded packet */
+    unsigned int cursize;      /* Amount of packet data in the buffer */
+    unsigned int in_maxbuf;    /* Maximum allowed size of an incoming encoded packet */
+} decode_context_t;
+
+void _plug_decode_init(decode_context_t *text,
+                      const sasl_utils_t *utils, unsigned int in_maxbuf);
+
+int _plug_decode(decode_context_t *text,
+                const char *input, unsigned inputlen,
+                char **output, unsigned *outputsize, unsigned *outputlen,
+                int (*decode_pkt)(void *rock,
+                                  const char *input, unsigned inputlen,
+                                  char **output, unsigned *outputlen),
+                void *rock);
+
+void _plug_decode_free(decode_context_t *text);
+
+int _plug_parseuser(const sasl_utils_t *utils,
+                   char **user, char **realm, const char *user_realm, 
+                   const char *serverFQDN, const char *input);
+
+int _plug_make_fulluser(const sasl_utils_t *utils,
+                       char **fulluser, const char * useronly, const char *realm);
+
+char * _plug_get_error_message (const sasl_utils_t *utils,
+#ifdef WIN32
+                               DWORD error
+#else
+                               int error
+#endif
+                               );
+void _plug_snprintf_os_info (char * osbuf, int osbuf_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PLUGIN_COMMON_H_ */
diff --git a/plugins/sasldb.c b/plugins/sasldb.c
new file mode 100644 (file)
index 0000000..d899d7a
--- /dev/null
@@ -0,0 +1,240 @@
+/* SASL server API implementation
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: sasldb.c,v 1.11 2006/04/03 10:58:19 mel 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.
+ */
+
+#include <config.h>
+
+/* sasldb stuff */
+
+#include <stdio.h>
+
+#include "sasl.h"
+#include "saslutil.h"
+#include "saslplug.h"
+#include "../sasldb/sasldb.h"
+
+#include "plugin_common.h"
+
+static void sasldb_auxprop_lookup(void *glob_context __attribute__((unused)),
+                                 sasl_server_params_t *sparams,
+                                 unsigned flags,
+                                 const char *user,
+                                 unsigned ulen) 
+{
+    char *userid = NULL;
+    char *realm = NULL;
+    const char *user_realm = NULL;
+    int ret;
+    const struct propval *to_fetch, *cur;
+    char value[8192];
+    size_t value_len;
+    char *user_buf;
+    
+    if(!sparams || !user) return;
+
+    user_buf = sparams->utils->malloc(ulen + 1);
+    if(!user_buf) {
+       goto done;
+    }
+
+    memcpy(user_buf, user, ulen);
+    user_buf[ulen] = '\0';
+
+    if(sparams->user_realm) {
+       user_realm = sparams->user_realm;
+    } else {
+       user_realm = sparams->serverFQDN;
+    }
+
+    ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm,
+                         sparams->serverFQDN, user_buf);
+    if(ret != SASL_OK) goto done;
+
+    to_fetch = sparams->utils->prop_get(sparams->propctx);
+    if(!to_fetch) goto done;
+
+    for(cur = to_fetch; cur->name; cur++) {
+       const char *realname = cur->name;
+       
+       /* Only look up properties that apply to this lookup! */
+       if(cur->name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) continue;
+       if(!(flags & SASL_AUXPROP_AUTHZID)) {
+           if(cur->name[0] != '*') continue;
+           else realname = cur->name + 1;
+       }
+       
+       /* If it's there already, we want to see if it needs to be
+        * overridden */
+       if(cur->values && !(flags & SASL_AUXPROP_OVERRIDE))
+           continue;
+       else if(cur->values)
+           sparams->utils->prop_erase(sparams->propctx, cur->name);
+           
+       ret = _sasldb_getdata(sparams->utils,
+                             sparams->utils->conn, userid, realm,
+                             realname, value, sizeof(value), &value_len);
+       if(ret != SASL_OK) {
+           /* We didn't find it, leave it as not found */
+           continue;
+       }
+
+       sparams->utils->prop_set(sparams->propctx, cur->name,
+                                value, (unsigned) value_len);
+    }
+
+ done:
+    if (userid) sparams->utils->free(userid);
+    if (realm)  sparams->utils->free(realm);
+    if (user_buf) sparams->utils->free(user_buf);
+}
+
+static int sasldb_auxprop_store(void *glob_context __attribute__((unused)),
+                               sasl_server_params_t *sparams,
+                               struct propctx *ctx,
+                               const char *user,
+                               unsigned ulen) 
+{
+    char *userid = NULL;
+    char *realm = NULL;
+    const char *user_realm = NULL;
+    int ret = SASL_FAIL;
+    int tmp_res;
+    const struct propval *to_store, *cur;
+    char *user_buf;
+
+    /* just checking if we are enabled */
+    if(!ctx) return SASL_OK;
+    
+    if(!sparams || !user) return SASL_BADPARAM;
+
+    user_buf = sparams->utils->malloc(ulen + 1);
+    if(!user_buf) {
+       ret = SASL_NOMEM;
+       goto done;
+    }
+
+    memcpy(user_buf, user, ulen);
+    user_buf[ulen] = '\0';
+
+    if(sparams->user_realm) {
+       user_realm = sparams->user_realm;
+    } else {
+       user_realm = sparams->serverFQDN;
+    }
+
+    ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm,
+                         sparams->serverFQDN, user_buf);
+    if(ret != SASL_OK) goto done;
+
+    to_store = sparams->utils->prop_get(ctx);
+    if(!to_store) {
+       ret = SASL_BADPARAM;
+       goto done;
+    }
+
+    /* All iterations return SASL_NOUSER                   ==> ret = SASL_NOUSER
+       Some iterations return SASL_OK and some SASL_NOUSER ==> ret = SASL_OK
+       At least one iteration returns any other error      ==> ret = the error */
+    ret = SASL_NOUSER;
+    for(cur = to_store; cur->name; cur++) {
+       /* We only support one value at a time right now. */
+       tmp_res = _sasldb_putdata(sparams->utils, sparams->utils->conn,
+                             userid, realm, cur->name,
+                             cur->values && cur->values[0] ?
+                             cur->values[0] : NULL,
+                             cur->values && cur->values[0] ?
+                             strlen(cur->values[0]) : 0);
+        /* SASL_NOUSER is returned when _sasldb_putdata fails to delete
+           a non-existent entry, which should not be treated as an error */
+        if ((tmp_res != SASL_NOUSER) &&
+            (ret == SASL_NOUSER || ret == SASL_OK)) {
+            ret = tmp_res;
+        }
+
+        /* Abort the loop if an error has occurred */
+        if (ret != SASL_NOUSER && ret != SASL_OK) {
+            break;
+        }
+    }
+
+ done:
+    if (userid) sparams->utils->free(userid);
+    if (realm)  sparams->utils->free(realm);
+    if (user_buf) sparams->utils->free(user_buf);
+
+    return ret;
+}
+
+static sasl_auxprop_plug_t sasldb_auxprop_plugin = {
+    0,                         /* Features */
+    0,                         /* spare */
+    NULL,                      /* glob_context */
+    sasldb_auxprop_free,        /* auxprop_free */
+    sasldb_auxprop_lookup,     /* auxprop_lookup */
+    "sasldb",                  /* name */
+    sasldb_auxprop_store       /* auxprop_store */
+};
+
+int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
+                             int max_version,
+                             int *out_version,
+                             sasl_auxprop_plug_t **plug,
+                             const char *plugname __attribute__((unused))) 
+{
+    if(!out_version || !plug) return SASL_BADPARAM;
+
+    /* Do we have database support? */
+    /* Note that we can use a NULL sasl_conn_t because our
+     * sasl_utils_t is "blessed" with the global callbacks */
+    if(_sasl_check_db(utils, NULL) != SASL_OK)
+       return SASL_NOMECH;
+
+    if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS;
+    
+    *out_version = SASL_AUXPROP_PLUG_VERSION;
+
+    *plug = &sasldb_auxprop_plugin;
+
+    return SASL_OK;
+}
diff --git a/plugins/sasldb_init.c b/plugins/sasldb_init.c
new file mode 100644 (file)
index 0000000..c75e1a8
--- /dev/null
@@ -0,0 +1,38 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_AUXPROP_PLUG_INIT( sasldb )
+
diff --git a/plugins/sql.c b/plugins/sql.c
new file mode 100644 (file)
index 0000000..b873653
--- /dev/null
@@ -0,0 +1,1113 @@
+/*
+**
+** SQL Auxprop plugin
+**
+** Ken Murchison
+** Maya Nigrosh -- original store() and txn support
+** Simon Loader -- original mysql plugin
+** Patrick Welche -- original pgsql plugin
+**
+** $Id: sql.c,v 1.29 2006/04/07 13:42:16 jeaton Exp $
+**
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "sasl.h"
+#include "saslutil.h"
+#include "saslplug.h"
+
+#include <ctype.h>
+
+#include "plugin_common.h"
+
+#define sql_max(a, b) ((a) > (b) ? (a) : (b))
+#define sql_len(input) ((input) ? strlen(input) : 0)
+#define sql_exists(input) ((input) && (*input))
+
+typedef struct sql_engine {
+    const char *name;
+    void *(*sql_open)(char *host, char *port, int usessl,
+                     const char *user, const char *password,
+                     const char *database, const sasl_utils_t *utils);
+    int (*sql_escape_str)(char *to, const char *from);
+    int (*sql_begin_txn)(void *conn, const sasl_utils_t *utils);
+    int (*sql_commit_txn)(void *conn, const sasl_utils_t *utils);
+    int (*sql_rollback_txn)(void *conn, const sasl_utils_t *utils);
+    int (*sql_exec)(void *conn, const char *cmd, char *value, size_t size,
+                   size_t *value_len, const sasl_utils_t *utils);
+    void (*sql_close)(void *conn);
+} sql_engine_t;
+
+typedef struct sql_settings {
+    const sql_engine_t *sql_engine;
+    const char *sql_user;
+    const char *sql_passwd;
+    const char *sql_hostnames;
+    const char *sql_database;
+    const char *sql_select;
+    const char *sql_insert;
+    const char *sql_update;
+    int sql_usessl;
+} sql_settings_t;
+
+static const char * SQL_BLANK_STRING = "";
+static const char * SQL_WILDCARD = "*";
+static const char * SQL_NULL_VALUE = "NULL";
+
+
+#ifdef HAVE_MYSQL
+#include <mysql.h>
+
+static void *_mysql_open(char *host, char *port, int usessl,
+                        const char *user, const char *password,
+                        const char *database, const sasl_utils_t *utils)
+{
+    MYSQL *mysql;
+    
+    if (!(mysql = mysql_init(NULL))) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "sql plugin: could not execute mysql_init()");
+       return NULL;
+    }
+    
+    return mysql_real_connect(mysql, host, user, password, database,
+                             port ? strtoul(port, NULL, 10) : 0, NULL,
+                             usessl ? CLIENT_SSL : 0);
+}
+
+static int _mysql_escape_str(char *to, const char *from)
+{
+    return mysql_escape_string(to, from, strlen(from));
+}
+
+static int _mysql_exec(void *conn, const char *cmd, char *value, size_t size,
+                      size_t *value_len, const sasl_utils_t *utils)
+{
+    MYSQL_RES *result;
+    MYSQL_ROW row;
+    int row_count, len;
+    
+    len = strlen(cmd);
+    /* mysql_real_query() doesn't want a terminating ';' */
+    if (cmd[len-1] == ';') len--;
+
+    /* 
+     *  Run the query. It is important to note that mysql_real_query
+     *  will return success even if the sql statement 
+     *  had an error in it. However, mysql_errno() will alsways
+     *  tell us if there was an error. Therefore we can ignore
+     *  the result from mysql_real_query and simply check mysql_errno()
+     *  to decide if there was really an error.
+     */
+    (void)mysql_real_query(conn, cmd, len);
+
+    if(mysql_errno(conn)) {
+        utils->log(NULL, SASL_LOG_ERR, "sql query failed: %s",
+                  mysql_error(conn));
+       return -1;
+    }
+
+    /* see if we should expect some results */
+    if (!mysql_field_count(conn)) {
+       /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */
+       return 0;
+    }
+
+    /* get the results */
+    result = mysql_store_result(conn);
+    if (!result) {
+       /* umm nothing found */
+       utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
+       return -1;
+    }
+
+    /* quick row check */
+    row_count = mysql_num_rows(result);
+    if (!row_count) {
+       /* umm nothing found */
+       mysql_free_result(result);
+       utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
+       return -1;
+    }
+    if (row_count > 1) {
+       utils->log(NULL, SASL_LOG_WARN,
+                  "sql plugin: found duplicate row for query %s", cmd);
+    }
+    
+    /* now get the result set value and value_len */
+    /* we only fetch one because we don't care about the rest */
+    row = mysql_fetch_row(result);
+    if (!row || !row[0]) {
+       /* umm nothing found */
+       utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
+       mysql_free_result(result);
+       return -1;
+    }
+    if (value) {
+       strncpy(value, row[0], size-2);
+       value[size-1] = '\0';
+       if (value_len) *value_len = strlen(value);
+    }
+    
+    /* free result */
+    mysql_free_result(result);
+    
+    return 0;
+}
+
+static int _mysql_begin_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _mysql_exec(conn,
+#if MYSQL_VERSION_ID >= 40011
+                      "START TRANSACTION",
+#else
+                      "BEGIN",
+#endif
+                      NULL, 0, NULL, utils);
+}
+
+static int _mysql_commit_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _mysql_exec(conn, "COMMIT", NULL, 0, NULL, utils);
+}
+
+static int _mysql_rollback_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _mysql_exec(conn, "ROLLBACK", NULL, 0, NULL, utils);
+}
+
+static void _mysql_close(void *conn)
+{
+    mysql_close(conn);
+}
+#endif /* HAVE_MYSQL */
+
+#ifdef HAVE_PGSQL
+#include <libpq-fe.h>
+
+static void *_pgsql_open(char *host, char *port, int usessl,
+                        const char *user, const char *password,
+                        const char *database, const sasl_utils_t *utils)
+{
+    PGconn *conn = NULL;
+    char *conninfo, *sep;
+    
+    /* create the connection info string */
+    /* The 64 represents the number of characters taken by
+     * the keyword tokens, plus a small pad
+     */
+    conninfo = utils->malloc(64 + sql_len(host) + sql_len(port)
+                            + sql_len(user) + sql_len(password)
+                            + sql_len(database));
+    if (!conninfo) {
+       MEMERROR(utils);
+       return NULL;
+    }
+    
+    /* add each term that exists */
+    conninfo[0] = '\0';
+    sep = "";
+    if (sql_exists(host)) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "host='");
+       strcat(conninfo, host);
+       strcat(conninfo, "'");
+       sep = " ";
+    }
+    if (sql_exists(port)) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "port='");
+       strcat(conninfo, port);
+       strcat(conninfo, "'");
+       sep = " ";
+    }
+    if (sql_exists(user)) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "user='");
+       strcat(conninfo, user);
+       strcat(conninfo, "'");
+       sep = " ";
+    }
+    if (sql_exists(password)) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "password='");
+       strcat(conninfo, password);
+       strcat(conninfo, "'");
+       sep = " ";
+    }
+    if (sql_exists(database)) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "dbname='");
+       strcat(conninfo, database);
+       strcat(conninfo, "'");
+       sep = " ";
+    }
+    if (usessl) {
+       strcat(conninfo, sep);
+       strcat(conninfo, "requiressl='1'");
+    }
+    
+    conn = PQconnectdb(conninfo);
+    free(conninfo);
+    
+    if ((PQstatus(conn) != CONNECTION_OK)) {
+       utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", PQerrorMessage(conn));
+       return NULL;
+    }
+    
+    return conn;
+}
+
+static int _pgsql_escape_str(char *to, const char *from)
+{
+    return PQescapeString(to, from, strlen(from));
+}
+
+static int _pgsql_exec(void *conn, const char *cmd, char *value, size_t size,
+                      size_t *value_len, const sasl_utils_t *utils)
+{
+    PGresult *result;
+    int row_count;
+    ExecStatusType status;
+    
+    /* run the query */
+    result = PQexec(conn, cmd);
+    
+    /* check the status */
+    status = PQresultStatus(result);
+    if (status == PGRES_COMMAND_OK) {
+       /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */
+       PQclear(result);
+       return 0;
+    }
+    else if (status != PGRES_TUPLES_OK) {
+       /* error */
+       utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ",
+                  PQresStatus(status));
+       PQclear(result);
+       return -1;
+    }
+    
+    /* quick row check */
+    row_count = PQntuples(result);
+    if (!row_count) {
+       /* umm nothing found */
+       utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
+       PQclear(result);
+       return -1;
+    }
+    if (row_count > 1) {
+       utils->log(NULL, SASL_LOG_WARN,
+                  "sql plugin: found duplicate row for query %s", cmd);
+    }
+    
+    /* now get the result set value and value_len */
+    /* we only fetch one because we don't care about the rest */
+    if (value) {
+       strncpy(value, PQgetvalue(result,0,0), size-2);
+       value[size-1] = '\0';
+       if (value_len) *value_len = strlen(value);
+    }
+    
+    /* free result */
+    PQclear(result);
+    return 0;
+}
+
+static int _pgsql_begin_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _pgsql_exec(conn, "BEGIN;", NULL, 0, NULL, utils);
+}
+
+static int _pgsql_commit_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _pgsql_exec(conn, "COMMIT;", NULL, 0, NULL, utils);
+}
+
+static int _pgsql_rollback_txn(void *conn, const sasl_utils_t *utils)
+{
+    return _pgsql_exec(conn, "ROLLBACK;", NULL, 0, NULL, utils);
+}
+
+static void _pgsql_close(void *conn)
+{
+    PQfinish(conn);
+}
+#endif /* HAVE_PGSQL */
+
+#ifdef HAVE_SQLITE
+#include <sqlite.h>
+
+static void *_sqlite_open(char *host __attribute__((unused)),
+                         char *port __attribute__((unused)),
+                         int usessl __attribute__((unused)),
+                         const char *user __attribute__((unused)),
+                         const char *password __attribute__((unused)),
+                         const char *database, const sasl_utils_t *utils)
+{
+    int rc;
+    sqlite *db;
+    char *zErrMsg = NULL;
+
+    db = sqlite_open(database, 0, &zErrMsg);
+    if (db == NULL) {
+       utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg);
+       sqlite_freemem (zErrMsg);
+       return NULL;
+    }
+
+    rc = sqlite_exec(db, "PRAGMA empty_result_callbacks = ON", NULL, NULL, &zErrMsg);
+    if (rc != SQLITE_OK) {
+       utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg);
+       sqlite_freemem (zErrMsg);
+       sqlite_close(db);
+       return NULL;
+    }
+
+    return (void*)db;
+}
+
+static int _sqlite_escape_str(char *to, const char *from)
+{
+    char s;
+
+    while ( (s = *from++) != '\0' ) {
+       if (s == '\'' || s == '\\') {
+           *to++ = '\\';
+       }
+       *to++ = s;
+    }
+    *to = '\0';
+
+    return 0;
+}
+
+static int sqlite_my_callback(void *pArg, int argc __attribute__((unused)),
+                             char **argv,
+                             char **columnNames __attribute__((unused)))
+{
+    char **result = (char**)pArg;
+
+    if (argv == NULL) {
+       *result = NULL;                         /* no record */
+    } else if (argv[0] == NULL) {
+       *result = strdup(SQL_NULL_VALUE);       /* NULL IS SQL_NULL_VALUE */
+    } else {
+       *result = strdup(argv[0]);
+    }
+
+    return /*ABORT*/1;
+}
+
+static int _sqlite_exec(void *db, const char *cmd, char *value, size_t size,
+                       size_t *value_len, const sasl_utils_t *utils)
+{
+    int rc;
+    char *result = NULL;
+    char *zErrMsg = NULL;
+
+    rc = sqlite_exec((sqlite*)db, cmd, sqlite_my_callback, (void*)&result, &zErrMsg);
+    if (rc != SQLITE_OK && rc != SQLITE_ABORT) {
+       utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ", zErrMsg);
+       sqlite_freemem (zErrMsg);
+       return -1;
+    }
+
+    if (rc == SQLITE_OK) {
+       /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */
+       return 0;
+    }
+
+    if (result == NULL) {
+       /* umm nothing found */
+       utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found");
+       return -1;
+    }
+
+    /* XXX: Duplication cannot be found by this method. */
+
+    /* now get the result set value and value_len */
+    /* we only fetch one because we don't care about the rest */
+    if (value) {
+       strncpy(value, result, size - 2);
+       value[size - 1] = '\0';
+       if (value_len) {
+           *value_len = strlen(value);
+       }
+    }
+
+    /* free result */
+    free(result);
+    return 0;
+}
+
+static int _sqlite_begin_txn(void *db, const sasl_utils_t *utils)
+{
+    return _sqlite_exec(db, "BEGIN TRANSACTION", NULL, 0, NULL, utils);
+}
+
+static int _sqlite_commit_txn(void *db, const sasl_utils_t *utils)
+{
+    return _sqlite_exec(db, "COMMIT TRANSACTION", NULL, 0, NULL, utils);
+}
+
+static int _sqlite_rollback_txn(void *db, const sasl_utils_t *utils)
+{
+    return _sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, 0, NULL, utils);
+}
+
+static void _sqlite_close(void *db)
+{
+    sqlite_close((sqlite*)db);
+}
+#endif /* HAVE_SQLITE */
+
+static const sql_engine_t sql_engines[] = {
+#ifdef HAVE_MYSQL
+    { "mysql", &_mysql_open, &_mysql_escape_str,
+      &_mysql_begin_txn, &_mysql_commit_txn, &_mysql_rollback_txn,
+      &_mysql_exec, &_mysql_close },
+#endif /* HAVE_MYSQL */
+#ifdef HAVE_PGSQL
+    { "pgsql", &_pgsql_open, &_pgsql_escape_str,
+      &_pgsql_begin_txn, &_pgsql_commit_txn, &_pgsql_rollback_txn,
+      &_pgsql_exec, &_pgsql_close },
+#endif
+#ifdef HAVE_SQLITE
+    { "sqlite", &_sqlite_open, &_sqlite_escape_str,
+      &_sqlite_begin_txn, &_sqlite_commit_txn, &_sqlite_rollback_txn,
+      &_sqlite_exec, &_sqlite_close },
+#endif
+    { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+/*
+**  Sql_create_statement
+**   uses statement line and allocate memory to replace
+**  Parts with the strings provided.
+**   %<char> =  no change
+**   %% = %
+**   %u = user
+**   %p = prop
+**   %r = realm
+**   %v = value of prop
+**  e.g select %p from auth where user = %p and domain = %r;
+**  Note: calling function must free memory.
+**
+*/
+
+static char *sql_create_statement(const char *statement, const char *prop,
+                                 const char *user, const char *realm, 
+                                 const char *value,  
+                                 const sasl_utils_t *utils)
+{
+    const char *ptr, *line_ptr;
+    char *buf, *buf_ptr;
+    int filtersize;
+    int ulen, plen, rlen, vlen;
+    int numpercents=0;
+    int biggest;
+    size_t i;
+    
+    /* calculate memory needed for creating the complete query string. */
+    ulen = strlen(user);
+    rlen = strlen(realm);
+    plen = strlen(prop);
+    vlen = sql_len(value);
+    
+    /* what if we have multiple %foo occurrences in the input query? */
+    for (i = 0; i < strlen(statement); i++) {
+       if (statement[i] == '%') {
+           numpercents++;
+       }
+    }
+    
+    /* find the biggest of ulen, rlen, plen, vlen */
+    biggest = sql_max(sql_max(ulen, rlen), sql_max(plen, vlen));
+    
+    /* plus one for the semicolon...and don't forget the trailing 0x0 */
+    filtersize = strlen(statement) + 1 + (numpercents*biggest)+1;
+    
+    /* ok, now try to allocate a chunk of that size */
+    buf = (char *) utils->malloc(filtersize);
+    
+    if (!buf) {
+       MEMERROR(utils);
+       return NULL;
+    }
+    
+    buf_ptr = buf;
+    line_ptr = statement;
+    
+    /* replace the strings */
+    while ( (ptr = strchr(line_ptr, '%')) ) {
+       /* copy up to but not including the next % */
+       memcpy(buf_ptr, line_ptr, ptr - line_ptr); 
+       buf_ptr += ptr - line_ptr;
+       ptr++;
+       switch (ptr[0]) {
+       case '%':
+           buf_ptr[0] = '%';
+           buf_ptr++;
+           break;
+       case 'u':
+           memcpy(buf_ptr, user, ulen);
+           buf_ptr += ulen;
+           break;
+       case 'r':
+           memcpy(buf_ptr, realm, rlen);
+           buf_ptr += rlen;
+           break;
+       case 'p':
+           memcpy(buf_ptr, prop, plen);
+           buf_ptr += plen;
+           break;
+       case 'v':
+           if (value != NULL) {
+               memcpy(buf_ptr, value, vlen);
+               buf_ptr += vlen;
+           }
+           else {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "'%%v' shouldn't be in a SELECT or DELETE");
+           }
+           break;
+       default:
+           buf_ptr[0] = '%';
+           buf_ptr[1] = ptr[0];
+           buf_ptr += 2;
+           break;
+       }
+       ptr++;
+       line_ptr = ptr;
+    }
+    
+    memcpy(buf_ptr, line_ptr, strlen(line_ptr)+1);
+    /* Make sure the current portion of the statement ends with a semicolon */
+    if (buf_ptr[strlen(buf_ptr-1)] != ';') {
+       strcat(buf_ptr, ";");
+    }
+
+    return (buf);
+}
+
+/* sql_get_settings
+ *
+ * Get the auxprop settings and put them in the global context array
+*/
+static void sql_get_settings(const sasl_utils_t *utils, void *glob_context)
+{
+    sql_settings_t *settings;
+    int r;
+    const char *usessl, *engine_name;
+    const sql_engine_t *e;
+    
+    settings = (sql_settings_t *) glob_context;
+    
+    r = utils->getopt(utils->getopt_context,"SQL", "sql_engine",
+                     &engine_name, NULL);
+    if (r || !engine_name) {
+       engine_name = "mysql";
+    }
+    
+    /* find the correct engine */
+    e = sql_engines;
+    while (e->name) {
+       if (!strcasecmp(engine_name, e->name)) break;
+       e++;
+    }
+
+    if (!e->name) {
+       utils->log(NULL, SASL_LOG_ERR, "SQL engine '%s' not supported",
+                  engine_name);
+    }
+
+    settings->sql_engine = e;
+
+    r = utils->getopt(utils->getopt_context,"SQL","sql_user",
+                     &settings->sql_user, NULL);
+    if ( r || !settings->sql_user ) {
+       settings->sql_user = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context,"SQL", "sql_passwd",
+                     &settings->sql_passwd, NULL);
+    if (r || !settings->sql_passwd ) {
+       settings->sql_passwd = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context,"SQL", "sql_hostnames",
+                     &settings->sql_hostnames, NULL);
+    if (r || !settings->sql_hostnames ) {
+       settings->sql_hostnames = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context,"SQL", "sql_database",
+                     &settings->sql_database, NULL);
+    if (r || !settings->sql_database ) {
+       settings->sql_database = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context,"SQL", "sql_select",
+                     &settings->sql_select, NULL);
+    if (r || !settings->sql_select ) {
+       /* backwards compatibility */
+       r = utils->getopt(utils->getopt_context,"SQL", "sql_statement",
+                         &settings->sql_select, NULL);
+       if (r || !settings->sql_select) {
+           settings->sql_select = SQL_BLANK_STRING;
+       }
+    }
+
+    r = utils->getopt(utils->getopt_context, "SQL", "sql_insert",
+                     &settings->sql_insert, NULL);
+    if (r || !settings->sql_insert) {
+       settings->sql_insert = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context, "SQL", "sql_update",
+                     &settings->sql_update, NULL);
+    if (r || !settings->sql_update) {
+       settings->sql_update = SQL_BLANK_STRING;
+    }
+
+    r = utils->getopt(utils->getopt_context, "SQL", "sql_usessl",
+                 &usessl, NULL);
+    if (r || !usessl) usessl = "no";
+
+    if (*usessl == '1' || *usessl == 'y'  || *usessl == 't' ||
+       (*usessl == 'o' && usessl[1] == 'n')) {
+       settings->sql_usessl = 1;
+    } else {
+       settings->sql_usessl = 0;
+    }
+}
+
+static void *sql_connect(sql_settings_t *settings, const sasl_utils_t *utils)
+{
+    void *conn = NULL;
+    char *db_host_ptr = NULL;
+    char *db_host = NULL;
+    char *cur_host, *cur_port;
+
+    /* loop around hostnames till we get a connection 
+     * it should probably save the connection but for 
+     * now we will just disconnect everytime
+     */
+    utils->log(NULL, SASL_LOG_DEBUG,
+              "sql plugin try and connect to a host\n");
+    
+    /* create a working version of the hostnames */
+    _plug_strdup(utils, settings->sql_hostnames, &db_host_ptr, NULL);
+    db_host = db_host_ptr;
+    cur_host = db_host;
+    while (cur_host != NULL) {
+       db_host = strchr(db_host,',');
+       if (db_host != NULL) {  
+           db_host[0] = '\0';
+
+           /* loop till we find some text */
+           while (!isalnum(db_host[0])) db_host++;
+       }
+       
+       utils->log(NULL, SASL_LOG_DEBUG,
+                  "sql plugin trying to open db '%s' on host '%s'%s\n",
+                  settings->sql_database, cur_host,
+                  settings->sql_usessl ? " using SSL" : "");
+       
+       /* set the optional port */
+       if ((cur_port = strchr(cur_host, ':'))) *cur_port++ = '\0';
+       
+       conn = settings->sql_engine->sql_open(cur_host, cur_port,
+                                             settings->sql_usessl,
+                                             settings->sql_user,
+                                             settings->sql_passwd,
+                                             settings->sql_database,
+                                             utils);
+       if (conn) break;
+       
+       utils->log(NULL, SASL_LOG_ERR,
+                  "sql plugin could not connect to host %s", cur_host);
+       
+       cur_host = db_host;
+    }
+
+    if (db_host_ptr) utils->free(db_host_ptr);
+
+    return conn;
+}
+
+static void sql_auxprop_lookup(void *glob_context,
+                              sasl_server_params_t *sparams,
+                              unsigned flags,
+                              const char *user,
+                              unsigned ulen) 
+{
+    char *userid = NULL;
+    /* realm could be used for something clever */
+    char *realm = NULL;
+    const char *user_realm = NULL;
+    const struct propval *to_fetch, *cur;
+    char value[8192];
+    size_t value_len;
+    
+    char *user_buf;
+    char *query = NULL;
+    char *escap_userid = NULL;
+    char *escap_realm = NULL;
+    sql_settings_t *settings;
+    void *conn = NULL;
+    int do_txn = 0;
+    
+    if (!glob_context || !sparams || !user) return;
+    
+    /* setup the settings */
+    settings = (sql_settings_t *) glob_context;
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "sql plugin Parse the username %s\n", user);
+    
+    user_buf = sparams->utils->malloc(ulen + 1);
+    if (!user_buf) goto done;
+    
+    memcpy(user_buf, user, ulen);
+    user_buf[ulen] = '\0';
+    
+    if(sparams->user_realm) {
+       user_realm = sparams->user_realm;
+    } else {
+       user_realm = sparams->serverFQDN;
+    }
+    
+    if (_plug_parseuser(sparams->utils, &userid, &realm, user_realm,
+                       sparams->serverFQDN, user_buf) != SASL_OK )
+       goto done;
+    
+    /* just need to escape userid and realm now */
+    /* allocate some memory */
+    escap_userid = (char *)sparams->utils->malloc(strlen(userid)*2+1);
+    escap_realm = (char *)sparams->utils->malloc(strlen(realm)*2+1);
+    
+    if (!escap_userid || !escap_realm) {
+       MEMERROR(sparams->utils);
+       goto done;
+    }
+    
+    /*************************************/
+    
+    /* find out what we need to get */
+    /* this corrupts const char *user */
+    to_fetch = sparams->utils->prop_get(sparams->propctx);
+    if (!to_fetch) goto done;
+
+    conn = sql_connect(settings, sparams->utils);
+    if (!conn) {
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "sql plugin couldn't connect to any host\n");
+       
+       goto done;
+    }
+    
+    /* escape out */
+    settings->sql_engine->sql_escape_str(escap_userid, userid);
+    settings->sql_engine->sql_escape_str(escap_realm, realm);
+    
+    for (cur = to_fetch; cur->name; cur++) {
+       char *realname = (char *) cur->name;
+
+       /* Only look up properties that apply to this lookup! */
+       if (cur->name[0] == '*'
+           && (flags & SASL_AUXPROP_AUTHZID))
+           continue;
+       if (!(flags & SASL_AUXPROP_AUTHZID)) {
+           if(cur->name[0] != '*')
+               continue;
+           else
+               realname = (char*)cur->name + 1;
+       }
+       
+       /* If it's there already, we want to see if it needs to be
+        * overridden */
+       if (cur->values && !(flags & SASL_AUXPROP_OVERRIDE))
+           continue;
+       else if (cur->values)
+           sparams->utils->prop_erase(sparams->propctx, cur->name);
+
+       if (!do_txn) {
+           do_txn = 1;
+           sparams->utils->log(NULL, SASL_LOG_DEBUG, "begin transaction");
+           if (settings->sql_engine->sql_begin_txn(conn, sparams->utils)) {
+               sparams->utils->log(NULL, SASL_LOG_ERR, 
+                                   "Unable to begin transaction\n");
+           }
+       }
+    
+       sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                           "sql plugin create statement from %s %s %s\n",
+                           realname, escap_userid, escap_realm);
+       
+       /* create a statement that we will use */
+       query = sql_create_statement(settings->sql_select,
+                                    realname,escap_userid,
+                                    escap_realm, NULL,
+                                    sparams->utils);
+       
+       sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                           "sql plugin doing query %s\n", query);
+       
+       /* run the query */
+       if (!settings->sql_engine->sql_exec(conn, query, value, sizeof(value),
+                                           &value_len, sparams->utils)) {
+           sparams->utils->prop_set(sparams->propctx, cur->name,
+                                    value, value_len);
+       }
+       
+       sparams->utils->free(query);
+    }
+
+    if (do_txn) {
+       sparams->utils->log(NULL, SASL_LOG_DEBUG, "commit transaction");
+       if (settings->sql_engine->sql_commit_txn(conn, sparams->utils)) {
+           sparams->utils->log(NULL, SASL_LOG_ERR, 
+                               "Unable to commit transaction\n");
+       }
+    }
+    
+  done:
+    if (escap_userid) sparams->utils->free(escap_userid);
+    if (escap_realm) sparams->utils->free(escap_realm);
+    if (conn) settings->sql_engine->sql_close(conn);
+    if (userid) sparams->utils->free(userid);
+    if (realm) sparams->utils->free(realm);
+    if (user_buf) sparams->utils->free(user_buf);
+}
+
+static int sql_auxprop_store(void *glob_context,
+                            sasl_server_params_t *sparams,
+                            struct propctx *ctx,
+                            const char *user,
+                            unsigned ulen) 
+{
+    char *userid = NULL;
+    char *realm = NULL;
+    const char *user_realm = NULL;
+    int ret = SASL_FAIL;
+    const struct propval *to_store, *cur;
+    
+    char *user_buf;
+    char *statement = NULL;
+    char *escap_userid = NULL;
+    char *escap_realm = NULL;
+    const char *cmd;
+    
+    sql_settings_t *settings;
+    void *conn = NULL;
+    
+    settings = (sql_settings_t *) glob_context; 
+
+    /* just checking if we are enabled */
+    if (!ctx &&
+       sql_exists(settings->sql_insert) &&
+       sql_exists(settings->sql_update)) return SASL_OK;
+    
+    /* make sure our input is okay */
+    if (!glob_context || !sparams || !user) return SASL_BADPARAM;
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "sql plugin Parse the username %s\n", user);
+    
+    user_buf = sparams->utils->malloc(ulen + 1);
+    if (!user_buf) {
+       ret = SASL_NOMEM;
+       goto done;
+    }
+    
+    memcpy(user_buf, user, ulen);
+    user_buf[ulen] = '\0';
+    
+    if (sparams->user_realm) {
+       user_realm = sparams->user_realm;
+    }
+    else {
+       user_realm = sparams->serverFQDN;
+    }
+    
+    ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm,
+                         sparams->serverFQDN, user_buf);
+    if (ret != SASL_OK)        goto done;
+    
+    /* just need to escape userid and realm now */
+    /* allocate some memory */
+    
+    escap_userid = (char *) sparams->utils->malloc(strlen(userid)*2+1);
+    escap_realm = (char *) sparams->utils->malloc(strlen(realm)*2+1);
+    
+    if (!escap_userid || !escap_realm) {
+       MEMERROR(sparams->utils);
+       goto done;
+    }
+    
+    to_store = sparams->utils->prop_get(ctx);
+    
+    if (!to_store) {
+       ret = SASL_BADPARAM;
+       goto done;
+    }
+
+    conn = sql_connect(settings, sparams->utils);
+    if (!conn) {
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "sql plugin couldn't connect to any host\n");
+       goto done;
+    }
+    
+    settings->sql_engine->sql_escape_str(escap_userid, userid);
+    settings->sql_engine->sql_escape_str(escap_realm, realm);
+    
+    if (settings->sql_engine->sql_begin_txn(conn, sparams->utils)) {
+       sparams->utils->log(NULL, SASL_LOG_ERR, 
+                           "Unable to begin transaction\n");
+    }
+    for (cur = to_store; ret == SASL_OK && cur->name; cur++) {
+       /* determine which command we need */
+       /* see if we already have a row for this user */
+       statement = sql_create_statement(settings->sql_select,
+                                        SQL_WILDCARD, escap_userid,
+                                        escap_realm, NULL,
+                                        sparams->utils);
+       if (!settings->sql_engine->sql_exec(conn, statement, NULL, 0, NULL,
+                                           sparams->utils)) {
+           /* already have a row => UPDATE */
+           cmd = settings->sql_update;
+       } else {
+           /* new row => INSERT */
+           cmd = settings->sql_insert;
+       }
+       sparams->utils->free(statement);
+
+       /* create a statement that we will use */
+       statement = sql_create_statement(cmd, cur->name, escap_userid,
+                                        escap_realm,
+                                        cur->values && cur->values[0] ?
+                                        cur->values[0] : SQL_NULL_VALUE,
+                                        sparams->utils);
+       
+       {
+           char *log_statement =
+               sql_create_statement(cmd, cur->name,
+                                    escap_userid,
+                                    escap_realm,
+                                    cur->values && cur->values[0] ?
+                                    "<omitted>" : SQL_NULL_VALUE,
+                                    sparams->utils);
+           sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                               "sql plugin doing statement %s\n",
+                               log_statement);
+           sparams->utils->free(log_statement);
+       }
+       
+       /* run the statement */
+       if (settings->sql_engine->sql_exec(conn, statement, NULL, 0, NULL,
+                                          sparams->utils)) {
+           ret = SASL_FAIL;
+       }
+       
+       sparams->utils->free(statement);
+    }
+    if (ret != SASL_OK) {
+       sparams->utils->log(NULL, SASL_LOG_ERR,
+                           "Failed to store auxprop; aborting transaction\n");
+       if (settings->sql_engine->sql_rollback_txn(conn, sparams->utils)) {
+           sparams->utils->log(NULL, SASL_LOG_ERR, 
+                               "Unable to rollback transaction\n");
+       }
+    }
+    else if (settings->sql_engine->sql_commit_txn(conn, sparams->utils)) {
+       sparams->utils->log(NULL, SASL_LOG_ERR, 
+                           "Unable to commit transaction\n");
+    }
+    
+  done:
+    if (escap_userid) sparams->utils->free(escap_userid);
+    if (escap_realm) sparams->utils->free(escap_realm);
+    if (conn) settings->sql_engine->sql_close(conn);
+    if (userid) sparams->utils->free(userid);
+    if (realm) sparams->utils->free(realm);
+    if (user_buf) sparams->utils->free(user_buf);
+    
+    return ret;
+    
+    /* do a little dance */
+}
+
+
+static void sql_auxprop_free(void *glob_context, const sasl_utils_t *utils)
+{
+    sql_settings_t *settings;
+    
+    settings = (sql_settings_t *)glob_context;
+    
+    if (!settings) return;
+    
+    utils->log(NULL, SASL_LOG_DEBUG, "sql freeing memory\n");
+    
+    utils->free(settings);
+}
+
+static sasl_auxprop_plug_t sql_auxprop_plugin = {
+    0,                 /* Features */
+    0,                 /* spare */
+    NULL,              /* glob_context */
+    sql_auxprop_free,  /* auxprop_free */
+    sql_auxprop_lookup,        /* auxprop_lookup */
+    "sql",             /* name */
+    sql_auxprop_store  /* auxprop_store */
+};
+
+int sql_auxprop_plug_init(const sasl_utils_t *utils,
+                         int max_version,
+                         int *out_version,
+                         sasl_auxprop_plug_t **plug,
+                         const char *plugname __attribute__((unused))) 
+{
+    sql_settings_t *settings;
+    
+    if (!out_version || !plug) return SASL_BADPARAM;
+    
+    if (max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS;
+    *out_version = SASL_AUXPROP_PLUG_VERSION;
+    
+    *plug = &sql_auxprop_plugin;
+    
+    settings = (sql_settings_t *) utils->malloc(sizeof(sql_settings_t));
+    
+    if (!settings) {
+       MEMERROR(utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(settings, 0, sizeof(sql_settings_t));
+    sql_get_settings(utils, settings);
+    
+    if (!settings->sql_engine->name) return SASL_NOMECH;
+
+    if (!sql_exists(settings->sql_select)) {
+       utils->log(NULL, SASL_LOG_ERR, "sql_select option missing");
+       utils->free(settings);  
+       return SASL_NOMECH;
+    }
+
+    utils->log(NULL, SASL_LOG_DEBUG,
+              "sql auxprop plugin using %s engine\n",
+              settings->sql_engine->name);
+    
+    sql_auxprop_plugin.glob_context = settings;
+    
+    return SASL_OK;
+}
diff --git a/plugins/sql_init.c b/plugins/sql_init.c
new file mode 100644 (file)
index 0000000..ffbe2e8
--- /dev/null
@@ -0,0 +1,38 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_AUXPROP_PLUG_INIT( sql )
+
diff --git a/plugins/srp.c b/plugins/srp.c
new file mode 100644 (file)
index 0000000..2f72d7f
--- /dev/null
@@ -0,0 +1,3179 @@
+/* SRP SASL plugin
+ * Ken Murchison
+ * Tim Martin  3/17/00
+ * $Id: srp.c,v 1.58 2006/04/24 19:21:44 mel 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.
+ */
+
+/*
+ * Notes:
+ *
+ * - The authentication exchanges *should* be correct (per draft -08)
+ *   but we won't know until we do some interop testing.
+ *
+ * - The security layers don't conform to draft -08:
+ *    o  We don't use eos() and os() elements in an SRP buffer, we send
+ *      just the bare octets.
+ *    o  We don't yet use the PRNG() and KDF() primatives described in
+ *       section 5.1.
+ *
+ * - Are we using cIV and sIV correctly for encrypt/decrypt?
+ *
+ * - We don't implement fast reauth.
+ */
+
+#include <config.h>
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#ifndef UINT32_MAX
+#define UINT32_MAX 4294967295U
+#endif
+
+#if UINT_MAX == UINT32_MAX
+typedef unsigned int uint32;
+#elif ULONG_MAX == UINT32_MAX
+typedef unsigned long uint32;
+#elif USHRT_MAX == UINT32_MAX
+typedef unsigned short uint32;
+#else
+#error dont know what to use for uint32
+#endif
+
+/* for big number support */
+#include <openssl/bn.h>
+
+/* for digest and cipher support */
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/md5.h>
+
+#include <sasl.h>
+#define MD5_H  /* suppress internal MD5 */
+#include <saslplug.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_srp_plugin_decl.h>
+#endif 
+
+/*****************************  Common Section  *****************************/
+
+static const char plugin_id[] = "$Id: srp.c,v 1.58 2006/04/24 19:21:44 mel Exp $";
+
+/* Size limit of cipher block size */
+#define SRP_MAXBLOCKSIZE 16
+/* Size limit of SRP buffer */
+#define SRP_MAXBUFFERSIZE 2147483643
+
+#define DEFAULT_MDA            "SHA-1"
+
+#define OPTION_MDA             "mda="
+#define OPTION_REPLAY_DETECTION        "replay_detection"
+#define OPTION_INTEGRITY       "integrity="
+#define OPTION_CONFIDENTIALITY "confidentiality="
+#define OPTION_MANDATORY       "mandatory="
+#define OPTION_MAXBUFFERSIZE   "maxbuffersize="
+
+/* Table of recommended Modulus (base 16) and Generator pairs */
+struct Ng {
+    char *N;
+    unsigned long g;
+} Ng_tab[] = {
+    /* [264 bits] */
+    { "115B8B692E0E045692CF280B436735C77A5A9E8A9E7ED56C965F87DB5B2A2ECE3",
+      2
+    },
+    /* [384 bits] */
+    { "8025363296FB943FCE54BE717E0E2958A02A9672EF561953B2BAA3BAACC3ED5754EB764C7AB7184578C57D5949CCB41B",
+      2
+    },
+    /* [512 bits] */
+    { "D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43",
+      2
+    },
+    /* [640 bits] */
+    { "C94D67EB5B1A2346E8AB422FC6A0EDAEDA8C7F894C9EEEC42F9ED250FD7F0046E5AF2CF73D6B2FA26BB08033DA4DE322E144E7A8E9B12A0E4637F6371F34A2071C4B3836CBEEAB15034460FAA7ADF483",
+      2
+    },
+    /* [768 bits] */
+    { "B344C7C4F8C495031BB4E04FF8F84EE95008163940B9558276744D91F7CC9F402653BE7147F00F576B93754BCDDF71B636F2099E6FFF90E79575F3D0DE694AFF737D9BE9713CEF8D837ADA6380B1093E94B6A529A8C6C2BE33E0867C60C3262B",
+      2
+    },
+    /* [1024 bits] */
+    { "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3",
+      2
+    },
+    /* [1280 bits] */
+    { "D77946826E811914B39401D56A0A7843A8E7575D738C672A090AB1187D690DC43872FC06A7B6A43F3B95BEAEC7DF04B9D242EBDC481111283216CE816E004B786C5FCE856780D41837D95AD787A50BBE90BD3A9C98AC0F5FC0DE744B1CDE1891690894BC1F65E00DE15B4B2AA6D87100C9ECC2527E45EB849DEB14BB2049B163EA04187FD27C1BD9C7958CD40CE7067A9C024F9B7C5A0B4F5003686161F0605B",
+      2
+    },
+    /* [1536 bits] */
+    { "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB",
+      2
+    },
+    /* [2048 bits] */
+    { "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73",
+      2
+    }
+};
+
+#define NUM_Ng (sizeof(Ng_tab) / sizeof(struct Ng))
+
+
+typedef struct layer_option_s {
+    const char *name;          /* name used in option strings */
+    unsigned enabled;          /* enabled?  determined at run-time */
+    unsigned bit;              /* unique bit in bitmask */
+    sasl_ssf_t ssf;            /* ssf of layer */
+    const char *evp_name;      /* name used for lookup in EVP table */
+} layer_option_t;
+
+static layer_option_t digest_options[] = {
+    { "SHA-1",         0, (1<<0), 1,   "sha1" },
+    { "RIPEMD-160",    0, (1<<1), 1,   "rmd160" },
+    { "MD5",           0, (1<<2), 1,   "md5" },
+    { NULL,            0,      0, 0,   NULL }
+};
+static layer_option_t *default_digest = &digest_options[0];
+static layer_option_t *server_mda = NULL;
+
+static layer_option_t cipher_options[] = {
+    { "DES",           0, (1<<0), 56,  "des-ofb" },
+    { "3DES",          0, (1<<1), 112, "des-ede-ofb" },
+    { "AES",           0, (1<<2), 128, "aes-128-ofb" },
+    { "Blowfish",      0, (1<<3), 128, "bf-ofb" },
+    { "CAST-128",      0, (1<<4), 128, "cast5-ofb" },
+    { "IDEA",          0, (1<<5), 128, "idea-ofb" },
+    { NULL,            0,      0, 0,   NULL}
+};
+/* XXX Hack until OpenSSL 0.9.7 */
+#if OPENSSL_VERSION_NUMBER < 0x00907000L
+static layer_option_t *default_cipher = &cipher_options[0];
+#else
+static layer_option_t *default_cipher = &cipher_options[2];
+#endif
+
+
+enum {
+    BIT_REPLAY_DETECTION=      (1<<0),
+    BIT_INTEGRITY=             (1<<1),
+    BIT_CONFIDENTIALITY=       (1<<2)
+};
+
+typedef struct srp_options_s {
+    unsigned mda;              /* bitmask of MDAs */
+    unsigned replay_detection; /* replay detection on/off flag */
+    unsigned integrity;                /* bitmask of integrity layers */
+    unsigned confidentiality;  /* bitmask of confidentiality layers */
+    unsigned mandatory;                /* bitmask of mandatory layers */
+    unsigned long maxbufsize;  /* max # bytes processed by security layer */
+} srp_options_t;
+
+/* The main SRP context */
+typedef struct context {
+    int state;
+    
+    BIGNUM N;                  /* safe prime modulus */
+    BIGNUM g;                  /* generator */
+    
+    BIGNUM v;                  /* password verifier */
+    
+    BIGNUM b;                  /* server private key */
+    BIGNUM B;                  /* server public key */
+    
+    BIGNUM a;                  /* client private key */
+    BIGNUM A;                  /* client public key */
+    
+    char K[EVP_MAX_MD_SIZE];   /* shared context key */
+    int Klen;
+    
+    char M1[EVP_MAX_MD_SIZE];  /* client evidence */
+    int M1len;
+    
+    char *authid;              /* authentication id (server) */
+    char *userid;              /* authorization id (server) */
+    sasl_secret_t *password;   /* user secret (client) */
+    unsigned int free_password; /* set if we need to free password */
+    
+    char *client_options;
+    char *server_options;
+    
+    srp_options_t client_opts; /* cache between client steps */
+    char cIV[SRP_MAXBLOCKSIZE];        /* cache between client steps */
+    
+    char *salt;                        /* password salt */
+    int saltlen;
+    
+    const EVP_MD *md;          /* underlying MDA */
+    
+    /* copy of utils from the params structures */
+    const sasl_utils_t *utils;
+    
+    /* per-step mem management */
+    char *out_buf;
+    unsigned out_buf_len;
+    
+    /* Layer foo */
+    unsigned layer;            /* bitmask of enabled layers */
+    const EVP_MD *hmac_md;     /* HMAC for integrity */
+    HMAC_CTX hmac_send_ctx;
+    HMAC_CTX hmac_recv_ctx;
+
+    const EVP_CIPHER *cipher;  /* cipher for confidentiality */
+    EVP_CIPHER_CTX cipher_enc_ctx;
+    EVP_CIPHER_CTX cipher_dec_ctx;
+    
+    /* replay detection sequence numbers */
+    int seqnum_out;
+    int seqnum_in;
+    
+    /* for encoding/decoding mem management */
+    char           *encode_buf, *decode_buf, *decode_pkt_buf;
+    unsigned       encode_buf_len, decode_buf_len, decode_pkt_buf_len;
+    
+    /* layers buffering */
+    decode_context_t decode_context;
+    
+} context_t;
+
+static int srp_encode(void *context,
+                     const struct iovec *invec,
+                     unsigned numiov,
+                     const char **output,
+                     unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    unsigned i;
+    char *input;
+    unsigned long inputlen, tmpnum;
+    int ret;
+    
+    if (!context || !invec || !numiov || !output || !outputlen) {
+       PARAMERROR( text->utils );
+       return SASL_BADPARAM;
+    }
+
+    /* calculate total size of input */
+    for (i = 0, inputlen = 0; i < numiov; i++)
+       inputlen += invec[i].iov_len;
+
+    /* allocate a buffer for the output */
+    ret = _plug_buf_alloc(text->utils, &text->encode_buf,
+                         &text->encode_buf_len,
+                         4 +                   /* for length */
+                         inputlen +            /* for content */
+                         SRP_MAXBLOCKSIZE +    /* for PKCS padding */
+                         EVP_MAX_MD_SIZE);     /* for HMAC */
+    if (ret != SASL_OK) return ret;
+
+    *outputlen = 4; /* length */
+
+    /* operate on each iovec */
+    for (i = 0; i < numiov; i++) {
+       input = invec[i].iov_base;
+       inputlen = invec[i].iov_len;
+    
+       if (text->layer & BIT_CONFIDENTIALITY) {
+           unsigned enclen;
+
+           /* encrypt the data into the output buffer */
+           EVP_EncryptUpdate(&text->cipher_enc_ctx,
+                             text->encode_buf + *outputlen, &enclen,
+                             input, inputlen);
+           *outputlen += enclen;
+
+           /* switch the input to the encrypted data */
+           input = text->encode_buf + 4;
+           inputlen = *outputlen - 4;
+       }
+       else {
+           /* copy the raw input to the output */
+           memcpy(text->encode_buf + *outputlen, input, inputlen);
+           *outputlen += inputlen;
+       }
+    }
+    
+    if (text->layer & BIT_CONFIDENTIALITY) {
+       unsigned enclen;
+
+       /* encrypt the last block of data into the output buffer */
+       EVP_EncryptFinal(&text->cipher_enc_ctx,
+                        text->encode_buf + *outputlen, &enclen);
+       *outputlen += enclen;
+    }
+
+    if (text->layer & BIT_INTEGRITY) {
+       unsigned hashlen;
+
+       /* hash the content */
+       HMAC_Update(&text->hmac_send_ctx, text->encode_buf+4, *outputlen-4);
+       
+       if (text->layer & BIT_REPLAY_DETECTION) {
+           /* hash the sequence number */
+           tmpnum = htonl(text->seqnum_out);
+           HMAC_Update(&text->hmac_send_ctx, (char *) &tmpnum, 4);
+           
+           text->seqnum_out++;
+       }
+
+       /* append the HMAC into the output buffer */
+       HMAC_Final(&text->hmac_send_ctx, text->encode_buf + *outputlen,
+                  &hashlen);
+       *outputlen += hashlen;
+    }
+
+    /* prepend the length of the output */
+    tmpnum = *outputlen - 4;
+    tmpnum = htonl(tmpnum);
+    memcpy(text->encode_buf, &tmpnum, 4);
+
+    *output = text->encode_buf;
+    
+    return SASL_OK;
+}
+
+/* decode a single SRP packet */
+static int srp_decode_packet(void *context,
+                            const char *input,
+                            unsigned inputlen,
+                            char **output,
+                            unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+
+    if (text->layer & BIT_INTEGRITY) {
+       const char *hash;
+       char myhash[EVP_MAX_MD_SIZE];
+       unsigned hashlen, myhashlen, i;
+       unsigned long tmpnum;
+
+       hashlen = EVP_MD_size(text->hmac_md);
+
+       if (inputlen < hashlen) {
+           text->utils->seterror(text->utils->conn, 0,
+                                 "SRP input is smaller "
+                                 "than hash length: %d vs %d\n",
+                                 inputlen, hashlen);
+           return SASL_BADPROT;
+       }
+
+       inputlen -= hashlen;
+       hash = input + inputlen;
+
+       /* create our own hash from the input */
+       HMAC_Update(&text->hmac_recv_ctx, input, inputlen);
+           
+       if (text->layer & BIT_REPLAY_DETECTION) {
+           /* hash the sequence number */
+           tmpnum = htonl(text->seqnum_in);
+           HMAC_Update(&text->hmac_recv_ctx, (char *) &tmpnum, 4);
+               
+           text->seqnum_in++;
+       }
+           
+       HMAC_Final(&text->hmac_recv_ctx, myhash, &myhashlen);
+
+       /* compare hashes */
+       for (i = 0; i < hashlen; i++) {
+           if ((myhashlen != hashlen) || (myhash[i] != hash[i])) {
+               SETERROR(text->utils, "Hash is incorrect\n");
+               return SASL_BADMAC;
+           }
+       }
+    }
+       
+    ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf),
+                         &(text->decode_pkt_buf_len),
+                         inputlen);
+    if (ret != SASL_OK) return ret;
+       
+    if (text->layer & BIT_CONFIDENTIALITY) {
+       unsigned declen;
+
+       /* decrypt the data into the output buffer */
+       EVP_DecryptUpdate(&text->cipher_dec_ctx,
+                         text->decode_pkt_buf, &declen,
+                         (char *) input, inputlen);
+       *outputlen = declen;
+           
+       EVP_DecryptFinal(&text->cipher_dec_ctx,
+                        text->decode_pkt_buf + declen, &declen);
+       *outputlen += declen;
+    } else {
+       /* copy the raw input to the output */
+       memcpy(text->decode_pkt_buf, input, inputlen);
+       *outputlen = inputlen;
+    }
+
+    *output = text->decode_pkt_buf;
+    
+    return SASL_OK;
+}
+
+/* decode and concatenate multiple SRP packets */
+static int srp_decode(void *context,
+                     const char *input, unsigned inputlen,
+                     const char **output, unsigned *outputlen)
+{
+    context_t *text = (context_t *) context;
+    int ret;
+    
+    ret = _plug_decode(&text->decode_context, input, inputlen,
+                      &text->decode_buf, &text->decode_buf_len, outputlen,
+                      srp_decode_packet, text);
+    
+    *output = text->decode_buf;
+    
+    return ret;
+}
+
+/*
+ * Convert a big integer to it's byte representation
+ */
+static int BigIntToBytes(BIGNUM *num, char *out, int maxoutlen, int *outlen)
+{
+    int len;
+    
+    len = BN_num_bytes(num);
+    
+    if (len > maxoutlen) return SASL_FAIL;
+    
+    *outlen = BN_bn2bin(num, out);
+    
+    return SASL_OK;    
+}
+
+/*
+ * Compare a big integer against a word.
+ */
+static int BigIntCmpWord(BIGNUM *a, BN_ULONG w)
+{
+    BIGNUM *b = BN_new();
+    int r;
+    
+    BN_set_word(b, w);
+    r = BN_cmp(a, b);
+    BN_free(b);
+    return r;
+}
+
+/*
+ * Generate a random big integer.
+ */
+static void GetRandBigInt(BIGNUM *out)
+{
+    BN_init(out);
+    
+    /* xxx likely should use sasl random funcs */
+    BN_rand(out, SRP_MAXBLOCKSIZE*8, 0, 0);
+}
+
+#define MAX_BUFFER_LEN 2147483643
+#define MAX_MPI_LEN 65535
+#define MAX_UTF8_LEN 65535
+#define MAX_OS_LEN 255
+
+/*
+ * Make an SRP buffer from the data specified by the fmt string.
+ */
+static int MakeBuffer(const sasl_utils_t *utils, char **buf, unsigned *buflen,
+                     unsigned *outlen, const char *fmt, ...)
+{
+    va_list ap;
+    char *p, *out = NULL;
+    int r, alloclen, len;
+    BIGNUM *mpi;
+    char *os, *str, c;
+    uint32 u;
+    short ns;
+    long totlen;
+
+    /* first pass to calculate size of buffer */
+    va_start(ap, fmt);
+    for (p = (char *) fmt, alloclen = 0; *p; p++) {
+       if (*p != '%') {
+           alloclen++;
+           continue;
+       }
+
+       switch (*++p) {
+       case 'm':
+           /* MPI */
+           mpi = va_arg(ap, BIGNUM *);
+           len = BN_num_bytes(mpi);
+           if (len > MAX_MPI_LEN) {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "String too long to create mpi string\n");
+               r = SASL_FAIL;
+               goto done;
+           }
+           alloclen += len + 2;
+           break;
+
+       case 'o':
+           /* octet sequence (len followed by data) */
+           len = va_arg(ap, int);
+           if (len > MAX_OS_LEN) {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "String too long to create os string\n");
+               r = SASL_FAIL;
+               goto done;
+           }
+           alloclen += len + 1;
+           os = va_arg(ap, char *);
+           break;
+
+       case 's':
+           /* string */
+           str = va_arg(ap, char *);
+           len = strlen(str);
+           if (len > MAX_UTF8_LEN) {
+               utils->log(NULL, SASL_LOG_ERR,
+                          "String too long to create utf8 string\n");
+               r = SASL_FAIL;
+               goto done;
+           }
+           alloclen += len + 2;
+           break;
+
+       case 'u':
+           /* unsigned int */
+           u = va_arg(ap, uint32);
+           alloclen += sizeof(uint32);
+           break;
+
+       case 'c':
+           /* char */
+           c = va_arg(ap, int) & 0xFF;
+           alloclen += 1;
+           break;
+
+       default:
+           alloclen += 1;
+           break;
+       }
+    }
+    va_end(ap);
+
+    if (alloclen > MAX_BUFFER_LEN) {
+       utils->log(NULL, SASL_LOG_ERR,
+                  "String too long to create SRP buffer string\n");
+       return SASL_FAIL;
+    }
+
+    alloclen += 4;
+    r = _plug_buf_alloc(utils, buf, buflen, alloclen);
+    if (r != SASL_OK) return r;
+
+    out = *buf + 4; /* skip size for now */
+
+    /* second pass to fill buffer */
+    va_start(ap, fmt);
+    for (p = (char *) fmt; *p; p++) {
+       if (*p != '%') {
+           *out = *p;
+           out++;
+           continue;
+       }
+
+       switch (*++p) {
+       case 'm':
+           /* MPI */
+           mpi = va_arg(ap, BIGNUM *);
+           r = BigIntToBytes(mpi, out+2, BN_num_bytes(mpi), &len);
+           if (r) goto done;
+           ns = htons(len);
+           memcpy(out, &ns, 2);        /* add 2 byte len (network order) */
+           out += len + 2;
+           break;
+
+       case 'o':
+           /* octet sequence (len followed by data) */
+           len = va_arg(ap, int);
+           os = va_arg(ap, char *);
+           *out = len & 0xFF;          /* add 1 byte len */
+           memcpy(out+1, os, len);     /* add data */
+           out += len+1;
+           break;
+
+       case 's':
+           /* string */
+           str = va_arg(ap, char *);
+           /* xxx do actual utf8 conversion */
+           len = strlen(str);
+           ns = htons(len);
+           memcpy(out, &ns, 2);        /* add 2 byte len (network order) */
+           memcpy(out+2, str, len);    /* add string */
+           out += len + 2;
+           break;
+
+       case 'u':
+           /* unsigned int */
+           u = va_arg(ap, uint32);
+           u = htonl(u);
+           memcpy(out, &u, sizeof(uint32));
+           out += sizeof(uint32);
+           break;
+
+       case 'c':
+           /* char */
+           c = va_arg(ap, int) & 0xFF;
+           *out = c;
+           out++;
+           break;
+
+       default:
+           *out = *p;
+           out++;
+           break;
+       }
+    }
+  done:
+    va_end(ap);
+
+    *outlen = out - *buf;
+
+    /* add 4 byte len (network order) */
+    totlen = htonl(*outlen - 4);
+    memcpy(*buf, &totlen, 4);
+
+    return r;
+}
+
+/* 
+ * Extract an SRP buffer into the data specified by the fmt string.
+ *
+ * A '-' flag means don't allocate memory for the data ('o' only).
+ */
+static int UnBuffer(const sasl_utils_t *utils, const char *buf,
+                   unsigned buflen, const char *fmt, ...)
+{
+    va_list ap;
+    char *p;
+    int r = SASL_OK, noalloc;
+    BIGNUM *mpi;
+    char **os, **str;
+    uint32 *u;
+    unsigned short ns;
+    unsigned len;
+
+    if (!buf || buflen < 4) {
+       utils->seterror(utils->conn, 0,
+                       "Buffer is not big enough to be SRP buffer: %d\n",
+                       buflen);
+       return SASL_BADPROT;
+    }
+    
+    /* get the length */
+    memcpy(&len, buf, 4);
+    len = ntohl(len);
+    buf += 4;
+    buflen -= 4;
+
+    /* make sure it's right */
+    if (len != buflen) {
+       SETERROR(utils, "SRP Buffer isn't of the right length\n");
+       return SASL_BADPROT;
+    }
+    
+    va_start(ap, fmt);
+    for (p = (char *) fmt; *p; p++) {
+       if (*p != '%') {
+           if (*buf != *p) {
+               r = SASL_BADPROT;
+               goto done;
+           }
+           buf++;
+           buflen--;
+           continue;
+       }
+
+       /* check for noalloc flag */
+       if ((noalloc = (*++p == '-'))) ++p;
+
+       switch (*p) {
+       case 'm':
+           /* MPI */
+           if (buflen < 2) {
+               SETERROR(utils, "Buffer is not big enough to be SRP MPI\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+    
+           /* get the length */
+           memcpy(&ns, buf, 2);
+           len = ntohs(ns);
+           buf += 2;
+           buflen -= 2;
+    
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this SRP MPI\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           mpi = va_arg(ap, BIGNUM *);
+           BN_init(mpi);
+           BN_bin2bn(buf, len, mpi);
+           break;
+
+       case 'o':
+           /* octet sequence (len followed by data) */
+           if (buflen < 1) {
+               SETERROR(utils, "Buffer is not big enough to be SRP os\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+
+           /* get the length */
+           len = (unsigned char) *buf;
+           buf++;
+           buflen--;
+
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this SRP os\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           *(va_arg(ap, int *)) = len;
+           os = va_arg(ap, char **);
+
+           if (noalloc)
+               *os = (char *) buf;
+           else {
+               *os = (char *) utils->malloc(len);
+               if (!*os) {
+                   r = SASL_NOMEM;
+                   goto done;
+               }
+    
+               memcpy(*os, buf, len);
+           }
+           break;
+
+       case 's':
+           /* string */
+           if (buflen < 2) {
+               SETERROR(utils, "Buffer is not big enough to be SRP UTF8\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+    
+           /* get the length */
+           memcpy(&ns, buf, 2);
+           len = ntohs(ns);
+           buf += 2;
+           buflen -= 2;
+    
+           /* make sure it's right */
+           if (len > buflen) {
+               SETERROR(utils, "Not enough data for this SRP UTF8\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+           
+           str = va_arg(ap, char **);
+           *str = (char *) utils->malloc(len+1); /* +1 for NUL */
+           if (!*str) {
+               r = SASL_NOMEM;
+               goto done;
+           }
+    
+           memcpy(*str, buf, len);
+           (*str)[len] = '\0';
+           break;
+
+       case 'u':
+           /* unsigned int */
+           if (buflen < sizeof(uint32)) {
+               SETERROR(utils, "Buffer is not big enough to be SRP uint\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+
+           len = sizeof(uint32);
+           u = va_arg(ap, uint32*);
+           memcpy(u, buf, len);
+           *u = ntohs(*u);
+           break;
+
+       case 'c':
+           /* char */
+           if (buflen < 1) {
+               SETERROR(utils, "Buffer is not big enough to be SRP char\n");
+               r = SASL_BADPROT;
+               goto done;
+           }
+
+           len = 1;
+           *(va_arg(ap, char *)) = *buf;
+           break;
+
+       default:
+           len = 1;
+           if (*buf != *p) {
+               r = SASL_BADPROT;
+               goto done;
+           }
+           break;
+       }
+
+       buf += len;
+       buflen -= len;
+    }
+
+  done:
+    va_end(ap);
+
+    if (buflen != 0) {
+       SETERROR(utils, "Extra data in SRP buffer\n");
+       r = SASL_BADPROT;
+    }
+
+    return r;
+}
+
+/*
+ * Apply the hash function to the data specifed by the fmt string.
+ */
+static int MakeHash(const EVP_MD *md, unsigned char hash[], int *hashlen,
+                   const char *fmt, ...)
+{
+    va_list ap;
+    char *p, buf[4096], *in;
+    int inlen;
+    EVP_MD_CTX mdctx;
+    int r = 0, hflag;
+
+    EVP_DigestInit(&mdctx, md);
+
+    va_start(ap, fmt);
+    for (p = (char *) fmt; *p; p++) {
+       if (*p != '%') {
+           in = p;
+           inlen = 1;
+           hflag = 0;
+       }
+       else {
+           if ((hflag = (*++p == 'h'))) ++p;
+
+           switch (*p) {
+           case 'm': {
+               /* MPI */
+               BIGNUM *mval = va_arg(ap, BIGNUM *);
+
+               in = buf;
+               r = BigIntToBytes(mval, buf, sizeof(buf)-1, &inlen);
+               if (r) goto done;
+               break;
+           }
+
+           case 'o': {
+               /* octet sequence (len followed by data) */
+               inlen = va_arg(ap, int);
+               in = va_arg(ap, char *);
+               break;
+           }
+
+           case 's':
+               /* string */
+               in = va_arg(ap, char *);
+               inlen = strlen(in);
+               break;
+
+           case 'u': {
+               /* unsigned int */
+               uint32 uval = va_arg(ap, uint32);
+
+               in = buf;
+               inlen = sizeof(uint32);
+               *((uint32 *) buf) = htonl(uval);
+               break;
+           }
+
+           default:
+               in = p;
+               inlen = 1;
+               break;
+           }
+       }
+
+       if (hflag) {
+           /* hash data separately before adding to current hash */
+           EVP_MD_CTX tmpctx;
+
+           EVP_DigestInit(&tmpctx, md);
+           EVP_DigestUpdate(&tmpctx, in, inlen);
+           EVP_DigestFinal(&tmpctx, buf, &inlen);
+           in = buf;
+       }
+
+       EVP_DigestUpdate(&mdctx, in, inlen);
+    }
+  done:
+    va_end(ap);
+
+    EVP_DigestFinal(&mdctx, hash, hashlen);
+
+    return r;
+}
+
+static int CalculateX(context_t *text, const char *salt, int saltlen, 
+                     const char *user, const char *pass, int passlen, 
+                     BIGNUM *x)
+{
+    char hash[EVP_MAX_MD_SIZE];
+    int hashlen;
+    
+    /* x = H(salt | H(user | ':' | pass)) */
+    MakeHash(text->md, hash, &hashlen, "%s:%o", user, passlen, pass);
+    MakeHash(text->md, hash, &hashlen, "%o%o", saltlen, salt, hashlen, hash);
+    
+    BN_init(x);
+    BN_bin2bn(hash, hashlen, x);
+    
+    return SASL_OK;
+}
+
+static int CalculateM1(context_t *text, BIGNUM *N, BIGNUM *g,
+                      char *U, char *salt, int saltlen,
+                      BIGNUM *A, BIGNUM *B, char *K, int Klen,
+                      char *I, char *L, char *M1, int *M1len)
+{
+    int r, i, len;
+    unsigned char Nhash[EVP_MAX_MD_SIZE];
+    unsigned char ghash[EVP_MAX_MD_SIZE];
+    unsigned char Ng[EVP_MAX_MD_SIZE];
+
+    /* bytes(H( bytes(N) )) ^ bytes( H( bytes(g) ))
+       ^ is the bitwise XOR operator. */
+    r = MakeHash(text->md, Nhash, &len, "%m", N);
+    if (r) return r;
+    r = MakeHash(text->md, ghash, &len, "%m", g);
+    if (r) return r;
+    
+    for (i = 0; i < len; i++) {
+       Ng[i] = (Nhash[i] ^ ghash[i]);
+    }
+
+    r = MakeHash(text->md, M1, M1len, "%o%hs%o%m%m%o%hs%hs",
+                len, Ng, U, saltlen, salt, A, B, Klen, K, I, L);
+    
+    return r;
+}
+
+static int CalculateM2(context_t *text, BIGNUM *A,
+                      char *M1, int M1len, char *K, int Klen,
+                      char *I, char *o, char *sid, uint32 ttl,
+                      char *M2, int *M2len)
+{
+    int r;
+    
+    r = MakeHash(text->md, M2, M2len, "%m%o%o%hs%hs%s%u",
+                A, M1len, M1, Klen, K, I, o, sid, ttl);
+
+    return r;
+}
+
+/* Parse an option out of an option string
+ * Place found option in 'option'
+ * 'nextptr' points to rest of string or NULL if at end
+ */
+static int ParseOption(const sasl_utils_t *utils,
+                      char *in, char **option, char **nextptr)
+{
+    char *comma;
+    int len;
+    int i;
+    
+    if (strlen(in) == 0) {
+       *option = NULL;
+       return SASL_OK;
+    }
+    
+    comma = strchr(in,',');    
+    if (comma == NULL) comma = in + strlen(in);
+    
+    len = comma - in;
+    
+    *option = utils->malloc(len + 1);
+    if (!*option) return SASL_NOMEM;
+    
+    /* lowercase string */
+    for (i = 0; i < len; i++) {
+       (*option)[i] = tolower((int)in[i]);
+    }
+    (*option)[len] = '\0';
+    
+    if (*comma) {
+       *nextptr = comma+1;
+    } else {
+       *nextptr = NULL;
+    }
+    
+    return SASL_OK;
+}
+
+static int FindBit(char *name, layer_option_t *opts)
+{
+    while (opts->name) {
+       if (!strcasecmp(name, opts->name)) {
+           return opts->bit;
+       }
+       
+       opts++;
+    }
+    
+    return 0;
+}
+
+static layer_option_t *FindOptionFromBit(unsigned bit, layer_option_t *opts)
+{
+    while (opts->name) {
+       if (opts->bit == bit) {
+           return opts;
+       }
+       
+       opts++;
+    }
+    
+    return NULL;
+}
+
+static int ParseOptionString(const sasl_utils_t *utils,
+                            char *str, srp_options_t *opts, int isserver)
+{
+    if (!strncasecmp(str, OPTION_MDA, strlen(OPTION_MDA))) {
+       
+       int bit = FindBit(str+strlen(OPTION_MDA), digest_options);
+       
+       if (isserver && (!bit || opts->mda)) {
+           opts->mda = -1;
+           if (!bit)
+               utils->seterror(utils->conn, 0,
+                               "SRP MDA %s not supported\n",
+                               str+strlen(OPTION_MDA));
+           else
+               SETERROR(utils, "Multiple SRP MDAs given\n");
+           return SASL_BADPROT;
+       }
+       
+       opts->mda |= bit;
+       
+    } else if (!strcasecmp(str, OPTION_REPLAY_DETECTION)) {
+       if (opts->replay_detection) {
+           SETERROR(utils, "SRP Replay Detection option appears twice\n");
+           return SASL_BADPROT;
+       }
+       opts->replay_detection = 1;
+       
+    } else if (!strncasecmp(str, OPTION_INTEGRITY, strlen(OPTION_INTEGRITY)) &&
+              !strncasecmp(str+strlen(OPTION_INTEGRITY), "HMAC-", 5)) {
+       
+       int bit = FindBit(str+strlen(OPTION_INTEGRITY)+5, digest_options);
+       
+       if (isserver && (!bit || opts->integrity)) {
+           opts->integrity = -1;
+           if (!bit)
+               utils->seterror(utils->conn, 0,
+                               "SRP Integrity option %s not supported\n",
+                               str+strlen(OPTION_INTEGRITY));
+           else
+               SETERROR(utils, "Multiple SRP Integrity options given\n");
+           return SASL_BADPROT;
+       }
+       
+       opts->integrity |= bit;
+       
+    } else if (!strncasecmp(str, OPTION_CONFIDENTIALITY,
+                           strlen(OPTION_CONFIDENTIALITY))) {
+       
+       int bit = FindBit(str+strlen(OPTION_CONFIDENTIALITY),
+                         cipher_options);
+       
+       if (isserver && (!bit || opts->confidentiality)) {
+           opts->confidentiality = -1;
+           if (!bit)
+               utils->seterror(utils->conn, 0,
+                               "SRP Confidentiality option %s not supported\n",
+                               str+strlen(OPTION_CONFIDENTIALITY));
+           else
+               SETERROR(utils,
+                        "Multiple SRP Confidentiality options given\n");
+           return SASL_FAIL;
+       }
+       
+       opts->confidentiality |= bit;
+       
+    } else if (!isserver && !strncasecmp(str, OPTION_MANDATORY,
+                                        strlen(OPTION_MANDATORY))) {
+       
+       char *layer = str+strlen(OPTION_MANDATORY);
+       
+       if (!strcasecmp(layer, OPTION_REPLAY_DETECTION))
+           opts->mandatory |= BIT_REPLAY_DETECTION;
+       else if (!strncasecmp(layer, OPTION_INTEGRITY,
+                             strlen(OPTION_INTEGRITY)-1))
+           opts->mandatory |= BIT_INTEGRITY;
+       else if (!strncasecmp(layer, OPTION_CONFIDENTIALITY,
+                             strlen(OPTION_CONFIDENTIALITY)-1))
+           opts->mandatory |= BIT_CONFIDENTIALITY;
+       else {
+           utils->seterror(utils->conn, 0,
+                           "Mandatory SRP option %s not supported\n", layer);
+           return SASL_BADPROT;
+       }
+       
+    } else if (!strncasecmp(str, OPTION_MAXBUFFERSIZE,
+                           strlen(OPTION_MAXBUFFERSIZE))) {
+       
+       opts->maxbufsize = strtoul(str+strlen(OPTION_MAXBUFFERSIZE), NULL, 10);
+       
+       if (opts->maxbufsize > SRP_MAXBUFFERSIZE) {
+           utils->seterror(utils->conn, 0,
+                           "SRP Maxbuffersize %lu too big (> %lu)\n",
+                           opts->maxbufsize, SRP_MAXBUFFERSIZE);
+           return SASL_BADPROT;
+       }
+       
+    } else {
+       /* Ignore unknown options */
+    }
+    
+    return SASL_OK;
+}
+
+static int ParseOptions(const sasl_utils_t *utils,
+                       char *in, srp_options_t *out, int isserver)
+{
+    int r;
+    
+    memset(out, 0, sizeof(srp_options_t));
+    out->maxbufsize = SRP_MAXBUFFERSIZE;
+    
+    while (in) {
+       char *opt;
+       
+       r = ParseOption(utils, in, &opt, &in);
+       if (r) return r;
+       
+       if (opt == NULL) return SASL_OK;
+       
+       utils->log(NULL, SASL_LOG_DEBUG, "Got option: [%s]\n",opt);
+       
+       r = ParseOptionString(utils, opt, out, isserver);
+       utils->free(opt);
+       
+       if (r) return r;
+    }
+    
+    return SASL_OK;
+}
+
+static layer_option_t *FindBest(int available, sasl_ssf_t min_ssf,
+                               sasl_ssf_t max_ssf, layer_option_t *opts)
+{
+    layer_option_t *best = NULL;
+    
+    if (!available) return NULL;
+    
+    while (opts->name) {
+       if (opts->enabled && (available & opts->bit) &&
+           (opts->ssf >= min_ssf) && (opts->ssf <= max_ssf) &&
+           (!best || (opts->ssf > best->ssf))) {
+           best = opts;
+       }
+       
+       opts++;
+    }
+    
+    return best;
+}
+
+static int OptionsToString(const sasl_utils_t *utils,
+                          srp_options_t *opts, char **out)
+{
+    char *ret = NULL;
+    int alloced = 0;
+    int first = 1;
+    layer_option_t *optlist;
+    
+    ret = utils->malloc(1);
+    if (!ret) return SASL_NOMEM;
+    alloced = 1;
+    ret[0] = '\0';
+    
+    optlist = digest_options;
+    while(optlist->name) {
+       if (opts->mda & optlist->bit) {
+           alloced += strlen(OPTION_MDA)+strlen(optlist->name)+1;
+           ret = utils->realloc(ret, alloced);
+           if (!ret) return SASL_NOMEM;
+           
+           if (!first) strcat(ret, ",");
+           strcat(ret, OPTION_MDA);
+           strcat(ret, optlist->name);
+           first = 0;
+       }
+       
+       optlist++;
+    }
+    
+    if (opts->replay_detection) {
+       alloced += strlen(OPTION_REPLAY_DETECTION)+1;
+       ret = utils->realloc(ret, alloced);
+       if (!ret) return SASL_NOMEM;
+       
+       if (!first) strcat(ret, ",");
+       strcat(ret, OPTION_REPLAY_DETECTION);
+       first = 0;
+    }
+    
+    optlist = digest_options;
+    while(optlist->name) {
+       if (opts->integrity & optlist->bit) {
+           alloced += strlen(OPTION_INTEGRITY)+5+strlen(optlist->name)+1;
+           ret = utils->realloc(ret, alloced);
+           if (!ret) return SASL_NOMEM;
+           
+           if (!first) strcat(ret, ",");
+           strcat(ret, OPTION_INTEGRITY);
+           strcat(ret, "HMAC-");
+           strcat(ret, optlist->name);
+           first = 0;
+       }
+       
+       optlist++;
+    }
+    
+    optlist = cipher_options;
+    while(optlist->name) {
+       if (opts->confidentiality & optlist->bit) {
+           alloced += strlen(OPTION_CONFIDENTIALITY)+strlen(optlist->name)+1;
+           ret = utils->realloc(ret, alloced);
+           if (!ret) return SASL_NOMEM;
+           
+           if (!first) strcat(ret, ",");
+           strcat(ret, OPTION_CONFIDENTIALITY);
+           strcat(ret, optlist->name);
+           first = 0;
+       }
+       
+       optlist++;
+    }
+    
+    if ((opts->integrity || opts->confidentiality) &&
+       opts->maxbufsize < SRP_MAXBUFFERSIZE) {
+       alloced += strlen(OPTION_MAXBUFFERSIZE)+10+1;
+       ret = utils->realloc(ret, alloced);
+       if (!ret) return SASL_NOMEM;
+       
+       if (!first) strcat(ret, ",");
+       strcat(ret, OPTION_MAXBUFFERSIZE);
+       sprintf(ret+strlen(ret), "%lu", opts->maxbufsize);
+       first = 0;
+    }
+    
+    if (opts->mandatory & BIT_REPLAY_DETECTION) {
+       alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_REPLAY_DETECTION)+1;
+       ret = utils->realloc(ret, alloced);
+       if (!ret) return SASL_NOMEM;
+       
+       if (!first) strcat(ret, ",");
+       strcat(ret, OPTION_MANDATORY);
+       strcat(ret, OPTION_REPLAY_DETECTION);
+       first = 0;
+    }
+    
+    if (opts->mandatory & BIT_INTEGRITY) {
+       alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_INTEGRITY)-1+1;
+       ret = utils->realloc(ret, alloced);
+       if (!ret) return SASL_NOMEM;
+       
+       if (!first) strcat(ret, ",");
+       strcat(ret, OPTION_MANDATORY);
+       strncat(ret, OPTION_INTEGRITY, strlen(OPTION_INTEGRITY)-1);
+       /* terminate string */
+       ret[alloced-1] = '\0';
+       first = 0;
+    }
+    
+    if (opts->mandatory & BIT_CONFIDENTIALITY) {
+       alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_CONFIDENTIALITY)-1+1;
+       ret = utils->realloc(ret, alloced);
+       if (!ret) return SASL_NOMEM;
+       
+       if (!first) strcat(ret, ",");
+       strcat(ret, OPTION_MANDATORY);
+       strncat(ret, OPTION_CONFIDENTIALITY, strlen(OPTION_CONFIDENTIALITY)-1);
+       /* terminate string */
+       ret[alloced-1] = '\0';
+       first = 0;
+    }
+    
+    *out = ret;
+    return SASL_OK;
+}
+
+
+/*
+ * Set the selected MDA.
+ */
+static int SetMDA(srp_options_t *opts, context_t *text)
+{
+    layer_option_t *opt;
+    
+    opt = FindOptionFromBit(opts->mda, digest_options);
+    if (!opt) {
+       text->utils->log(NULL, SASL_LOG_ERR,
+                        "Unable to find SRP MDA option now\n");
+       return SASL_FAIL;
+    }
+    
+    text->md = EVP_get_digestbyname(opt->evp_name);
+    
+    return SASL_OK;
+}
+
+/*
+ * Setup the selected security layer.
+ */
+static int LayerInit(srp_options_t *opts, context_t *text,
+                    sasl_out_params_t *oparams, char *enc_IV, char *dec_IV,
+                    unsigned maxbufsize)
+{
+    layer_option_t *opt;
+    
+    if ((opts->integrity == 0) && (opts->confidentiality == 0)) {
+       oparams->encode = NULL;
+       oparams->decode = NULL;
+       oparams->mech_ssf = 0;
+       text->utils->log(NULL, SASL_LOG_DEBUG, "Using no protection\n");
+       return SASL_OK;
+    }
+    
+    oparams->encode = &srp_encode;
+    oparams->decode = &srp_decode;
+    oparams->maxoutbuf = opts->maxbufsize - 4; /* account for 4-byte length */
+
+    _plug_decode_init(&text->decode_context, text->utils, maxbufsize);
+    
+    if (opts->replay_detection) {
+       text->utils->log(NULL, SASL_LOG_DEBUG, "Using replay detection\n");
+
+       text->layer |= BIT_REPLAY_DETECTION;
+       
+       /* If no integrity layer specified, use default */
+       if (!opts->integrity)
+           opts->integrity = default_digest->bit;
+    }
+    
+    if (opts->integrity) {
+       text->utils->log(NULL, SASL_LOG_DEBUG, "Using integrity protection\n");
+       
+       text->layer |= BIT_INTEGRITY;
+       
+       opt = FindOptionFromBit(opts->integrity, digest_options);
+       if (!opt) {
+           text->utils->log(NULL, SASL_LOG_ERR,
+                            "Unable to find SRP integrity layer option\n");
+           return SASL_FAIL;
+       }
+       
+       oparams->mech_ssf = opt->ssf;
+
+       /* Initialize the HMACs */
+       text->hmac_md = EVP_get_digestbyname(opt->evp_name);
+       HMAC_Init(&text->hmac_send_ctx, text->K, text->Klen, text->hmac_md);
+       HMAC_Init(&text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md);
+       
+       /* account for HMAC */
+       oparams->maxoutbuf -= EVP_MD_size(text->hmac_md);
+    }
+    
+    if (opts->confidentiality) {
+       text->utils->log(NULL, SASL_LOG_DEBUG,
+                        "Using confidentiality protection\n");
+       
+       text->layer |= BIT_CONFIDENTIALITY;
+       
+       opt = FindOptionFromBit(opts->confidentiality, cipher_options);
+       if (!opt) {
+           text->utils->log(NULL, SASL_LOG_ERR,
+                            "Unable to find SRP confidentiality layer option\n");
+           return SASL_FAIL;
+       }
+       
+       oparams->mech_ssf = opt->ssf;
+
+       /* Initialize the ciphers */
+       text->cipher = EVP_get_cipherbyname(opt->evp_name);
+
+       EVP_CIPHER_CTX_init(&text->cipher_enc_ctx);
+       EVP_EncryptInit(&text->cipher_enc_ctx, text->cipher, text->K, enc_IV);
+
+       EVP_CIPHER_CTX_init(&text->cipher_dec_ctx);
+       EVP_DecryptInit(&text->cipher_dec_ctx, text->cipher, text->K, dec_IV);
+    }
+    
+    return SASL_OK;
+}
+
+static void LayerCleanup(context_t *text)
+{
+    if (text->layer & BIT_INTEGRITY) {
+       HMAC_cleanup(&text->hmac_send_ctx);
+       HMAC_cleanup(&text->hmac_recv_ctx);
+    }
+
+    if (text->layer & BIT_CONFIDENTIALITY) {
+       EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx);
+       EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx);
+    }
+}
+    
+
+/*
+ * Dispose of a SRP context (could be server or client)
+ */ 
+static void srp_common_mech_dispose(void *conn_context,
+                                   const sasl_utils_t *utils)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    if (!text) return;
+    
+    BN_clear_free(&text->N);
+    BN_clear_free(&text->g);
+    BN_clear_free(&text->v);
+    BN_clear_free(&text->b);
+    BN_clear_free(&text->B);
+    BN_clear_free(&text->a);
+    BN_clear_free(&text->A);
+    
+    if (text->authid)          utils->free(text->authid);
+    if (text->userid)          utils->free(text->userid);
+    if (text->free_password)   _plug_free_secret(utils, &(text->password));
+    if (text->salt)            utils->free(text->salt);
+    
+    if (text->client_options)  utils->free(text->client_options);
+    if (text->server_options)  utils->free(text->server_options);
+    LayerCleanup(text);
+    _plug_decode_free(&text->decode_context);
+
+    if (text->encode_buf)      utils->free(text->encode_buf);
+    if (text->decode_buf)      utils->free(text->decode_buf);
+    if (text->decode_pkt_buf)  utils->free(text->decode_pkt_buf);
+    if (text->out_buf)         utils->free(text->out_buf);
+    
+    utils->free(text);
+}
+
+static void
+srp_common_mech_free(void *global_context __attribute__((unused)),
+                    const sasl_utils_t *utils __attribute__((unused)))
+{
+    EVP_cleanup();
+}
+
+
+/*****************************  Server Section  *****************************/
+
+/* A large safe prime (N = 2q+1, where q is prime)
+ *
+ * Use N with the most bits from our table.
+ *
+ * All arithmetic is done modulo N
+ */
+static int generate_N_and_g(BIGNUM *N, BIGNUM *g)
+{
+    int result;
+    
+    BN_init(N);
+    result = BN_hex2bn(&N, Ng_tab[NUM_Ng-1].N);
+    if (!result) return SASL_FAIL;
+    
+    BN_init(g);
+    BN_set_word(g, Ng_tab[NUM_Ng-1].g);
+    
+    return SASL_OK;
+}
+
+static int CalculateV(context_t *text,
+                     BIGNUM *N, BIGNUM *g,
+                     const char *user,
+                     const char *pass, unsigned passlen,
+                     BIGNUM *v, char **salt, int *saltlen)
+{
+    BIGNUM x;
+    BN_CTX *ctx = BN_CTX_new();
+    int r;
+    
+    /* generate <salt> */    
+    *saltlen = SRP_MAXBLOCKSIZE;
+    *salt = (char *)text->utils->malloc(*saltlen);
+    if (!*salt) return SASL_NOMEM;
+    text->utils->rand(text->utils->rpool, *salt, *saltlen);
+    
+    r = CalculateX(text, *salt, *saltlen, user, pass, passlen, &x);
+    if (r) {
+       text->utils->seterror(text->utils->conn, 0, 
+                             "Error calculating 'x'");
+       return r;
+    }
+    
+    /* v = g^x % N */
+    BN_init(v);
+    BN_mod_exp(v, g, &x, N, ctx);
+    
+    BN_CTX_free(ctx);
+    BN_clear_free(&x);
+    
+    return r;   
+}
+
+static int CalculateB(context_t *text  __attribute__((unused)),
+                     BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM *b, BIGNUM *B)
+{
+    BIGNUM v3;
+    BN_CTX *ctx = BN_CTX_new();
+    
+    /* Generate b */
+    GetRandBigInt(b);
+       
+    /* Per [SRP]: make sure b > log[g](N) -- g is always 2 */
+    BN_add_word(b, BN_num_bits(N));
+       
+    /* B = (3v + g^b) % N */
+    BN_init(&v3);
+    BN_set_word(&v3, 3);
+    BN_mod_mul(&v3, &v3, v, N, ctx);
+    BN_init(B);
+    BN_mod_exp(B, g, b, N, ctx);
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+    BN_mod_add(B, B, &v3, N, ctx);
+#else
+    BN_add(B, B, &v3);
+    BN_mod(B, B, N, ctx);
+#endif
+
+    BN_CTX_free(ctx);
+    
+    return SASL_OK;
+}
+       
+static int ServerCalculateK(context_t *text, BIGNUM *v,
+                           BIGNUM *N, BIGNUM *A, BIGNUM *b, BIGNUM *B,
+                           char *K, int *Klen)
+{
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    int hashlen;
+    BIGNUM u;
+    BIGNUM base;
+    BIGNUM S;
+    BN_CTX *ctx = BN_CTX_new();
+    int r;
+    
+    /* u = H(A | B) */
+    r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
+    if (r) return r;
+       
+    BN_init(&u);
+    BN_bin2bn(hash, hashlen, &u);
+       
+    /* S = (Av^u) ^ b % N */
+    BN_init(&base);
+    BN_mod_exp(&base, v, &u, N, ctx);
+    BN_mod_mul(&base, &base, A, N, ctx);
+    
+    BN_init(&S);
+    BN_mod_exp(&S, &base, b, N, ctx);
+    
+    /* per Tom Wu: make sure Av^u != 1 (mod N) */
+    if (BN_is_one(&base)) {
+       SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
+       r = SASL_BADPROT;
+       goto err;
+    }
+    
+    /* per Tom Wu: make sure Av^u != -1 (mod N) */
+    BN_add_word(&base, 1);
+    if (BN_cmp(&S, N) == 0) {
+       SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n");
+       r = SASL_BADPROT;
+       goto err;
+    }
+    
+    /* K = H(S) */
+    r = MakeHash(text->md, K, Klen, "%m", &S);
+    if (r) goto err;
+    
+    r = SASL_OK;
+    
+  err:
+    BN_CTX_free(ctx);
+    BN_clear_free(&u);
+    BN_clear_free(&base);
+    BN_clear_free(&S);
+    
+    return r;
+}
+
+static int ParseUserSecret(const sasl_utils_t *utils,
+                          char *secret, size_t seclen,
+                          char **mda, BIGNUM *v, char **salt, int *saltlen)
+{
+    int r;
+    
+    /* The secret data is stored as suggested in RFC 2945:
+     *
+     *  { utf8(mda) mpi(v) os(salt) }  (base64 encoded)
+     */
+    r = utils->decode64(secret, seclen, secret, seclen, &seclen);
+
+    if (!r)
+       r = UnBuffer(utils, secret, seclen, "%s%m%o", mda, v, saltlen, salt);
+    if (r) {
+       utils->seterror(utils->conn, 0, 
+                       "Error UnBuffering user secret");
+    }
+
+    return r;
+}
+
+static int CreateServerOptions(sasl_server_params_t *sparams, char **out)
+{
+    srp_options_t opts;
+    sasl_ssf_t limitssf, requiressf;
+    layer_option_t *optlist;
+    
+    /* zero out options */
+    memset(&opts,0,sizeof(srp_options_t));
+    
+    /* Add mda */
+    opts.mda = server_mda->bit;
+
+    if(sparams->props.maxbufsize == 0) {
+       limitssf = 0;
+       requiressf = 0;
+    } else {
+       if (sparams->props.max_ssf < sparams->external_ssf) {
+           limitssf = 0;
+       } else {
+           limitssf = sparams->props.max_ssf - sparams->external_ssf;
+       }
+       if (sparams->props.min_ssf < sparams->external_ssf) {
+           requiressf = 0;
+       } else {
+           requiressf = sparams->props.min_ssf - sparams->external_ssf;
+       }
+    }
+    
+    /*
+     * Add integrity options
+     * Can't advertise integrity w/o support for default HMAC
+     */
+    if (default_digest->enabled) {
+       optlist = digest_options;
+       while(optlist->name) {
+           if (optlist->enabled &&
+               /*(requiressf <= 1) &&*/ (limitssf >= 1)) {
+               opts.integrity |= optlist->bit;
+           }
+           optlist++;
+       }
+    }
+    
+    /* if we set any integrity options we can advertise replay detection */
+    if (opts.integrity) {
+       opts.replay_detection = 1;
+    }
+    
+    /*
+     * Add confidentiality options
+     * Can't advertise confidentiality w/o support for default cipher
+     */
+    if (default_cipher->enabled) {
+       optlist = cipher_options;
+       while(optlist->name) {
+           if (optlist->enabled &&
+               (requiressf <= optlist->ssf) &&
+               (limitssf >= optlist->ssf)) {
+               opts.confidentiality |= optlist->bit;
+           }
+           optlist++;
+       }
+    }
+    
+    /* Add mandatory options */
+    if (requiressf >= 1)
+       opts.mandatory = BIT_REPLAY_DETECTION | BIT_INTEGRITY;
+    if (requiressf > 1)
+       opts.mandatory |= BIT_CONFIDENTIALITY;
+    
+    /* Add maxbuffersize */
+    opts.maxbufsize = SRP_MAXBUFFERSIZE;
+    if (sparams->props.maxbufsize &&
+       sparams->props.maxbufsize < opts.maxbufsize)
+       opts.maxbufsize = sparams->props.maxbufsize;
+    
+    return OptionsToString(sparams->utils, &opts, out);
+}
+
+static int
+srp_server_mech_new(void *glob_context __attribute__((unused)),
+                   sasl_server_params_t *params,
+                   const char *challenge __attribute__((unused)),
+                   unsigned challen __attribute__((unused)),
+                   void **conn_context)
+{
+    context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(context_t));
+    if (text == NULL) {
+       MEMERROR(params->utils);
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(context_t));
+    
+    text->state = 1;
+    text->utils = params->utils;
+    text->md = EVP_get_digestbyname(server_mda->evp_name);
+    
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int srp_server_mech_step1(context_t *text,
+                                sasl_server_params_t *params,
+                                const char *clientin,
+                                unsigned clientinlen,
+                                const char **serverout,
+                                unsigned *serveroutlen,
+                                sasl_out_params_t *oparams)
+{
+    int result;
+    char *sid = NULL;
+    char *cn = NULL;
+    int cnlen;
+    char *realm = NULL;
+    char *user = NULL;
+    const char *password_request[] = { "*cmusaslsecretSRP",
+                                      SASL_AUX_PASSWORD,
+                                      NULL };
+    struct propval auxprop_values[3];
+    
+    /* Expect:
+     *
+     * U - authentication identity
+     * I - authorization identity
+     * sid - session id
+     * cn - client nonce
+     *
+     * { utf8(U) utf8(I) utf8(sid) os(cn) }
+     *
+     */
+    result = UnBuffer(params->utils, clientin, clientinlen,
+                     "%s%s%s%o", &text->authid, &text->userid, &sid,
+                     &cnlen, &cn);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 1");
+       return result;
+    }
+    /* Get the realm */
+    result = _plug_parseuser(params->utils, &user, &realm, params->user_realm,
+                            params->serverFQDN, text->authid);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error getting realm");
+       goto cleanup;
+    }
+    
+    /* Generate N and g */
+    result = generate_N_and_g(&text->N, &text->g);
+    if (result) {
+       params->utils->seterror(text->utils->conn, 0, 
+                               "Error calculating N and g");
+       return result;
+    }
+    
+    /* Get user secret */
+    result = params->utils->prop_request(params->propctx, password_request);
+    if (result != SASL_OK) goto cleanup;
+    
+    /* this will trigger the getting of the aux properties */
+    result = params->canon_user(params->utils->conn,
+                               text->authid, 0, SASL_CU_AUTHID, oparams);
+    if (result != SASL_OK) goto cleanup;
+    
+    result = params->canon_user(params->utils->conn,
+                               text->userid, 0, SASL_CU_AUTHZID, oparams);
+    if (result != SASL_OK) goto cleanup;
+    
+    result = params->utils->prop_getnames(params->propctx, password_request,
+                                         auxprop_values);
+    if (result < 0 ||
+       ((!auxprop_values[0].name || !auxprop_values[0].values) &&
+        (!auxprop_values[1].name || !auxprop_values[1].values))) {
+       /* We didn't find this username */
+       params->utils->seterror(params->utils->conn,0,
+                               "no secret in database");
+       result = params->transition ? SASL_TRANS : SASL_NOUSER;
+       goto cleanup;
+    }
+    
+    if (auxprop_values[0].name && auxprop_values[0].values) {
+       char *mda = NULL;
+       
+       /* We have a precomputed verifier */
+       result = ParseUserSecret(params->utils,
+                                (char*) auxprop_values[0].values[0],
+                                auxprop_values[0].valsize,
+                                &mda, &text->v, &text->salt, &text->saltlen);
+       
+       if (result) {
+           /* ParseUserSecret sets error, if any */
+           if (mda) params->utils->free(mda);
+           goto cleanup;
+       }
+       
+       /* find mda */
+       server_mda = digest_options;
+       while (server_mda->name) {
+           if (!strcasecmp(server_mda->name, mda))
+               break;
+           
+           server_mda++;
+       }
+       
+       if (!server_mda->name) {
+           params->utils->seterror(params->utils->conn, 0,
+                                   "unknown SRP mda '%s'", mda);
+           params->utils->free(mda);
+           result = SASL_FAIL;
+           goto cleanup;
+       }
+       params->utils->free(mda);
+       
+    } else if (auxprop_values[1].name && auxprop_values[1].values) {
+       /* We only have the password -- calculate the verifier */
+       int len = strlen(auxprop_values[1].values[0]);
+
+       if (len == 0) {
+           params->utils->seterror(params->utils->conn,0,
+                                   "empty secret");
+           result = SASL_FAIL;
+           goto cleanup;
+       }
+       
+       result = CalculateV(text, &text->N, &text->g, text->authid,
+                           auxprop_values[1].values[0], len,
+                           &text->v, &text->salt, &text->saltlen);
+       if (result) {
+           params->utils->seterror(params->utils->conn, 0, 
+                                   "Error calculating v");
+           goto cleanup;
+       }
+    } else {
+       params->utils->seterror(params->utils->conn, 0,
+                               "Have neither type of secret");
+       result = SASL_FAIL;
+       goto cleanup;
+    }    
+    
+    /* erase the plaintext password */
+    params->utils->prop_erase(params->propctx, password_request[1]);
+    
+    /* Calculate B */
+    result = CalculateB(text, &text->v, &text->N, &text->g,
+                       &text->b, &text->B);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error calculating B");
+       return result;
+    }
+
+    /* Create L */
+    result = CreateServerOptions(params, &text->server_options);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error creating server options");
+       goto cleanup;
+    }
+    
+    /* Send out:
+     *
+     * N - safe prime modulus
+     * g - generator
+     * s - salt
+     * B - server's public key
+     * L - server options (available layers etc)
+     *
+     * { 0x00 mpi(N) mpi(g) os(s) mpi(B) utf8(L) }
+     *
+     */
+    result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
+                       serveroutlen, "%c%m%m%o%m%s",
+                       0x00, &text->N, &text->g, text->saltlen, text->salt,
+                       &text->B, text->server_options);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error creating SRP buffer from data in step 1");
+       goto cleanup;
+    }
+    *serverout = text->out_buf;
+    
+    text->state = 2;
+    result = SASL_CONTINUE;
+    
+  cleanup:
+    if (sid) params->utils->free(sid);
+    if (cn) params->utils->free(cn);
+    if (user) params->utils->free(user);
+    if (realm) params->utils->free(realm);
+    
+    return result;
+}
+
+static int srp_server_mech_step2(context_t *text,
+                       sasl_server_params_t *params,
+                       const char *clientin,
+                       unsigned clientinlen,
+                       const char **serverout,
+                       unsigned *serveroutlen,
+                       sasl_out_params_t *oparams)
+{
+    int result;    
+    char *M1 = NULL, *cIV = NULL; /* don't free */
+    int M1len, cIVlen;
+    srp_options_t client_opts;
+    char myM1[EVP_MAX_MD_SIZE];
+    int myM1len;
+    int i;
+    char M2[EVP_MAX_MD_SIZE];
+    int M2len;
+    char sIV[SRP_MAXBLOCKSIZE];
+    
+    /* Expect:
+     *
+     * A - client's public key
+     * M1 - client evidence
+     * o - client option list
+     * cIV - client's initial vector
+     *
+     * { mpi(A) os(M1) utf8(o) os(cIV) }
+     *
+     */
+    result = UnBuffer(params->utils, clientin, clientinlen,
+                     "%m%-o%s%-o", &text->A, &M1len, &M1,
+                     &text->client_options, &cIVlen, &cIV);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 2");
+       goto cleanup;
+    }
+    
+    /* Per [SRP]: reject A <= 0 */
+    if (BigIntCmpWord(&text->A, 0) <= 0) {
+       SETERROR(params->utils, "Illegal value for 'A'\n");
+       result = SASL_BADPROT;
+       goto cleanup;
+    }
+
+    /* parse client options */
+    result = ParseOptions(params->utils, text->client_options, &client_opts, 1);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error parsing user's options");
+       
+       if (client_opts.confidentiality) {
+           /* Mark that we attempted confidentiality layer negotiation */
+           oparams->mech_ssf = 2;
+       }
+       else if (client_opts.integrity || client_opts.replay_detection) {
+           /* Mark that we attempted integrity layer negotiation */
+           oparams->mech_ssf = 1;
+       }
+       return result;
+    }
+
+    result = SetMDA(&client_opts, text);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error setting options");
+       return result;   
+    }
+
+    /* Calculate K */
+    result = ServerCalculateK(text, &text->v, &text->N, &text->A,
+                             &text->b, &text->B, text->K, &text->Klen);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error calculating K");
+       return result;
+    }
+    
+    /* See if M1 is correct */
+    result = CalculateM1(text, &text->N, &text->g, text->authid,
+                        text->salt, text->saltlen, &text->A, &text->B,
+                        text->K, text->Klen, text->userid,
+                        text->server_options, myM1, &myM1len);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error calculating M1");
+       goto cleanup;
+    }
+    
+    if (myM1len != M1len) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "SRP M1 lengths do not match");
+       result = SASL_BADAUTH;
+       goto cleanup;
+    }
+    
+    for (i = 0; i < myM1len; i++) {
+       if (myM1[i] != M1[i]) {
+           params->utils->seterror(params->utils->conn, 0, 
+                                   "client evidence does not match what we "
+                                   "calculated. Probably a password error");
+           result = SASL_BADAUTH;
+           goto cleanup;
+       }
+    }
+    
+    /* calculate M2 to send */
+    result = CalculateM2(text, &text->A, M1, M1len, text->K, text->Klen,
+                        text->userid, text->client_options, "", 0,
+                        M2, &M2len);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error calculating M2 (server evidence)");
+       goto cleanup;
+    }
+    
+    /* Create sIV (server initial vector) */
+    text->utils->rand(text->utils->rpool, sIV, sizeof(sIV));
+    
+    /*
+     * Send out:
+     * M2 - server evidence
+     * sIV - server's initial vector
+     * sid - session id
+     * ttl - time to live
+     *
+     * { os(M2) os(sIV) utf8(sid) uint(ttl) }
+     */
+    result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
+                       serveroutlen, "%o%o%s%u", M2len, M2,
+                       sizeof(sIV), sIV, "", 0);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error making output buffer in SRP step 3");
+       goto cleanup;
+    }
+    *serverout = text->out_buf;
+
+    /* configure security layer */
+    result = LayerInit(&client_opts, text, oparams, cIV, sIV,
+                      params->props.maxbufsize);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error initializing security layer");
+       return result;   
+    }
+
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->param_version = 0;
+    
+    result = SASL_OK;
+    
+  cleanup:
+    
+    return result;
+}
+
+static int srp_server_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)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    if (!sparams
+       || !serverout
+       || !serveroutlen
+       || !oparams)
+       return SASL_BADPARAM;
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG,
+                       "SRP server step %d\n", text->state);
+    
+    *serverout = NULL;
+    *serveroutlen = 0;
+       
+    switch (text->state) {
+
+    case 1:
+       return srp_server_mech_step1(text, sparams, clientin, clientinlen,
+                                    serverout, serveroutlen, oparams);
+
+    case 2:
+       return srp_server_mech_step2(text, sparams, clientin, clientinlen,
+                                    serverout, serveroutlen, oparams);
+
+    default:
+       sparams->utils->seterror(sparams->utils->conn, 0,
+                                "Invalid SRP server step %d", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+#ifdef DO_SRP_SETPASS
+static int srp_setpass(void *glob_context __attribute__((unused)),
+                      sasl_server_params_t *sparams,
+                      const char *userstr,
+                      const char *pass,
+                      unsigned passlen __attribute__((unused)),
+                      const char *oldpass __attribute__((unused)),
+                      unsigned oldpasslen __attribute__((unused)),
+                      unsigned flags)
+{
+    int r;
+    char *user = NULL;
+    char *user_only = NULL;
+    char *realm = NULL;
+    sasl_secret_t *sec = NULL;
+    struct propctx *propctx = NULL;
+    const char *store_request[] = { "cmusaslsecretSRP",
+                                    NULL };
+    
+    /* Do we have a backend that can store properties? */
+    if (!sparams->utils->auxprop_store ||
+       sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) {
+       SETERROR(sparams->utils, "SRP: auxprop backend can't store properties");
+       return SASL_NOMECH;
+    }
+    
+    /* NB: Ideally we need to canonicalize userstr here */
+    r = _plug_parseuser(sparams->utils, &user_only, &realm, sparams->user_realm,
+                       sparams->serverFQDN, userstr);
+
+    if (r) {
+       sparams->utils->seterror(sparams->utils->conn, 0, 
+                                "Error parsing user");
+       return r;
+    }
+
+    r = _plug_make_fulluser(sparams->utils, &user, user_only, realm);
+
+    if (r) {
+       goto end;
+    }
+
+    if ((flags & SASL_SET_DISABLE) || pass == NULL) {
+       sec = NULL;
+    } else {
+       context_t *text;
+       BIGNUM N;
+       BIGNUM g;
+       BIGNUM v;
+       char *salt;
+       int saltlen;
+       char *buffer = NULL;
+       int bufferlen, alloclen, encodelen;
+       
+       text = sparams->utils->malloc(sizeof(context_t));
+       if (text == NULL) {
+           MEMERROR(sparams->utils);
+           return SASL_NOMEM;
+       }
+       
+       memset(text, 0, sizeof(context_t));
+       
+       text->utils = sparams->utils;
+       text->md = EVP_get_digestbyname(server_mda->evp_name);
+       
+       r = generate_N_and_g(&N, &g);
+       if (r) {
+           sparams->utils->seterror(sparams->utils->conn, 0, 
+                                    "Error calculating N and g");
+           goto end;
+       }
+
+       /* user is a full username here */
+       r = CalculateV(text, &N, &g, user, pass, passlen, &v, &salt, &saltlen);
+       if (r) {
+           sparams->utils->seterror(sparams->utils->conn, 0, 
+                                    "Error calculating v");
+           goto end;
+       }
+       
+       /* The secret data is stored as suggested in RFC 2945:
+        *
+        *  { utf8(mda) mpi(v) os(salt) }  (base64 encoded)
+        */
+       
+       r = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
+                      &bufferlen, "%s%m%o",
+                      server_mda->name, &v, saltlen, salt);
+       
+       if (r) {
+           sparams->utils->seterror(sparams->utils->conn, 0, 
+                                    "Error making buffer for secret");
+           goto end;
+       }
+       buffer = text->out_buf;
+       
+       /* Put 'buffer' into sasl_secret_t.
+        * This will be base64 encoded, so make sure its big enough.
+        */
+       alloclen = (bufferlen/3 + 1) * 4 + 1;
+       sec = sparams->utils->malloc(sizeof(sasl_secret_t)+alloclen);
+       if (!sec) {
+           r = SASL_NOMEM;
+           goto end;
+       }
+       sparams->utils->encode64(buffer, bufferlen, sec->data, alloclen,
+                                &encodelen);
+       sec->len = encodelen;
+       
+       /* Clean everything up */
+      end:
+       if (buffer) sparams->utils->free((void *) buffer);
+       BN_clear_free(&N);
+       BN_clear_free(&g);
+       BN_clear_free(&v);
+       sparams->utils->free(text);
+       
+       if (r) return r;
+    }
+    
+    /* do the store */
+    propctx = sparams->utils->prop_new(0);
+    if (!propctx)
+       r = SASL_FAIL;
+    if (!r)
+       r = sparams->utils->prop_request(propctx, store_request);
+    if (!r)
+       r = sparams->utils->prop_set(propctx, "cmusaslsecretSRP",
+                                    (sec ? sec->data : NULL),
+                                    (sec ? sec->len : 0));
+    if (!r)
+       r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user);
+    if (propctx)
+       sparams->utils->prop_dispose(&propctx);
+    
+    if (r) {
+       sparams->utils->seterror(sparams->utils->conn, 0, 
+                                "Error putting SRP secret");
+       goto cleanup;
+    }
+    
+    sparams->utils->log(NULL, SASL_LOG_DEBUG, "Setpass for SRP successful\n");
+    
+  cleanup:
+    
+    if (user)  _plug_free_string(sparams->utils, &user);
+    if (user_only)     _plug_free_string(sparams->utils, &user_only);
+    if (realm)         _plug_free_string(sparams->utils, &realm);
+    if (sec)    _plug_free_secret(sparams->utils, &sec);
+    
+    return r;
+}
+#endif /* DO_SRP_SETPASS */
+
+static int srp_mech_avail(void *glob_context __attribute__((unused)),
+                         sasl_server_params_t *sparams,
+                         void **conn_context __attribute__((unused))) 
+{
+    /* Do we have access to the selected MDA? */
+    if (!server_mda || !server_mda->enabled) {
+       SETERROR(sparams->utils,
+                "SRP unavailable due to selected MDA unavailable");
+       return SASL_NOMECH;
+    }
+    
+    return SASL_OK;
+}
+
+static sasl_server_plug_t srp_server_plugins[] = 
+{
+    {
+       "SRP",                          /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NODICTIONARY
+       | SASL_SEC_FORWARD_SECRECY
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* glob_context */
+       &srp_server_mech_new,           /* mech_new */
+       &srp_server_mech_step,          /* mech_step */
+       &srp_common_mech_dispose,       /* mech_dispose */
+       &srp_common_mech_free,          /* mech_free */
+#ifdef DO_SRP_SETPASS
+       &srp_setpass,                   /* setpass */
+#else
+       NULL,
+#endif
+       NULL,                           /* user_query */
+       NULL,                           /* idle */
+       &srp_mech_avail,                /* mech avail */
+       NULL                            /* spare */
+    }
+};
+
+int srp_server_plug_init(const sasl_utils_t *utils,
+                        int maxversion,
+                        int *out_version,
+                        const sasl_server_plug_t **pluglist,
+                        int *plugcount,
+                        const char *plugname __attribute__((unused)))
+{
+    const char *mda;
+    unsigned int len;
+    layer_option_t *opts;
+    
+    if (maxversion < SASL_SERVER_PLUG_VERSION) {
+       SETERROR(utils, "SRP version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    utils->getopt(utils->getopt_context, "SRP", "srp_mda", &mda, &len);
+    if (!mda) mda = DEFAULT_MDA;
+    
+    /* Add all digests and ciphers */
+    OpenSSL_add_all_algorithms();
+    
+    /* See which digests we have available and set max_ssf accordingly */
+    opts = digest_options;
+    while (opts->name) {
+       if (EVP_get_digestbyname(opts->evp_name)) {
+           opts->enabled = 1;
+           
+           srp_server_plugins[0].max_ssf = opts->ssf;
+       }
+       
+       /* Locate the server MDA */
+       if (!strcasecmp(opts->name, mda) || !strcasecmp(opts->evp_name, mda)) {
+           server_mda = opts;
+       }
+       
+       opts++;
+    }
+    
+    /* See which ciphers we have available and set max_ssf accordingly */
+    opts = cipher_options;
+    while (opts->name) {
+       if (EVP_get_cipherbyname(opts->evp_name)) {
+           opts->enabled = 1;
+           
+           if (opts->ssf > srp_server_plugins[0].max_ssf) {
+               srp_server_plugins[0].max_ssf = opts->ssf;
+           }
+       }
+       
+       opts++;
+    }
+    
+    *out_version = SASL_SERVER_PLUG_VERSION;
+    *pluglist = srp_server_plugins;
+    *plugcount = 1;
+    
+    return SASL_OK;
+}
+
+/*****************************  Client Section  *****************************/
+
+/* Check to see if N,g is in the recommended list */
+static int check_N_and_g(const sasl_utils_t *utils, BIGNUM *N, BIGNUM *g)
+{
+    char *N_prime;
+    unsigned long g_prime;
+    unsigned i;
+    int r = SASL_FAIL;
+    
+    N_prime = BN_bn2hex(N);
+    g_prime = BN_get_word(g);
+    
+    for (i = 0; i < NUM_Ng; i++) {
+       if (!strcasecmp(N_prime, Ng_tab[i].N) && (g_prime == Ng_tab[i].g)) {
+           r = SASL_OK;
+           break;
+       }
+    }
+    
+    if (N_prime) utils->free(N_prime);
+    
+    return r;
+}
+
+static int CalculateA(context_t *text  __attribute__((unused)),
+                     BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A)
+{
+    BN_CTX *ctx = BN_CTX_new();
+    
+    /* Generate a */
+    GetRandBigInt(a);
+       
+    /* Per [SRP]: make sure a > log[g](N) -- g is always 2 */
+    BN_add_word(a, BN_num_bits(N));
+       
+    /* A = g^a % N */
+    BN_init(A);
+    BN_mod_exp(A, g, a, N, ctx);
+
+    BN_CTX_free(ctx);
+    
+    return SASL_OK;
+}
+       
+static int ClientCalculateK(context_t *text, char *salt, int saltlen,
+                           char *user, char *pass, int passlen,
+                           BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A,
+                           BIGNUM *B, char *K, int *Klen)
+{
+    int r;
+    unsigned char hash[EVP_MAX_MD_SIZE];
+    int hashlen;
+    BIGNUM x;
+    BIGNUM u;
+    BIGNUM aux;
+    BIGNUM gx;
+    BIGNUM gx3;
+    BIGNUM base;
+    BIGNUM S;
+    BN_CTX *ctx = BN_CTX_new();
+    
+    /* u = H(A | B) */
+    r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B);
+    if (r) goto err;
+    BN_init(&u);
+    BN_bin2bn(hash, hashlen, &u);
+    
+    /* per Tom Wu: make sure u != 0 */
+    if (BN_is_zero(&u)) {
+       SETERROR(text->utils, "SRP: Illegal value for 'u'\n");
+       r = SASL_BADPROT;
+       goto err;
+    }
+    
+    /* S = (B - 3(g^x)) ^ (a + ux) % N */
+
+    r = CalculateX(text, salt, saltlen, user, pass, passlen, &x);
+    if (r) return r;
+    
+    /* a + ux */
+    BN_init(&aux);
+    BN_mul(&aux, &u, &x, ctx);
+    BN_add(&aux, &aux, a);
+    
+    /* gx3 = 3(g^x) % N */
+    BN_init(&gx);
+    BN_mod_exp(&gx, g, &x, N, ctx);
+    BN_init(&gx3);
+    BN_set_word(&gx3, 3);
+    BN_mod_mul(&gx3, &gx3, &gx, N, ctx);
+    
+    /* base = (B - 3(g^x)) % N */
+    BN_init(&base);
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+    BN_mod_sub(&base, B, &gx3, N, ctx);
+#else
+    BN_sub(&base, B, &gx3);
+    BN_mod(&base, &base, N, ctx);
+    if (BigIntCmpWord(&base, 0) < 0) {
+       BN_add(&base, &base, N);
+    }
+#endif
+    
+    /* S = base^aux % N */
+    BN_init(&S);
+    BN_mod_exp(&S, &base, &aux, N, ctx);
+    
+    /* K = H(S) */
+    r = MakeHash(text->md, K, Klen, "%m", &S);
+    if (r) goto err;
+    
+    r = SASL_OK;
+    
+  err:
+    BN_CTX_free(ctx);
+    BN_clear_free(&x);
+    BN_clear_free(&u);
+    BN_clear_free(&aux);
+    BN_clear_free(&gx);
+    BN_clear_free(&gx3);
+    BN_clear_free(&base);
+    BN_clear_free(&S);
+    
+    return r;
+}
+
+static int CreateClientOpts(sasl_client_params_t *params, 
+                           srp_options_t *available, 
+                           srp_options_t *out)
+{
+    layer_option_t *opt;
+    sasl_ssf_t external;
+    sasl_ssf_t limit;
+    sasl_ssf_t musthave;
+    
+    /* zero out output */
+    memset(out, 0, sizeof(srp_options_t));
+    
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "Available MDA = %d\n", available->mda);
+    
+    /* mda */
+    opt = FindBest(available->mda, 0, 256, digest_options);
+    
+    if (opt) {
+       out->mda = opt->bit;
+    }
+    else {
+       SETERROR(params->utils, "Can't find an acceptable SRP MDA\n");
+       return SASL_BADAUTH;
+    }
+    
+    /* get requested ssf */
+    external = params->external_ssf;
+    
+    /* what do we _need_?  how much is too much? */
+    if(params->props.maxbufsize == 0) {
+       musthave = 0;
+       limit = 0;
+    } else {
+       if (params->props.max_ssf > external) {
+           limit = params->props.max_ssf - external;
+       } else {
+           limit = 0;
+       }
+       if (params->props.min_ssf > external) {
+           musthave = params->props.min_ssf - external;
+       } else {
+           musthave = 0;
+       }
+    }
+        
+    /* we now go searching for an option that gives us at least "musthave"
+       and at most "limit" bits of ssf. */
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "Available confidentiality = %d  "
+                      "musthave = %d  limit = %d",
+                      available->confidentiality, musthave, limit);
+    
+    /* confidentiality */
+    if (limit > 1) {
+       
+       opt = FindBest(available->confidentiality, musthave, limit,
+                      cipher_options);
+       
+       if (opt) {
+           out->confidentiality = opt->bit;
+           /* we've already satisfied the SSF with the confidentiality
+            * layer, but we'll also use an integrity layer if we can
+            */
+           musthave = 0;
+       }
+       else if (musthave > 1) {
+           SETERROR(params->utils,
+                    "Can't find an acceptable SRP confidentiality layer\n");
+           return SASL_TOOWEAK;
+       }
+    }
+    
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "Available integrity = %d "
+                      "musthave = %d  limit = %d",
+                      available->integrity, musthave, limit);
+    
+    /* integrity */
+    if ((limit >= 1) && (musthave <= 1)) {
+       
+       opt = FindBest(available->integrity, musthave, limit,
+                      digest_options);
+       
+       if (opt) {
+           out->integrity = opt->bit;
+           
+           /* if we set an integrity option we can set replay detection */
+           out->replay_detection = available->replay_detection;
+       }
+       else if (musthave > 0) {
+           SETERROR(params->utils,
+                    "Can't find an acceptable SRP integrity layer\n");
+           return SASL_TOOWEAK;
+       }
+    }
+    
+    /* Check to see if we've satisfied all of the servers mandatory layers */
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "Mandatory layers = %d\n",available->mandatory);
+    
+    if ((!out->replay_detection &&
+        (available->mandatory & BIT_REPLAY_DETECTION)) ||
+       (!out->integrity &&
+        (available->mandatory & BIT_INTEGRITY)) ||
+       (!out->confidentiality &&
+        (available->mandatory & BIT_CONFIDENTIALITY))) {
+       SETERROR(params->utils, "Mandatory SRP layer not supported\n");
+       return SASL_BADAUTH;
+    }
+    
+    /* Add maxbuffersize */
+    out->maxbufsize = SRP_MAXBUFFERSIZE;
+    if (params->props.maxbufsize && params->props.maxbufsize < out->maxbufsize)
+       out->maxbufsize = params->props.maxbufsize;
+    
+    return SASL_OK;
+}
+
+static int srp_client_mech_new(void *glob_context __attribute__((unused)),
+                              sasl_client_params_t *params,
+                              void **conn_context)
+{
+    context_t *text;
+    
+    /* holds state are in */
+    text = params->utils->malloc(sizeof(context_t));
+    if (text == NULL) {
+       MEMERROR( params->utils );
+       return SASL_NOMEM;
+    }
+    
+    memset(text, 0, sizeof(context_t));
+    
+    text->state = 1;
+    text->utils = params->utils;
+
+    *conn_context = text;
+    
+    return SASL_OK;
+}
+
+static int
+srp_client_mech_step1(context_t *text,
+                     sasl_client_params_t *params,
+                     const char *serverin __attribute__((unused)),
+                     unsigned serverinlen,
+                     sasl_interact_t **prompt_need,
+                     const char **clientout,
+                     unsigned *clientoutlen,
+                     sasl_out_params_t *oparams)
+{
+    const char *authid = NULL, *userid = NULL;
+    int auth_result = SASL_OK;
+    int pass_result = SASL_OK;
+    int user_result = SASL_OK;
+    int result;
+    
+    /* Expect: 
+     *   absolutely nothing
+     * 
+     */
+    if (serverinlen > 0) {
+       SETERROR(params->utils, "Invalid input to first step of SRP\n");
+       return SASL_BADPROT;
+    }
+    
+    /* try to get the authid */
+    if (oparams->authid==NULL) {
+       auth_result = _plug_get_authid(params->utils, &authid, prompt_need);
+       
+       if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT))
+           return auth_result;
+    }
+    
+    /* try to get the userid */
+    if (oparams->user == NULL) {
+       user_result = _plug_get_userid(params->utils, &userid, prompt_need);
+       
+       if ((user_result != SASL_OK) && (user_result != SASL_INTERACT))
+           return user_result;
+    }
+    
+    /* try to get the password */
+    if (text->password == NULL) {
+       pass_result=_plug_get_password(params->utils, &text->password,
+                                      &text->free_password, prompt_need);
+           
+       if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT))
+           return pass_result;
+    }
+    
+    /* free prompts we got */
+    if (prompt_need && *prompt_need) {
+       params->utils->free(*prompt_need);
+       *prompt_need = NULL;
+    }
+    
+    /* if there are prompts not filled in */
+    if ((auth_result == SASL_INTERACT) || (user_result == SASL_INTERACT) ||
+       (pass_result == SASL_INTERACT)) {
+       /* make the prompt list */
+       result =
+           _plug_make_prompts(params->utils, prompt_need,
+                              user_result == SASL_INTERACT ?
+                              "Please enter your authorization name" : NULL,
+                              NULL,
+                              auth_result == SASL_INTERACT ?
+                              "Please enter your authentication name" : NULL,
+                              NULL,
+                              pass_result == SASL_INTERACT ?
+                              "Please enter your password" : NULL, NULL,
+                              NULL, NULL, NULL,
+                              NULL, NULL, NULL);
+       if (result != SASL_OK) return result;
+           
+       return SASL_INTERACT;
+    }
+    
+    if (!userid || !*userid) {
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams);
+    }
+    else {
+       result = params->canon_user(params->utils->conn, authid, 0,
+                                   SASL_CU_AUTHID, oparams);
+       if (result != SASL_OK) return result;
+
+       result = params->canon_user(params->utils->conn, userid, 0,
+                                   SASL_CU_AUTHZID, oparams);
+    }
+    if (result != SASL_OK) return result;
+    
+    /* Send out:
+     *
+     * U - authentication identity 
+     * I - authorization identity
+     * sid - previous session id
+     * cn - client nonce
+     *
+     * { utf8(U) utf8(I) utf8(sid) os(cn) }
+     */
+    result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
+                       clientoutlen, "%s%s%s%o",
+                       (char *) oparams->authid, (char *) oparams->user,
+                       "", 0, "");
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+    *clientout = text->out_buf;
+    
+    text->state = 2;
+
+    result = SASL_CONTINUE;
+    
+  cleanup:
+    
+    return result;
+}
+
+static int
+srp_client_mech_step2(context_t *text,
+                     sasl_client_params_t *params,
+                     const char *serverin,
+                     unsigned serverinlen,
+                     sasl_interact_t **prompt_need __attribute__((unused)),
+                     const char **clientout,
+                     unsigned *clientoutlen,
+                     sasl_out_params_t *oparams)
+{
+    int result;
+    char reuse;
+    srp_options_t server_opts;
+    
+    /* Expect:
+     *
+     *  { 0x00 mpi(N) mpi(g) os(s) mpi(B) utf8(L) }
+     */
+    result = UnBuffer(params->utils, serverin, serverinlen,
+                     "%c%m%m%o%m%s", &reuse, &text->N, &text->g,
+                     &text->saltlen, &text->salt, &text->B,
+                     &text->server_options);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 2");
+       goto cleanup;
+    }
+
+    /* Check N and g to see if they are one of the recommended pairs */
+    result = check_N_and_g(params->utils, &text->N, &text->g);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Values of 'N' and 'g' are not recommended\n");
+       goto cleanup;
+    }
+    
+    /* Per [SRP]: reject B <= 0, B >= N */
+    if (BigIntCmpWord(&text->B, 0) <= 0 || BN_cmp(&text->B, &text->N) >= 0) {
+       SETERROR(params->utils, "Illegal value for 'B'\n");
+       result = SASL_BADPROT;
+       goto cleanup;
+    }
+
+    /* parse server options */
+    memset(&server_opts, 0, sizeof(srp_options_t));
+    result = ParseOptions(params->utils, text->server_options, &server_opts, 0);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error parsing SRP server options\n");
+       goto cleanup;
+    }
+    
+    /* Create o */
+    result = CreateClientOpts(params, &server_opts, &text->client_opts);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error creating client options\n");
+       goto cleanup;
+    }
+    
+    result = OptionsToString(params->utils, &text->client_opts,
+                            &text->client_options);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error converting client options to an option string\n");
+       goto cleanup;
+    }
+
+    result = SetMDA(&text->client_opts, text);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error setting MDA");
+       goto cleanup;
+    }
+
+    /* Calculate A */
+    result = CalculateA(text, &text->N, &text->g, &text->a, &text->A);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error calculating A");
+       return result;
+    }
+    
+    /* Calculate shared context key K */
+    result = ClientCalculateK(text, text->salt, text->saltlen,
+                             (char *) oparams->authid, 
+                             text->password->data, text->password->len,
+                             &text->N, &text->g, &text->a, &text->A, &text->B,
+                             text->K, &text->Klen);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error creating K\n");
+       goto cleanup;
+    }
+    
+    /* Calculate M1 (client evidence) */
+    result = CalculateM1(text, &text->N, &text->g, (char *) oparams->authid,
+                        text->salt, text->saltlen, &text->A, &text->B,
+                        text->K, text->Klen, (char *) oparams->user,
+                        text->server_options, text->M1, &text->M1len);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error creating M1\n");
+       goto cleanup;
+    }
+
+    /* Create cIV (client initial vector) */
+    text->utils->rand(text->utils->rpool, text->cIV, sizeof(text->cIV));
+    
+    /* Send out:
+     *
+     * A - client's public key
+     * M1 - client evidence
+     * o - client option list
+     * cIV - client initial vector
+     *
+     * { mpi(A) os(M1) utf8(o) os(cIV) }
+     */
+    result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len,
+                       clientoutlen, "%m%o%s%o",
+                       &text->A, text->M1len, text->M1, text->client_options,
+                       sizeof(text->cIV), text->cIV);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n");
+       goto cleanup;
+    }
+    *clientout = text->out_buf;
+    
+    text->state = 3;
+
+    result = SASL_CONTINUE;
+    
+  cleanup:
+    
+    return result;
+}
+
+static int
+srp_client_mech_step3(context_t *text,
+                     sasl_client_params_t *params,
+                     const char *serverin,
+                     unsigned serverinlen,
+                     sasl_interact_t **prompt_need __attribute__((unused)),
+                     const char **clientout __attribute__((unused)),
+                     unsigned *clientoutlen __attribute__((unused)),
+                     sasl_out_params_t *oparams)
+{
+    int result;    
+    char *M2 = NULL, *sIV = NULL; /* don't free */
+    char *sid = NULL;
+    int M2len, sIVlen;
+    uint32 ttl;
+    int i;
+    char myM2[EVP_MAX_MD_SIZE];
+    int myM2len;
+    
+    /* Expect:
+     *
+     * M2 - server evidence
+     * sIV - server initial vector
+     * sid - session id
+     * ttl - time to live
+     *
+     *   { os(M2) os(sIV) utf8(sid) uint(ttl) }
+     */
+    result = UnBuffer(params->utils, serverin, serverinlen,
+                     "%-o%-o%s%u", &M2len, &M2, &sIVlen, &sIV,
+                     &sid, &ttl);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error UnBuffering input in step 3");
+       goto cleanup;
+    }
+
+    /* calculate our own M2 */
+    result = CalculateM2(text, &text->A, text->M1, text->M1len,
+                        text->K, text->Klen, (char *) oparams->user,
+                        text->client_options, "", 0,
+                        myM2, &myM2len);
+    if (result) {
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Error calculating our own M2 (server evidence)\n");
+       goto cleanup;
+    }
+    
+    /* compare to see if is server spoof */
+    if (myM2len != M2len) {
+       SETERROR(params->utils, "SRP Server M2 length wrong\n");
+       result = SASL_BADSERV;
+       goto cleanup;
+    }
+    
+    
+    for (i = 0; i < myM2len; i++) {
+       if (M2[i] != myM2[i]) {
+           SETERROR(params->utils,
+                    "SRP Server spoof detected. M2 incorrect\n");
+           result = SASL_BADSERV;
+           goto cleanup;
+       }
+    }
+    
+    /*
+     * Send out: nothing
+     */
+
+    /* configure security layer */
+    result = LayerInit(&text->client_opts, text, oparams, sIV, text->cIV,
+                      params->props.maxbufsize);
+    if (result) {
+       params->utils->seterror(params->utils->conn, 0, 
+                               "Error initializing security layer");
+       return result;   
+    }
+
+    /* set oparams */
+    oparams->doneflag = 1;
+    oparams->param_version = 0;
+
+    result = SASL_OK;
+    
+  cleanup:
+    if (sid) params->utils->free(sid);
+    
+    return result;
+}
+
+static int srp_client_mech_step(void *conn_context,
+                               sasl_client_params_t *params,
+                               const char *serverin,
+                               unsigned serverinlen,
+                               sasl_interact_t **prompt_need,
+                               const char **clientout,
+                               unsigned *clientoutlen,
+                               sasl_out_params_t *oparams)
+{
+    context_t *text = (context_t *) conn_context;
+    
+    params->utils->log(NULL, SASL_LOG_DEBUG,
+                      "SRP client step %d\n", text->state);
+    
+    *clientout = NULL;
+    *clientoutlen = 0;
+    
+    switch (text->state) {
+
+    case 1:
+       return srp_client_mech_step1(text, params, serverin, serverinlen, 
+                                    prompt_need, clientout, clientoutlen,
+                                    oparams);
+
+    case 2:
+       return srp_client_mech_step2(text, params, serverin, serverinlen, 
+                                    prompt_need, clientout, clientoutlen,
+                                    oparams);
+
+    case 3:
+       return srp_client_mech_step3(text, params, serverin, serverinlen, 
+                                    prompt_need, clientout, clientoutlen,
+                                    oparams);
+
+    default:
+       params->utils->log(NULL, SASL_LOG_ERR,
+                          "Invalid SRP client step %d\n", text->state);
+       return SASL_FAIL;
+    }
+    
+    return SASL_FAIL; /* should never get here */
+}
+
+
+static sasl_client_plug_t srp_client_plugins[] = 
+{
+    {
+       "SRP",                          /* mech_name */
+       0,                              /* max_ssf */
+       SASL_SEC_NOPLAINTEXT
+       | SASL_SEC_NOANONYMOUS
+       | SASL_SEC_NOACTIVE
+       | SASL_SEC_NODICTIONARY
+       | SASL_SEC_FORWARD_SECRECY
+       | SASL_SEC_MUTUAL_AUTH,         /* security_flags */
+       SASL_FEAT_WANT_CLIENT_FIRST
+       | SASL_FEAT_ALLOWS_PROXY,       /* features */
+       NULL,                           /* required_prompts */
+       NULL,                           /* glob_context */
+       &srp_client_mech_new,           /* mech_new */
+       &srp_client_mech_step,          /* mech_step */
+       &srp_common_mech_dispose,       /* mech_dispose */
+       &srp_common_mech_free,          /* mech_free */
+       NULL,                           /* idle */
+       NULL,                           /* spare */
+       NULL                            /* spare */
+    }
+};
+
+int srp_client_plug_init(const sasl_utils_t *utils __attribute__((unused)),
+                        int maxversion,
+                        int *out_version,
+                        const sasl_client_plug_t **pluglist,
+                        int *plugcount,
+                        const char *plugname __attribute__((unused)))
+{
+    layer_option_t *opts;
+    
+    if (maxversion < SASL_CLIENT_PLUG_VERSION) {
+       SETERROR(utils, "SRP version mismatch");
+       return SASL_BADVERS;
+    }
+    
+    /* Add all digests and ciphers */
+    OpenSSL_add_all_algorithms();
+    
+    /* See which digests we have available and set max_ssf accordingly */
+    opts = digest_options;
+    while (opts->name) {
+       if (EVP_get_digestbyname(opts->evp_name)) {
+           opts->enabled = 1;
+           
+           srp_client_plugins[0].max_ssf = opts->ssf;
+       }
+       
+       opts++;
+    }
+    
+    /* See which ciphers we have available and set max_ssf accordingly */
+    opts = cipher_options;
+    while (opts->name) {
+       if (EVP_get_cipherbyname(opts->evp_name)) {
+           opts->enabled = 1;
+           
+           if (opts->ssf > srp_client_plugins[0].max_ssf) {
+               srp_client_plugins[0].max_ssf = opts->ssf;
+           }
+       }
+       
+       opts++;
+    }
+    
+    *out_version = SASL_CLIENT_PLUG_VERSION;
+    *pluglist = srp_client_plugins;
+    *plugcount=1;
+    
+    return SASL_OK;
+}
diff --git a/plugins/srp_init.c b/plugins/srp_init.c
new file mode 100644 (file)
index 0000000..305dcb3
--- /dev/null
@@ -0,0 +1,43 @@
+
+#include <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifndef macintosh
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <assert.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include <saslutil.h>
+
+#include "plugin_common.h"
+
+#ifdef macintosh
+#include <sasl_srp_plugin_decl.h>
+#endif
+
+#ifdef WIN32
+BOOL APIENTRY DllMain( HANDLE hModule, 
+                       DWORD  ul_reason_for_call, 
+                       LPVOID lpReserved
+                                        )
+{
+    switch (ul_reason_for_call)
+       {
+               case DLL_PROCESS_ATTACH:
+               case DLL_THREAD_ATTACH:
+               case DLL_THREAD_DETACH:
+               case DLL_PROCESS_DETACH:
+                       break;
+    }
+    return TRUE;
+}
+#endif
+
+SASL_CLIENT_PLUG_INIT( srp )
+SASL_SERVER_PLUG_INIT( srp )
+
diff --git a/pwcheck/Makefile.am b/pwcheck/Makefile.am
new file mode 100644 (file)
index 0000000..8c9fc09
--- /dev/null
@@ -0,0 +1,32 @@
+# Makefile.am for the pwcheck daemon
+# Larry Greenfield
+#
+#         Copyright 1999 by Carnegie Mellon University
+#
+#                       All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of CMU not be
+# used in advertising or publicity pertaining to distribution of the
+# software without specific, written prior permission.
+#
+# CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+# CMU 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.
+#
+
+sbin_PROGRAMS = pwcheck
+
+INCLUDES = -I../include -I../lib
+
+pwcheck_SOURCES = pwcheck.c
+EXTRA_pwcheck_SOURCES = pwcheck_getpwnam.c pwcheck_getspnam.c
+pwcheck_DEPENDECIES = pwcheck_@PWCHECKMETH@.lo
+pwcheck_LDADD = pwcheck_@PWCHECKMETH@.lo @LIB_CRYPT@ @LIB_SOCKET@
diff --git a/pwcheck/Makefile.in b/pwcheck/Makefile.in
new file mode 100644 (file)
index 0000000..7cedcf6
--- /dev/null
@@ -0,0 +1,525 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the pwcheck daemon
+# Larry Greenfield
+#
+#         Copyright 1999 by Carnegie Mellon University
+#
+#                       All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies and that
+# both that copyright notice and this permission notice appear in
+# supporting documentation, and that the name of CMU not be
+# used in advertising or publicity pertaining to distribution of the
+# software without specific, written prior permission.
+#
+# CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+# CMU 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.
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+sbin_PROGRAMS = pwcheck
+
+INCLUDES = -I../include -I../lib
+
+pwcheck_SOURCES = pwcheck.c
+EXTRA_pwcheck_SOURCES = pwcheck_getpwnam.c pwcheck_getspnam.c
+pwcheck_DEPENDECIES = pwcheck_@PWCHECKMETH@.lo
+pwcheck_LDADD = pwcheck_@PWCHECKMETH@.lo @LIB_CRYPT@ @LIB_SOCKET@
+subdir = pwcheck
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+sbin_PROGRAMS = pwcheck$(EXEEXT)
+PROGRAMS = $(sbin_PROGRAMS)
+
+am_pwcheck_OBJECTS = pwcheck.$(OBJEXT)
+pwcheck_OBJECTS = $(am_pwcheck_OBJECTS)
+pwcheck_DEPENDENCIES = pwcheck_@PWCHECKMETH@.lo
+pwcheck_LDFLAGS =
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/pwcheck.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pwcheck_getpwnam.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pwcheck_getspnam.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(pwcheck_SOURCES) $(EXTRA_pwcheck_SOURCES)
+DIST_COMMON = README $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(pwcheck_SOURCES) $(EXTRA_pwcheck_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  pwcheck/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(sbindir)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+            || test -f $$p1 \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-sbinPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
+         rm -f $(DESTDIR)$(sbindir)/$$f; \
+       done
+
+clean-sbinPROGRAMS:
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+pwcheck$(EXEEXT): $(pwcheck_OBJECTS) $(pwcheck_DEPENDENCIES) 
+       @rm -f pwcheck$(EXEEXT)
+       $(LINK) $(pwcheck_LDFLAGS) $(pwcheck_OBJECTS) $(pwcheck_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwcheck.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwcheck_getpwnam.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwcheck_getspnam.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(sbindir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-sbinPROGRAMS ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-sbinPROGRAMS install-strip installcheck installcheck-am \
+       installdirs maintainer-clean maintainer-clean-generic \
+       mostlyclean mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+       uninstall-am uninstall-info-am uninstall-sbinPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/pwcheck/README b/pwcheck/README
new file mode 100644 (file)
index 0000000..8c5db69
--- /dev/null
@@ -0,0 +1,45 @@
+Pwcheck is a daemon for permitting the SASL library to check passwords
+against the shadow password database.
+
+To use:
+
+* Configure the Cyrus SASL library with the "--with-pwcheck" switch.
+
+* Compile and install the Cyrus SASL library software
+
+* Create the directory "/var/pwcheck" and make it readable by only
+those users who need to be able to verify passwords.  For instance, if
+you wish to use pwcheck with Cyrus imapd:
+
+       mkdir /var/pwcheck
+       chown cyrus /var/pwcheck
+       chmod 700 /var/pwcheck
+
+* Configure your applications to use "pwcheck_method: pwcheck". For 
+  example, if you are using this with the Cyrus IMAP server, you can
+  put in the imapd.conf the following line:
+
+       sasl_pwcheck_method: pwcheck
+  or for an application that doesn't overload its configuration file,
+  you could put the following line in its configuration file located
+  in /usr/lib/sasl (e.g. /usr/lib/<app_name>.conf): 
+
+       pwcheck_method: pwcheck
+
+* Upon system startup, arrange for the daemon $prefix/sbin/pwcheck
+to be run as root in the background.
+
+How it works:
+
+The Cyrus servers connect to the unix-domain socket
+/var/pwcheck/pwcheck to send a potential user's userid and password to
+the pwcheck daemon.  The pwcheck daemon uses its root privileges to
+verify the userid and password against the shadow password database.
+The pwcheck daemon then returns an error message or "OK" to the Cyrus
+server and closes the unix-domain connection.
+
+The permissions on the /var/pwcheck directory control who can connect
+to the pwcheck daemon.  The pwcheck daemon is not designed to deal
+with denial-of-service attacks from its clients, so the directory
+should be restricted to trustworthy server processes.
diff --git a/pwcheck/pwcheck.c b/pwcheck/pwcheck.c
new file mode 100644 (file)
index 0000000..38d66fb
--- /dev/null
@@ -0,0 +1,255 @@
+/* pwcheck.c -- Unix pwcheck daemon
+   $Id: pwcheck.c,v 1.8 2001/12/04 02:06:51 rjs3 Exp $
+Copyright 1998, 1999 Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon
+University not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+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.
+******************************************************************/
+
+#include <config.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <syslog.h>
+
+#if !defined(_PATH_PWCHECKPID)
+#ifdef _PATH_VARRUN
+# define _PATH_PWCHECKPID (_PATH_VARRUN "pwcheck.pid")
+#else
+# define _PATH_PWCHECKPID (NULL)
+#endif
+#endif
+
+void newclient(int);
+int retry_write(int, const char *, unsigned int);
+
+/*
+ * Unix pwcheck daemon-authenticated login (shadow password)
+ */
+
+int
+main()
+{
+    char fnamebuf[MAXPATHLEN];
+    int s;
+    int c;
+    int count;
+    int rc;
+    struct sockaddr_un srvaddr;
+    struct sockaddr_un clientaddr;
+    int r;
+    int len;
+    mode_t oldumask;
+    char *pid_file = _PATH_PWCHECKPID;
+    FILE *fp = NULL;
+    pid_t pid;
+
+    openlog("pwcheck", LOG_NDELAY, LOG_AUTH);
+
+    /* Daemonize. */
+    count = 5;
+    while (count--) {
+       pid = fork();
+            
+       if (pid > 0)
+           _exit(0);               /* parent dies */
+            
+       if ((pid == -1) && (errno == EAGAIN)) {
+           syslog(LOG_WARNING, "master fork failed (sleeping): %m");
+           sleep(5);
+           continue;
+       }
+    }
+    if (pid == -1) {
+       rc = errno;
+       syslog(LOG_ERR, "FATAL: master fork failed: %m");
+       fprintf(stderr, "pwcheck: ");
+       errno = rc;
+       perror("fork");
+       exit(1);
+    }
+
+    /*
+     * We're now running in the child. Lose our controlling terminal
+     * and obtain a new process group.
+     */
+    if (setsid() == -1) {
+       rc = errno;
+       syslog(LOG_ERR, "FATAL: setsid: %m");
+       fprintf(stderr, "pwcheck: ");
+       errno = rc;
+       perror("setsid");
+       exit(1);
+    }
+        
+    s = open("/dev/null", O_RDWR, 0);
+    if (s == -1) {
+       rc = errno;
+       syslog(LOG_ERR, "FATAL: /dev/null: %m");
+       fprintf(stderr, "pwcheck: ");
+       errno = rc;
+       perror("/dev/null");
+       exit(1);
+            
+    }
+    dup2(s, fileno(stdin));
+    dup2(s, fileno(stdout));
+    dup2(s, fileno(stderr));
+    if (s > 2) {
+       close(s);
+    }
+
+    /*
+     *   Record process ID - shamelessly stolen from inetd (I.V.)
+     */
+    pid = getpid();
+    if (pid_file) {
+       fp = fopen(pid_file, "w");
+    }
+    if (fp) {
+        fprintf(fp, "%ld\n", (long)pid);
+        fclose(fp);
+    } else if (pid_file) {
+        syslog(LOG_WARNING, "%s: %m", pid_file);
+    }
+
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s == -1) {
+       perror("socket");
+       exit(1);
+    }
+
+    strncpy(fnamebuf, PWCHECKDIR, sizeof(fnamebuf));
+    strncpy(fnamebuf + sizeof(PWCHECKDIR)-1, "/pwcheck",
+           sizeof(fnamebuf) - sizeof(PWCHECKDIR));
+    fnamebuf[MAXPATHLEN-1] = '\0';
+
+    (void) unlink(fnamebuf);
+
+    memset((char *)&srvaddr, 0, sizeof(srvaddr));
+    srvaddr.sun_family = AF_UNIX;
+    strncpy(srvaddr.sun_path, fnamebuf, sizeof(srvaddr.sun_path));
+    /* Most systems make sockets 0777 no matter what you ask for.
+       Known exceptions are Linux and DUX. */
+    oldumask = umask((mode_t) 0); /* for Linux, which observes the umask when
+                           setting up the socket */
+    r = bind(s, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
+    if (r == -1) {
+       syslog(LOG_ERR, "%.*s: %m",
+              sizeof(srvaddr.sun_path), srvaddr.sun_path);
+       exit(1);
+    }
+    umask(oldumask); /* for Linux */
+    chmod(fnamebuf, (mode_t) 0777); /* for DUX, where this isn't the default.
+                                   (harmlessly fails on some systems) */       
+    r = listen(s, 5);
+    if (r == -1) {
+       syslog(LOG_ERR, "listen: %m");
+       exit(1);
+    }
+
+    for (;;) {
+       len = sizeof(clientaddr);
+       c = accept(s, (struct sockaddr *)&clientaddr, &len);
+       if (c == -1 && errno != EINTR) {
+           syslog(LOG_WARNING, "accept: %m");
+           continue;
+       }
+
+       newclient(c);
+    }
+}
+
+void newclient(int c)
+{
+    char request[1024];
+    int n;
+    unsigned int start;
+    char *reply;
+    extern char *pwcheck();
+    
+    start = 0;
+    while (start < sizeof(request) - 1) {
+       n = read(c, request+start, sizeof(request) - 1 - start);
+       if (n < 1) {
+           reply = "Error reading request";
+           goto sendreply;
+       }
+               
+       start += n;
+
+       if (request[start-1] == '\0' && strlen(request) < start) {
+           break;
+       }
+    }
+
+    if (start >= sizeof(request) - 1) {
+       reply = "Request too big";
+    }
+    else {
+       reply = pwcheck(request, request + strlen(request) + 1);
+    }
+
+sendreply:
+
+    retry_write(c, reply, strlen(reply));
+    close(c);
+}
+  
+/*
+ * Keep calling the write() system call with 'fd', 'buf', and 'nbyte'
+ * until all the data is written out or an error occurs.
+ */
+int retry_write(int fd, const char *buf, unsigned int nbyte)
+{
+    int n;
+    int written = 0;
+
+    if (nbyte == 0)
+       return 0;
+
+    for (;;) {
+        n = write(fd, buf, nbyte);
+        if (n == -1) {
+            if (errno == EINTR)
+               continue;
+            return -1;
+        }
+
+        written += n;
+
+        if ((unsigned int) n >= nbyte)
+           return written;
+
+        buf += n;
+        nbyte -= n;
+    }
+}
diff --git a/pwcheck/pwcheck_getpwnam.c b/pwcheck/pwcheck_getpwnam.c
new file mode 100644 (file)
index 0000000..4b34222
--- /dev/null
@@ -0,0 +1,54 @@
+/* pwcheck_getpwnam.c -- check passwords using getpwname()
+   $Id: pwcheck_getpwnam.c,v 1.1 1999/08/26 16:22:43 leg Exp $
+
+Copyright 1998, 1999 Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon
+University not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+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.
+******************************************************************/
+
+#include <pwd.h>
+
+extern char *crypt();
+
+char *pwcheck(userid, password)
+char *userid;
+char *password;
+{
+    char* r;
+    struct passwd *pwd;
+
+    pwd = getpwnam(userid);
+    if (!pwd) {
+       r = "Userid not found";
+    }
+    else if (pwd->pw_passwd[0] == '*') {
+       r = "Account disabled";
+    }
+    else if (strcmp(pwd->pw_passwd, crypt(password, pwd->pw_passwd)) != 0) {
+       r = "Incorrect password";
+    }
+    else {
+       r = "OK";
+    }
+
+    endpwent();
+    
+    return r;
+}
diff --git a/pwcheck/pwcheck_getspnam.c b/pwcheck/pwcheck_getspnam.c
new file mode 100644 (file)
index 0000000..2b11286
--- /dev/null
@@ -0,0 +1,47 @@
+/* pwcheck_getspnam.c -- check passwords using getspnam()
+   $Id: pwcheck_getspnam.c,v 1.1 1999/08/26 16:22:44 leg Exp $
+
+Copyright 1998, 1999 Carnegie Mellon University
+
+                      All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Carnegie Mellon
+University not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+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.
+******************************************************************/
+
+#include <shadow.h>
+
+extern char *crypt();
+
+char *pwcheck(userid, password)
+char *userid;
+char *password;
+{
+    struct spwd *pwd;
+
+    pwd = getspnam(userid);
+    if (!pwd) {
+       return "Userid not found";
+    }
+    
+    if (strcmp(pwd->sp_pwdp, crypt(password, pwd->sp_pwdp)) != 0) {
+       return "Incorrect password";
+    }
+    else {
+       return "OK";
+    }
+}
diff --git a/sample/Makefile.am b/sample/Makefile.am
new file mode 100644 (file)
index 0000000..0e18483
--- /dev/null
@@ -0,0 +1,63 @@
+# Makefile.am -- automake input for sample SASL programs
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+INCLUDES=-I$(top_srcdir)/include
+
+noinst_PROGRAMS = client server
+EXTRA_PROGRAMS = sample-client sample-server
+CLEANFILES=sample-client sample-server ./.libs/*sample-client ./.libs/*sample-server
+
+sample_client_SOURCES = sample-client.c
+sample_server_SOURCES = sample-server.c
+
+server_SOURCES = server.c common.c common.h
+client_SOURCES = client.c common.c common.h
+
+server_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+client_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+
+sample_client_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+sample_server_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+
+EXTRA_DIST = NTMakefile
diff --git a/sample/Makefile.in b/sample/Makefile.in
new file mode 100644 (file)
index 0000000..f1a87d7
--- /dev/null
@@ -0,0 +1,559 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am -- automake input for sample SASL programs
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+INCLUDES = -I$(top_srcdir)/include
+
+noinst_PROGRAMS = client server
+EXTRA_PROGRAMS = sample-client sample-server
+CLEANFILES = sample-client sample-server ./.libs/*sample-client ./.libs/*sample-server
+
+sample_client_SOURCES = sample-client.c
+sample_server_SOURCES = sample-server.c
+
+server_SOURCES = server.c common.c common.h
+client_SOURCES = client.c common.c common.h
+
+server_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+client_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+
+sample_client_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+sample_server_LDADD = ../lib/libsasl2.la $(LIB_SOCKET)
+
+EXTRA_DIST = NTMakefile
+subdir = sample
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+EXTRA_PROGRAMS = sample-client$(EXEEXT) sample-server$(EXEEXT)
+noinst_PROGRAMS = client$(EXEEXT) server$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS)
+
+am_client_OBJECTS = client.$(OBJEXT) common.$(OBJEXT)
+client_OBJECTS = $(am_client_OBJECTS)
+client_DEPENDENCIES = ../lib/libsasl2.la
+client_LDFLAGS =
+am_sample_client_OBJECTS = sample-client.$(OBJEXT)
+sample_client_OBJECTS = $(am_sample_client_OBJECTS)
+sample_client_DEPENDENCIES = ../lib/libsasl2.la
+sample_client_LDFLAGS =
+am_sample_server_OBJECTS = sample-server.$(OBJEXT)
+sample_server_OBJECTS = $(am_sample_server_OBJECTS)
+sample_server_DEPENDENCIES = ../lib/libsasl2.la
+sample_server_LDFLAGS =
+am_server_OBJECTS = server.$(OBJEXT) common.$(OBJEXT)
+server_OBJECTS = $(am_server_OBJECTS)
+server_DEPENDENCIES = ../lib/libsasl2.la
+server_LDFLAGS =
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/client.Po ./$(DEPDIR)/common.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sample-client.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sample-server.Po ./$(DEPDIR)/server.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(client_SOURCES) $(sample_client_SOURCES) \
+       $(sample_server_SOURCES) $(server_SOURCES)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(client_SOURCES) $(sample_client_SOURCES) $(sample_server_SOURCES) $(server_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  sample/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+clean-noinstPROGRAMS:
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+client$(EXEEXT): $(client_OBJECTS) $(client_DEPENDENCIES) 
+       @rm -f client$(EXEEXT)
+       $(LINK) $(client_LDFLAGS) $(client_OBJECTS) $(client_LDADD) $(LIBS)
+sample-client$(EXEEXT): $(sample_client_OBJECTS) $(sample_client_DEPENDENCIES) 
+       @rm -f sample-client$(EXEEXT)
+       $(LINK) $(sample_client_LDFLAGS) $(sample_client_OBJECTS) $(sample_client_LDADD) $(LIBS)
+sample-server$(EXEEXT): $(sample_server_OBJECTS) $(sample_server_DEPENDENCIES) 
+       @rm -f sample-server$(EXEEXT)
+       $(LINK) $(sample_server_LDFLAGS) $(sample_server_OBJECTS) $(sample_server_LDADD) $(LIBS)
+server$(EXEEXT): $(server_OBJECTS) $(server_DEPENDENCIES) 
+       @rm -f server$(EXEEXT)
+       $(LINK) $(server_LDFLAGS) $(server_OBJECTS) $(server_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample-client.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample-server.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/server.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstPROGRAMS ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am info info-am install \
+       install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool pdf \
+       pdf-am ps ps-am tags uninstall uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sample/NTMakefile b/sample/NTMakefile
new file mode 100644 (file)
index 0000000..0c6ef8e
--- /dev/null
@@ -0,0 +1,103 @@
+!INCLUDE ..\win32\common.mak
+
+### Also:- client.exe server.exe
+sample_apps=sample-client.exe sample-server.exe
+sample_out=sample-client.pdb sample-server.pdb client.pdb server.pdb
+
+server_SOURCES = server.c common.c common.h
+client_SOURCES = client.c common.c common.h
+compat_sources = getaddrinfo.c getnameinfo.c
+sample_client_SOURCES = sample-client.c
+sample_server_SOURCES = sample-server.c
+
+common_objs = common.obj
+server_objs = server.obj
+client_objs = client.obj
+compat_objs = getaddrinfo.obj getnameinfo.obj
+sample_client_objs = sample-client.obj
+sample_server_objs = sample-server.obj
+
+!IF $(TARGET_WIN_SYSTEM) < 51
+common_objs = $(common_objs) $(compat_objs)
+!ENDIF 
+
+all_objs = $(common_objs) $(server_objs) $(client_objs) $(sample_client_objs) $(sample_server_objs)
+all_out = $(sample_apps) $(sample_out)
+
+DB_FLAGS = /I $(DB_INCLUDE)
+CPPFLAGS = /I "..\win32\include" /I "." /I "..\include" $(DB_FLAGS) /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL"
+CPPFLAGS = $(CPPFLAGS) /DNEED_GETOPT
+
+!IF $(TARGET_WIN_SYSTEM) >= 51
+CPPFLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(CPPFLAGS)
+!ENDIF 
+
+SASL_LIB=/libpath:"..\lib" libsasl.lib
+
+# EXTRA_LIBS is automatically included into LINK32EXE_FLAGS/LINK32DLL_FLAGS
+EXTRA_LIBS=$(SASL_LIB)
+
+# Where to install files from this directory
+bindir = $(prefix)\bin
+
+all : all-recursive
+
+#
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
+#
+# In order to force xcopy not to confirm if the second parameter is file or directory,
+# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
+# instead of libsasl.lib. Ugly, but works!
+#
+# Note, that we will copy all executabless here, not just $(sample_apps). This is a bug, but it allows
+# us to copy optionally built executables, which might not be in $(sample_apps). The latter is a feature.
+#
+install: $(sample_apps)
+       @xcopy *.exe $(bindir) /I /F /Y
+
+all-recursive : $(sample_apps)
+
+server.exe: $(server_objs) $(common_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"server.pdb" /out:"server.exe" $(server_objs) $(common_objs)
+<<
+
+client.exe: $(client_objs) $(common_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"client.pdb" /out:"client.exe" $(client_objs) $(common_objs)
+<<
+
+sample-server.exe: $(sample_server_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"sample-server.pdb" /out:"sample-server.exe" $(sample_server_objs)
+<<
+
+sample-client.exe: $(sample_client_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"sample-client.pdb" /out:"sample-client.exe" $(sample_client_objs)
+<<
+
+getaddrinfo.c: ..\lib\getaddrinfo.c
+       copy ..\lib\getaddrinfo.c .
+
+getnameinfo.c: ..\lib\getnameinfo.c
+       copy ..\lib\getnameinfo.c .
+
+CLEAN :
+       -@erase $(all_objs)
+       -@erase "*.idb"
+       -@erase "*.pch"
+       -@erase "*.pdb"
+       -@erase $(all_out)
+       -@erase getaddrinfo.c
+
+.c.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
diff --git a/sample/client.c b/sample/client.c
new file mode 100644 (file)
index 0000000..0ddb16c
--- /dev/null
@@ -0,0 +1,443 @@
+/* $Id: client.c,v 1.7 2004/03/09 17:35:32 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <assert.h>
+
+#include <sasl.h>
+
+#include "common.h"
+
+/* remove \r\n at end of the line */
+static void chop(char *s)
+{
+    char *p;
+
+    assert(s);
+    p = s + strlen(s) - 1;
+    if (p[0] == '\n') {
+       *p-- = '\0';
+    }
+    if (p >= s && p[0] == '\r') {
+       *p-- = '\0';
+    }
+}
+
+static int getrealm(void *context __attribute__((unused)), 
+                   int id,
+                   const char **availrealms,
+                   const char **result)
+{
+    static char buf[1024];
+
+    /* paranoia check */
+    if (id != SASL_CB_GETREALM) return SASL_BADPARAM;
+    if (!result) return SASL_BADPARAM;
+
+    printf("please choose a realm (available:");
+    while (*availrealms) {
+       printf(" %s", *availrealms);
+       availrealms++;
+    }
+    printf("): ");
+
+    fgets(buf, sizeof buf, stdin);
+    chop(buf);
+    *result = buf;
+  
+    return SASL_OK;
+}
+
+static int simple(void *context __attribute__((unused)),
+                 int id,
+                 const char **result,
+                 unsigned *len)
+{
+    static char buf[1024];
+
+    /* paranoia check */
+    if (! result)
+       return SASL_BADPARAM;
+
+    switch (id) {
+    case SASL_CB_USER:
+       printf("please enter an authorization id: ");
+       break;
+    case SASL_CB_AUTHNAME:
+       printf("please enter an authentication id: ");
+       break;
+    default:
+       return SASL_BADPARAM;
+    }
+
+    fgets(buf, sizeof buf, stdin);
+    chop(buf);
+    *result = buf;
+    if (len) *len = strlen(buf);
+  
+    return SASL_OK;
+}
+
+#ifndef HAVE_GETPASSPHRASE
+static char *
+getpassphrase(const char *prompt)
+{
+  return getpass(prompt);
+}
+#endif /* ! HAVE_GETPASSPHRASE */
+
+static int
+getsecret(sasl_conn_t *conn,
+         void *context __attribute__((unused)),
+         int id,
+         sasl_secret_t **psecret)
+{
+    char *password;
+    size_t len;
+    static sasl_secret_t *x;
+
+    /* paranoia check */
+    if (! conn || ! psecret || id != SASL_CB_PASS)
+       return SASL_BADPARAM;
+
+    password = getpassphrase("Password: ");
+    if (! password)
+       return SASL_FAIL;
+
+    len = strlen(password);
+
+    x = (sasl_secret_t *) realloc(x, sizeof(sasl_secret_t) + len);
+  
+    if (!x) {
+       memset(password, 0, len);
+       return SASL_NOMEM;
+    }
+
+    x->len = len;
+    strcpy(x->data, password);
+    memset(password, 0, len);
+    
+    *psecret = x;
+    return SASL_OK;
+}
+
+
+/* callbacks we support */
+static sasl_callback_t callbacks[] = {
+  {
+    SASL_CB_GETREALM, &getrealm, NULL
+  }, {
+    SASL_CB_USER, &simple, NULL
+  }, {
+    SASL_CB_AUTHNAME, &simple, NULL
+  }, {
+    SASL_CB_PASS, &getsecret, NULL
+  }, {
+    SASL_CB_LIST_END, NULL, NULL
+  }
+};
+
+int getconn(const char *host, const char *port)
+{
+    struct addrinfo hints, *ai, *r;
+    int err, sock = -1;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+
+    if ((err = getaddrinfo(host, port, &hints, &ai)) != 0) {
+       fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
+       exit(EX_UNAVAILABLE);
+    }
+
+    for (r = ai; r; r = r->ai_next) {
+       sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+       if (sock < 0)
+           continue;
+       if (connect(sock, r->ai_addr, r->ai_addrlen) >= 0)
+           break;
+       close(sock);
+       sock = -1;
+    }
+
+    freeaddrinfo(ai);
+    if (sock < 0) {
+       perror("connect");
+       exit(EX_UNAVAILABLE);
+    }
+
+    return sock;
+}
+
+char *mech;
+
+int mysasl_negotiate(FILE *in, FILE *out, sasl_conn_t *conn)
+{
+    char buf[8192];
+    const char *data;
+    const char *chosenmech;
+    int len;
+    int r, c;
+
+    /* get the capability list */
+    dprintf(0, "receiving capability list... ");
+    len = recv_string(in, buf, sizeof buf);
+    dprintf(0, "%s\n", buf);
+
+    if (mech) {
+       /* make sure that 'mech' appears in 'buf' */
+       if (!strstr(buf, mech)) {
+           printf("server doesn't offer mandatory mech '%s'\n", mech);
+           return -1;
+       }
+    } else {
+       mech = buf;
+    }
+
+    r = sasl_client_start(conn, mech, NULL, &data, &len, &chosenmech);
+    if (r != SASL_OK && r != SASL_CONTINUE) {
+       saslerr(r, "starting SASL negotiation");
+       printf("\n%s\n", sasl_errdetail(conn));
+       return -1;
+    }
+    
+    dprintf(1, "using mechanism %s\n", chosenmech);
+
+    /* we send up to 3 strings;
+       the mechanism chosen, the presence of initial response,
+       and optionally the initial response */
+    send_string(out, chosenmech, strlen(chosenmech));
+    if(data) {
+       send_string(out, "Y", 1);
+       send_string(out, data, len);
+    } else {
+       send_string(out, "N", 1);
+    }
+
+    for (;;) {
+       dprintf(2, "waiting for server reply...\n");
+
+       c = fgetc(in);
+       switch (c) {
+       case 'O':
+           goto done_ok;
+
+       case 'N':
+           goto done_no;
+
+       case 'C': /* continue authentication */
+           break;
+
+       default:
+           printf("bad protocol from server (%c %x)\n", c, c);
+           return -1;
+       }
+       len = recv_string(in, buf, sizeof buf);
+
+       r = sasl_client_step(conn, buf, len, NULL, &data, &len);
+       if (r != SASL_OK && r != SASL_CONTINUE) {
+           saslerr(r, "performing SASL negotiation");
+           printf("\n%s\n", sasl_errdetail(conn));
+           return -1;
+       }
+
+       if (data) {
+           dprintf(2, "sending response length %d...\n", len);
+           send_string(out, data, len);
+       } else {
+           dprintf(2, "sending null response...\n");
+           send_string(out, "", 0);
+       }
+    }
+
+ done_ok:
+    printf("successful authentication\n");
+    return 0;
+
+ done_no:
+    printf("authentication failed\n");
+    return -1;
+}
+
+void usage(void)
+{
+    fprintf(stderr, "usage: client [-p port] [-s service] [-m mech] host\n");
+    exit(EX_USAGE);
+}
+
+int main(int argc, char *argv[])
+{
+    int c;
+    char *host = "localhost";
+    char *port = "12345";
+    char localaddr[NI_MAXHOST + NI_MAXSERV],
+       remoteaddr[NI_MAXHOST + NI_MAXSERV];
+    char *service = "rcmd";
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    int r;
+    sasl_conn_t *conn;
+    FILE *in, *out;
+    int fd;
+    int salen;
+    int niflags, error;
+    struct sockaddr_storage local_ip, remote_ip;
+
+    while ((c = getopt(argc, argv, "p:s:m:")) != EOF) {
+       switch(c) {
+       case 'p':
+           port = optarg;
+           break;
+
+       case 's':
+           service = optarg;
+           break;
+
+       case 'm':
+           mech = optarg;
+           break;
+
+       default:
+           usage();
+           break;
+       }
+    }
+
+    if (optind > argc - 1) {
+       usage();
+    }
+    if (optind == argc - 1) {
+       host = argv[optind];
+    }
+
+    /* initialize the sasl library */
+    r = sasl_client_init(callbacks);
+    if (r != SASL_OK) saslfail(r, "initializing libsasl");
+
+    /* connect to remote server */
+    fd = getconn(host, port);
+
+    /* set ip addresses */
+    salen = sizeof(local_ip);
+    if (getsockname(fd, (struct sockaddr *)&local_ip, &salen) < 0) {
+       perror("getsockname");
+    }
+
+    niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+    if (((struct sockaddr *)&local_ip)->sa_family == AF_INET6)
+      niflags |= NI_WITHSCOPEID;
+#endif
+    error = getnameinfo((struct sockaddr *)&local_ip, salen,
+                       hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags);
+    if (error != 0) {
+       fprintf(stderr, "getnameinfo: %s\n", gai_strerror(error));
+       strcpy(hbuf, "unknown");
+       strcpy(pbuf, "unknown");
+    }
+    snprintf(localaddr, sizeof(localaddr), "%s;%s", hbuf, pbuf);
+
+    salen = sizeof(remote_ip);
+    if (getpeername(fd, (struct sockaddr *)&remote_ip, &salen) < 0) {
+       perror("getpeername");
+    }
+
+    niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+    if (((struct sockaddr *)&remote_ip)->sa_family == AF_INET6)
+       niflags |= NI_WITHSCOPEID;
+#endif
+    error = getnameinfo((struct sockaddr *)&remote_ip, salen,
+                       hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), niflags);
+    if (error != 0) {
+       fprintf(stderr, "getnameinfo: %s\n", gai_strerror(error));
+       strcpy(hbuf, "unknown");
+       strcpy(pbuf, "unknown");
+    }
+    snprintf(remoteaddr, sizeof(remoteaddr), "%s;%s", hbuf, pbuf);
+    
+    /* client new connection */
+    r = sasl_client_new(service, host, localaddr, remoteaddr, NULL, 0, &conn);
+    if (r != SASL_OK) saslfail(r, "allocating connection state");
+
+    /* set external properties here
+       sasl_setprop(conn, SASL_SSF_EXTERNAL, &extprops); */
+
+    /* set required security properties here
+       sasl_setprop(conn, SASL_SEC_PROPS, &secprops); */
+
+    in = fdopen(fd, "r");
+    out = fdopen(fd, "w");
+
+    r = mysasl_negotiate(in, out, conn);
+    if (r == SASL_OK) {
+       /* send/receive data */
+       
+       
+    }
+    
+    printf("closing connection\n");
+    fclose(in);
+    fclose(out);
+    close(fd);
+    sasl_dispose(&conn);
+
+    sasl_done();
+
+    return 0;
+}
diff --git a/sample/common.c b/sample/common.c
new file mode 100644 (file)
index 0000000..bcbffe4
--- /dev/null
@@ -0,0 +1,154 @@
+/* $Id: common.c,v 1.4 2003/02/13 19:56:06 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+#include <sasl.h>
+
+/* send/recv library for IMAP4 style literals.
+
+   really not important; just one way of doing length coded strings */
+
+int send_string(FILE *f, const char *s, int l)
+{
+    int al;
+
+    al = fprintf(f, "{%d}\r\n", l);
+    fwrite(s, 1, l, f);
+    fflush(f);
+
+    printf("send: {%d}\n", l);
+    while (l--) {
+       if (isprint((unsigned char) *s)) {
+           printf("%c", *s);
+       } else {
+           printf("[%X]", (unsigned char) *s);
+       }
+       s++;
+    }
+    printf("\n");
+
+    return al;
+}
+
+int recv_string(FILE *f, char *buf, int buflen)
+{
+    int c;
+    int len, l;
+    char *s;
+    
+    c = fgetc(f);
+    if (c != '{') return -1;
+
+    /* read length */
+    len = 0;
+    c = fgetc(f);
+    while (isdigit(c)) {
+       len = len * 10 + (c - '0');
+       c = fgetc(f);
+    }
+    if (c != '}') return -1;
+    c = fgetc(f);
+    if (c != '\r') return -1;
+    c = fgetc(f);
+    if (c != '\n') return -1;
+
+    /* read string */
+    if (buflen <= len) {
+       fread(buf, buflen - 1, 1, f);
+       buf[buflen - 1] = '\0';
+       /* discard oversized string */
+       len -= buflen - 1;
+       while (len--) (void)fgetc(f);
+
+       len = buflen - 1;
+    } else {
+       fread(buf, len, 1, f);
+       buf[len] = '\0';
+    }
+
+    l = len;
+    s = buf;
+    printf("recv: {%d}\n", len);
+    while (l--) {
+       if (isprint((unsigned char) *s)) {
+           printf("%c", *s);
+       } else {
+           printf("[%X]", (unsigned char) *s);
+       }
+       s++;
+    }
+    printf("\n");
+
+    return len;
+}
+
+int debuglevel = 0;
+
+int dprintf(int lvl, const char *fmt, ...)
+{
+    va_list ap;
+    int ret = 0;
+
+    if (debuglevel >= lvl) {
+       va_start(ap, fmt);
+       ret = vfprintf(stdout, fmt, ap);
+       va_end(ap);
+    } 
+
+    return ret;
+}
+
+void saslerr(int why, const char *what)
+{
+  fprintf(stderr, "%s: %s", what, sasl_errstring(why, NULL, NULL));
+}
+
+void saslfail(int why, const char *what)
+{
+    saslerr(why, what);
+    exit(EX_TEMPFAIL);
+}
+
diff --git a/sample/common.h b/sample/common.h
new file mode 100644 (file)
index 0000000..fe56b1d
--- /dev/null
@@ -0,0 +1,49 @@
+/* $Id: common.h,v 1.3 2003/02/13 19:56:06 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.
+ */
+
+extern int send_string(FILE *f, const char *s, int l);
+extern int recv_string(FILE *f, char *buf, int buflen);
+
+extern int debuglevel;
+extern int dprintf(int lvl, const char *fmt, ...);
+
+extern void saslerr(int why, const char *what);
+extern void saslfail(int why, const char *what);
diff --git a/sample/sample-client.c b/sample/sample-client.c
new file mode 100644 (file)
index 0000000..228e08d
--- /dev/null
@@ -0,0 +1,855 @@
+/* sample-client.c -- sample SASL client
+ * Rob Earhart
+ * $Id: sample-client.c,v 1.31 2004/10/26 11:14:33 mel 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.
+ */
+#include <config.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef WIN32
+# include <winsock2.h>
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+__declspec(dllimport) int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#else  /* WIN32 */
+# include <netinet/in.h>
+#endif /* WIN32 */
+#include <sasl.h>
+#include <saslutil.h>
+
+#ifdef macintosh
+#include <sioux.h>
+#include <parse_cmd_line.h>
+#define MAX_ARGC (100)
+int xxx_main(int argc, char *argv[]);
+int main(void)
+{
+       char *argv[MAX_ARGC];
+       int argc;
+       char line[400];
+       SIOUXSettings.asktosaveonclose = 0;
+       SIOUXSettings.showstatusline = 1;
+       argc=parse_cmd_line(MAX_ARGC,argv,sizeof(line),line);
+       return xxx_main(argc,argv);
+}
+#define main xxx_main
+#endif
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef HAVE_GETSUBOPT
+int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#endif
+
+static const char
+build_ident[] = "$Build: sample-client " PACKAGE "-" VERSION " $";
+
+static const char *progname = NULL;
+static int verbose;
+
+#define SAMPLE_SEC_BUF_SIZE (2048)
+
+#define N_CALLBACKS (16)
+
+static const char
+message[] = "Come here Watson, I want you.";
+
+char buf[SAMPLE_SEC_BUF_SIZE];
+
+static const char *bit_subopts[] = {
+#define OPT_MIN (0)
+  "min",
+#define OPT_MAX (1)
+  "max",
+  NULL
+};
+
+static const char *ext_subopts[] = {
+#define OPT_EXT_SSF (0)
+  "ssf",
+#define OPT_EXT_ID (1)
+  "id",
+  NULL
+};
+
+static const char *flag_subopts[] = {
+#define OPT_NOPLAIN (0)
+  "noplain",
+#define OPT_NOACTIVE (1)
+  "noactive",
+#define OPT_NODICT (2)
+  "nodict",
+#define OPT_FORWARDSEC (3)
+  "forwardsec",
+#define OPT_NOANONYMOUS (4)
+  "noanonymous",
+#define OPT_PASSCRED (5)
+  "passcred",
+  NULL
+};
+
+static const char *ip_subopts[] = {
+#define OPT_IP_LOCAL (0)
+  "local",
+#define OPT_IP_REMOTE (1)
+  "remote",
+  NULL
+};
+
+static sasl_conn_t *conn = NULL;
+
+static void
+free_conn(void)
+{
+  if (conn)
+    sasl_dispose(&conn);
+}
+
+static int
+sasl_my_log(void *context __attribute__((unused)),
+           int priority,
+           const char *message) 
+{
+  const char *label;
+
+  if (! message)
+    return SASL_BADPARAM;
+
+  switch (priority) {
+  case SASL_LOG_ERR:
+    label = "Error";
+    break;
+  case SASL_LOG_NOTE:
+    label = "Info";
+    break;
+  default:
+    label = "Other";
+    break;
+  }
+
+  fprintf(stderr, "%s: SASL %s: %s\n",
+         progname, label, message);
+
+  return SASL_OK;
+}
+
+static int getrealm(void *context, 
+                   int id,
+                   const char **availrealms __attribute__((unused)),
+                   const char **result)
+{
+  if (id!=SASL_CB_GETREALM) return SASL_FAIL;
+
+  *result=(char *) context;
+  
+  return SASL_OK;
+}
+
+static int
+getpath(void *context,
+       const char ** path) 
+{
+  const char *searchpath = (const char *) context;
+
+  if (! path)
+    return SASL_BADPARAM;
+
+  if (searchpath) {
+      *path = searchpath;
+  } else {
+      *path = PLUGINDIR;
+  }
+
+  return SASL_OK;
+}
+
+static int
+simple(void *context,
+       int id,
+       const char **result,
+       unsigned *len)
+{
+  const char *value = (const char *)context;
+
+  if (! result)
+    return SASL_BADPARAM;
+
+  switch (id) {
+  case SASL_CB_USER:
+    *result = value;
+    if (len)
+      *len = value ? (unsigned) strlen(value) : 0;
+    break;
+  case SASL_CB_AUTHNAME:
+    *result = value;
+    if (len)
+      *len = value ? (unsigned) strlen(value) : 0;
+    break;
+  case SASL_CB_LANGUAGE:
+    *result = NULL;
+    if (len)
+      *len = 0;
+    break;
+  default:
+    return SASL_BADPARAM;
+  }
+
+  printf("returning OK: %s\n", *result);
+
+  return SASL_OK;
+}
+
+#ifndef HAVE_GETPASSPHRASE
+static char *
+getpassphrase(const char *prompt)
+{
+  return getpass(prompt);
+}
+#endif /* ! HAVE_GETPASSPHRASE */
+
+static int
+getsecret(sasl_conn_t *conn,
+         void *context __attribute__((unused)),
+         int id,
+         sasl_secret_t **psecret)
+{
+  char *password;
+  unsigned len;
+
+  if (! conn || ! psecret || id != SASL_CB_PASS)
+    return SASL_BADPARAM;
+
+  password = getpassphrase("Password: ");
+  if (! password)
+    return SASL_FAIL;
+
+  len = (unsigned) strlen(password);
+
+  *psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len);
+  
+  if (! *psecret) {
+    memset(password, 0, len);
+    return SASL_NOMEM;
+  }
+
+  (*psecret)->len = len;
+  strcpy((char *)(*psecret)->data, password);
+  memset(password, 0, len);
+    
+  return SASL_OK;
+}
+
+static int
+prompt(void *context __attribute__((unused)),
+       int id,
+       const char *challenge,
+       const char *prompt,
+       const char *defresult,
+       const char **result,
+       unsigned *len)
+{
+  if ((id != SASL_CB_ECHOPROMPT && id != SASL_CB_NOECHOPROMPT)
+      || !prompt || !result || !len)
+    return SASL_BADPARAM;
+
+  if (! defresult)
+    defresult = "";
+  
+  fputs(prompt, stdout);
+  if (challenge)
+    printf(" [challenge: %s]", challenge);
+  printf(" [%s]: ", defresult);
+  fflush(stdout);
+  
+  if (id == SASL_CB_ECHOPROMPT) {
+    char *original = getpassphrase("");
+    if (! original)
+      return SASL_FAIL;
+    if (*original)
+      *result = strdup(original);
+    else
+      *result = strdup(defresult);
+    memset(original, 0L, strlen(original));
+  } else {
+    char buf[1024];
+    fgets(buf, 1024, stdin);
+    if (buf[0]) {
+      *result = strdup(buf);
+    } else {
+      *result = strdup(defresult);
+    }
+    memset(buf, 0L, sizeof(buf));
+  }
+  if (! *result)
+    return SASL_NOMEM;
+
+  *len = (unsigned) strlen(*result);
+  
+  return SASL_OK;
+}
+
+static void
+sasldebug(int why, const char *what, const char *errstr)
+{
+  fprintf(stderr, "%s: %s: %s",
+         progname,
+         what,
+         sasl_errstring(why, NULL, NULL));
+  if (errstr)
+    fprintf(stderr, " (%s)\n", errstr);
+  else
+    putc('\n', stderr);
+}
+
+static void
+saslfail(int why, const char *what, const char *errstr)
+{
+  sasldebug(why, what, errstr);
+  free_conn();
+  sasl_done();
+  exit(EXIT_FAILURE);
+}
+
+static void
+fail(const char *what)
+{
+  fprintf(stderr, "%s: %s\n",
+         progname, what);
+  exit(EXIT_FAILURE);
+}
+
+static void
+osfail()
+{
+  perror(progname);
+  exit(EXIT_FAILURE);
+}
+
+static void
+samp_send(const char *buffer,
+         unsigned length)
+{
+  char *buf;
+  unsigned len, alloclen;
+  int result;
+
+  alloclen = ((length / 3) + 1) * 4 + 1;
+  buf = malloc(alloclen);
+  if (! buf)
+    osfail();
+  result = sasl_encode64(buffer, length, buf, alloclen, &len);
+  if (result != SASL_OK)
+    saslfail(result, "Encoding data in base64", NULL);
+  printf("C: %s\n", buf);
+  free(buf);
+}
+
+static unsigned
+samp_recv()
+{
+  unsigned len;
+  int result;
+  
+  if (! fgets(buf, SAMPLE_SEC_BUF_SIZE, stdin)
+      || strncmp(buf, "S: ", 3))
+    fail("Unable to parse input");
+  result = sasl_decode64(buf + 3, (unsigned) strlen(buf + 3), buf,
+                        SAMPLE_SEC_BUF_SIZE, &len);
+  if (result != SASL_OK)
+    saslfail(result, "Decoding data from base64", NULL);
+  buf[len] = '\0';
+  printf("recieved %d byte message\n",len);
+  if (verbose) { printf("got '%s'\n", buf); }
+  return len;
+}
+
+int
+main(int argc, char *argv[])
+{
+  int c = 0;
+  int errflag = 0;
+  int result;
+  sasl_security_properties_t secprops;
+  sasl_ssf_t extssf = 0;
+  const char *ext_authid = NULL;
+  char *options, *value;
+  const char *data;
+  const char *chosenmech;
+  int serverlast = 0;
+  unsigned len;
+  int clientfirst = 1;
+  sasl_callback_t callbacks[N_CALLBACKS], *callback;
+  char *realm = NULL;
+  char *mech = NULL,
+    *iplocal = NULL,
+    *ipremote = NULL,
+    *searchpath = NULL,
+    *service = "rcmd",
+    *fqdn = "",
+    *userid = NULL,
+    *authid = NULL;
+  sasl_ssf_t *ssf;
+    
+#ifdef WIN32
+  /* initialize winsock */
+    WSADATA wsaData;
+
+    result = WSAStartup( MAKEWORD(2, 0), &wsaData );
+    if ( result != 0) {
+       saslfail(SASL_FAIL, "Initializing WinSockets", NULL);
+    }
+#endif
+
+  progname = strrchr(argv[0], HIER_DELIMITER);
+  if (progname)
+    progname++;
+  else
+    progname = argv[0];
+
+  /* Init defaults... */
+  memset(&secprops, 0L, sizeof(secprops));
+  secprops.maxbufsize = SAMPLE_SEC_BUF_SIZE;
+  secprops.max_ssf = UINT_MAX;
+
+  verbose = 0;
+  while ((c = getopt(argc, argv, "vhldb:e:m:f:i:p:r:s:n:u:a:?")) != EOF)
+    switch (c) {
+    case 'v':
+       verbose = 1;
+       break;
+    case 'b':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)bit_subopts, &value)) {
+       case OPT_MIN:
+         if (! value)
+           errflag = 1;
+         else
+           secprops.min_ssf = atoi(value);
+         break;
+       case OPT_MAX:
+         if (! value)
+           errflag = 1;
+         else
+           secprops.max_ssf = atoi(value);
+         break;
+       default:
+         errflag = 1;
+         break;          
+         }
+      break;
+
+    case 'l':
+       serverlast = SASL_SUCCESS_DATA;
+       break;
+       
+    case 'd':
+       clientfirst = 0;
+       break;
+
+    case 'e':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)ext_subopts, &value)) {
+       case OPT_EXT_SSF:
+         if (! value)
+           errflag = 1;
+         else
+           extssf = atoi(value);
+         break;
+       case OPT_MAX:
+         if (! value)
+           errflag = 1;
+         else
+           ext_authid = value;
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+      break;
+
+    case 'm':
+      mech = optarg;
+      break;
+
+    case 'f':
+      options = optarg;
+      while (*options != '\0') {
+       switch(getsubopt(&options, (const char * const *)flag_subopts, &value)) {
+       case OPT_NOPLAIN:
+         secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
+         break;
+       case OPT_NOACTIVE:
+         secprops.security_flags |= SASL_SEC_NOACTIVE;
+         break;
+       case OPT_NODICT:
+         secprops.security_flags |= SASL_SEC_NODICTIONARY;
+         break;
+       case OPT_FORWARDSEC:
+         secprops.security_flags |= SASL_SEC_FORWARD_SECRECY;
+         break;
+       case OPT_NOANONYMOUS:
+         secprops.security_flags |= SASL_SEC_NOANONYMOUS;
+         break;
+       case OPT_PASSCRED:
+         secprops.security_flags |= SASL_SEC_PASS_CREDENTIALS;
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+       if (value) errflag = 1;
+       }
+      break;
+
+    case 'i':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)ip_subopts, &value)) {
+       case OPT_IP_LOCAL:
+         if (! value)
+           errflag = 1;
+         else
+           iplocal = value;
+         break;
+       case OPT_IP_REMOTE:
+         if (! value)
+           errflag = 1;
+         else
+           ipremote = value;
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+      break;
+
+    case 'p':
+      searchpath = optarg;
+      break;
+
+    case 'r':
+      realm = optarg;
+      break;
+
+    case 's':
+      service=malloc(1000);
+      strcpy(service,optarg);
+      /*      service = optarg;*/
+      printf("service=%s\n",service);
+      break;
+
+    case 'n':
+      fqdn = optarg;
+      break;
+
+    case 'u':
+      userid = optarg;
+      break;
+
+    case 'a':
+      authid = optarg;
+      break;
+
+    default:                   /* unknown flag */
+      errflag = 1;
+      break;
+    }
+
+  if (optind != argc) {
+    /* We don't *have* extra arguments */
+    errflag = 1;
+  }
+
+  if (errflag) {
+    fprintf(stderr, "%s: Usage: %s [-b min=N,max=N] [-e ssf=N,id=ID] [-m MECH] [-f FLAGS] [-i local=IP,remote=IP] [-p PATH] [-s NAME] [-n FQDN] [-u ID] [-a ID]\n"
+           "\t-b ...\t#bits to use for encryption\n"
+           "\t\tmin=N\tminumum #bits to use (1 => integrity)\n"
+           "\t\tmax=N\tmaximum #bits to use\n"
+           "\t-e ...\tassume external encryption\n"
+           "\t\tssf=N\texternal mech provides N bits of encryption\n"
+           "\t\tid=ID\texternal mech provides authentication id ID\n"
+           "\t-m MECH\tforce use of MECH for security\n"
+           "\t-f ...\tset security flags\n"
+           "\t\tnoplain\t\trequire security vs. passive attacks\n"
+           "\t\tnoactive\trequire security vs. active attacks\n"
+           "\t\tnodict\t\trequire security vs. passive dictionary attacks\n"
+           "\t\tforwardsec\trequire forward secrecy\n"
+           "\t\tmaximum\t\trequire all security flags\n"
+           "\t\tpasscred\tattempt to pass client credentials\n"
+           "\t-i ...\tset IP addresses (required by some mechs)\n"
+           "\t\tlocal=IP;PORT\tset local address to IP, port PORT\n"
+           "\t\tremote=IP;PORT\tset remote address to IP, port PORT\n"
+           "\t-p PATH\tcolon-seperated search path for mechanisms\n"
+           "\t-r REALM\trealm to use"
+           "\t-s NAME\tservice name pass to mechanisms\n"
+           "\t-n FQDN\tserver fully-qualified domain name\n"
+           "\t-u ID\tuser (authorization) id to request\n"
+           "\t-a ID\tid to authenticate as\n"
+           "\t-d\tDisable client-send-first\n"
+           "\t-l\tEnable server-send-last\n",
+           progname, progname);
+    exit(EXIT_FAILURE);
+  }
+
+  /* Fill in the callbacks that we're providing... */
+  callback = callbacks;
+
+  /* log */
+  callback->id = SASL_CB_LOG;
+  callback->proc = &sasl_my_log;
+  callback->context = NULL;
+  ++callback;
+  
+  /* getpath */
+  if (searchpath) {
+    callback->id = SASL_CB_GETPATH;
+    callback->proc = &getpath;
+    callback->context = searchpath;
+    ++callback;
+  }
+
+  /* user */
+  if (userid) {
+    callback->id = SASL_CB_USER;
+    callback->proc = &simple;
+    callback->context = userid;
+    ++callback;
+  }
+
+  /* authname */
+  if (authid) {
+    callback->id = SASL_CB_AUTHNAME;
+    callback->proc = &simple;
+    callback->context = authid;
+    ++callback;
+  }
+
+  if (realm!=NULL)
+  {
+    callback->id = SASL_CB_GETREALM;
+    callback->proc = &getrealm;
+    callback->context = realm;
+    callback++;
+  }
+
+  /* password */
+  callback->id = SASL_CB_PASS;
+  callback->proc = &getsecret;
+  callback->context = NULL;
+  ++callback;
+
+  /* echoprompt */
+  callback->id = SASL_CB_ECHOPROMPT;
+  callback->proc = &prompt;
+  callback->context = NULL;
+  ++callback;
+
+  /* noechoprompt */
+  callback->id = SASL_CB_NOECHOPROMPT;
+  callback->proc = &prompt;
+  callback->context = NULL;
+  ++callback;
+
+  /* termination */
+  callback->id = SASL_CB_LIST_END;
+  callback->proc = NULL;
+  callback->context = NULL;
+  ++callback;
+
+  if (N_CALLBACKS < callback - callbacks)
+    fail("Out of callback space; recompile with larger N_CALLBACKS");
+
+  result = sasl_client_init(callbacks);
+  if (result != SASL_OK)
+    saslfail(result, "Initializing libsasl", NULL);
+
+  result = sasl_client_new(service,
+                          fqdn,
+                          iplocal,ipremote,
+                          NULL,serverlast,
+                          &conn);
+  if (result != SASL_OK)
+    saslfail(result, "Allocating sasl connection state", NULL);
+
+  if(extssf) {
+      result = sasl_setprop(conn,
+                           SASL_SSF_EXTERNAL,
+                           &extssf);
+
+      if (result != SASL_OK)
+         saslfail(result, "Setting external SSF", NULL);
+  }
+  
+  if(ext_authid) {
+      result = sasl_setprop(conn,
+                           SASL_AUTH_EXTERNAL,
+                           &ext_authid);
+
+      if (result != SASL_OK)
+         saslfail(result, "Setting external authid", NULL);
+  }
+  
+  result = sasl_setprop(conn,
+                       SASL_SEC_PROPS,
+                       &secprops);
+
+  if (result != SASL_OK)
+    saslfail(result, "Setting security properties", NULL);
+
+  puts("Waiting for mechanism list from server...");
+  len = samp_recv();
+
+  if (mech) {
+    printf("Forcing use of mechanism %s\n", mech);
+    strncpy(buf, mech, SAMPLE_SEC_BUF_SIZE);
+    buf[SAMPLE_SEC_BUF_SIZE - 1] = '\0';
+  }
+
+  printf("Choosing best mechanism from: %s\n", buf);
+
+  if(clientfirst) {
+      result = sasl_client_start(conn,
+                                buf,
+                                NULL,
+                                &data,
+                                &len,
+                                &chosenmech);
+  } else {
+      data = "";
+      len = 0;
+      result = sasl_client_start(conn,
+                                buf,
+                                NULL,
+                                NULL,
+                                0,
+                                &chosenmech);
+  }
+  
+  
+  if (result != SASL_OK && result != SASL_CONTINUE) {
+      printf("error was %s\n", sasl_errdetail(conn));
+      saslfail(result, "Starting SASL negotiation", NULL);
+  }
+
+  printf("Using mechanism %s\n", chosenmech);
+  strcpy(buf, chosenmech);
+  if (data) {
+    if (SAMPLE_SEC_BUF_SIZE - strlen(buf) - 1 < len)
+      fail("Not enough buffer space");
+    puts("Preparing initial.");
+    memcpy(buf + strlen(buf) + 1, data, len);
+    len += (unsigned) strlen(buf) + 1;
+    data = NULL;
+  } else {
+    len = (unsigned) strlen(buf);
+  }
+  
+  puts("Sending initial response...");
+  samp_send(buf, len);
+
+  while (result == SASL_CONTINUE) {
+    puts("Waiting for server reply...");
+    len = samp_recv();
+    result = sasl_client_step(conn, buf, len, NULL,
+                             &data, &len);
+    if (result != SASL_OK && result != SASL_CONTINUE)
+       saslfail(result, "Performing SASL negotiation", NULL);
+    if (data && len) {
+       puts("Sending response...");
+       samp_send(data, len);
+    } else if (result != SASL_OK || !serverlast) {
+       samp_send("",0);
+    }
+    
+  }
+  puts("Negotiation complete");
+
+  result = sasl_getprop(conn, SASL_USERNAME, (const void **)&data);
+  if (result != SASL_OK)
+    sasldebug(result, "username", NULL);
+  else
+    printf("Username: %s\n", data);
+
+#define CLIENT_MSG1 "client message 1"
+#define SERVER_MSG1 "srv message 1"
+
+  result = sasl_getprop(conn, SASL_SSF, (const void **)&ssf);
+  if (result != SASL_OK)
+    sasldebug(result, "ssf", NULL);
+  else
+    printf("SSF: %d\n", *ssf);
+ printf("Waiting for encoded message...\n");
+ len=samp_recv();
+ {
+       unsigned int recv_len;
+       const char *recv_data;
+       result=sasl_decode(conn,buf,len,&recv_data,&recv_len);
+       if (result != SASL_OK)
+           saslfail(result, "sasl_decode", NULL);
+       printf("recieved decoded message '%s'\n",recv_data);
+       if(strcmp(recv_data,SERVER_MSG1)!=0)
+           saslfail(1,"recive decoded server message",NULL);
+ }
+  result=sasl_encode(conn,CLIENT_MSG1,sizeof(CLIENT_MSG1),
+       &data,&len);
+  if (result != SASL_OK)
+      saslfail(result, "sasl_encode", NULL);
+  printf("sending encrypted message '%s'\n",CLIENT_MSG1);
+  samp_send(data,len);
+
+  free_conn();
+  sasl_done();
+
+#ifdef WIN32
+  WSACleanup();
+#endif
+  return (EXIT_SUCCESS);
+}
diff --git a/sample/sample-server.c b/sample/sample-server.c
new file mode 100644 (file)
index 0000000..a2b35a0
--- /dev/null
@@ -0,0 +1,630 @@
+/* sample-server.c -- sample SASL server
+ * Rob Earhart
+ * $Id: sample-server.c,v 1.31 2004/10/26 11:14:34 mel 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.
+ */
+
+#include <config.h>
+#include <limits.h>
+#include <stdio.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+# include <winsock2.h>
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+__declspec(dllimport) int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#define HAVE_GETSUBOPT
+#else /* WIN32 */
+# include <netinet/in.h>
+#endif /* WIN32 */
+#include <sasl.h>
+#include <saslutil.h>
+
+#ifndef HAVE_GETSUBOPT
+int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#endif
+
+static const char
+build_ident[] = "$Build: sample-server " PACKAGE "-" VERSION " $";
+
+static const char *progname = NULL;
+static int verbose;
+
+/* Note: if this is changed, change it in samp_read(), too. */
+#define SAMPLE_SEC_BUF_SIZE (2048)
+
+static const char
+message[] = "Come here Watson, I want you.";
+
+char buf[SAMPLE_SEC_BUF_SIZE];
+
+static const char *bit_subopts[] = {
+#define OPT_MIN (0)
+  "min",
+#define OPT_MAX (1)
+  "max",
+  NULL
+};
+
+static const char *ext_subopts[] = {
+#define OPT_EXT_SSF (0)
+  "ssf",
+#define OPT_EXT_ID (1)
+  "id",
+  NULL
+};
+
+static const char *flag_subopts[] = {
+#define OPT_NOPLAIN (0)
+  "noplain",
+#define OPT_NOACTIVE (1)
+  "noactive",
+#define OPT_NODICT (2)
+  "nodict",
+#define OPT_FORWARDSEC (3)
+  "forwardsec",
+#define OPT_NOANONYMOUS (4)
+  "noanonymous",
+#define OPT_PASSCRED (5)
+  "passcred",
+  NULL
+};
+
+static const char *ip_subopts[] = {
+#define OPT_IP_LOCAL (0)
+  "local",
+#define OPT_IP_REMOTE (1)
+  "remote",
+  NULL
+};
+
+char *mech = NULL,
+  *iplocal = NULL,
+  *ipremote = NULL,
+  *searchpath = NULL,
+  *service = "rcmd",
+  *localdomain = NULL,
+  *userdomain = NULL;
+sasl_conn_t *conn = NULL;
+
+static void
+free_conn(void)
+{
+  if (conn)
+    sasl_dispose(&conn);
+}
+
+static int
+sasl_my_log(void *context __attribute__((unused)),
+           int priority,
+           const char *message) 
+{
+  const char *label;
+
+  if (! message)
+    return SASL_BADPARAM;
+
+  switch (priority) {
+  case SASL_LOG_ERR:
+    label = "Error";
+    break;
+  case SASL_LOG_NOTE:
+    label = "Info";
+    break;
+  default:
+    label = "Other";
+    break;
+  }
+
+  fprintf(stderr, "%s: SASL %s: %s\n",
+         progname, label, message);
+
+  return SASL_OK;
+}
+
+static int
+getpath(void *context __attribute__((unused)),
+       char ** path) 
+{
+  if (! path)
+    return SASL_BADPARAM;
+
+  if (searchpath) {
+    *path = searchpath;
+  } else {
+    *path = PLUGINDIR;
+  }
+
+  return SASL_OK;
+}
+
+static sasl_callback_t callbacks[] = {
+  {
+    SASL_CB_LOG, &sasl_my_log, NULL
+  }, {
+    SASL_CB_GETPATH, &getpath, NULL
+  }, {
+    SASL_CB_LIST_END, NULL, NULL
+  }
+};
+
+static void
+sasldebug(int why, const char *what, const char *errstr)
+{
+  fprintf(stderr, "%s: %s: %s",
+         progname,
+         what,
+         sasl_errstring(why, NULL, NULL));
+  if (errstr)
+    fprintf(stderr, " (%s)\n", errstr);
+  else
+    putc('\n', stderr);
+}
+
+static void
+saslfail(int why, const char *what, const char *errstr)
+{
+  sasldebug(why, what, errstr);
+  exit(EXIT_FAILURE);
+}
+
+static void
+fail(const char *what)
+{
+  fprintf(stderr, "%s: %s\n",
+         progname, what);
+  exit(EXIT_FAILURE);
+}
+
+static void
+osfail()
+{
+  perror(progname);
+  exit(EXIT_FAILURE);
+}
+
+static void
+samp_send(const char *buffer,
+         unsigned length)
+{
+  char *buf;
+  unsigned len, alloclen;
+  int result;
+
+  alloclen = ((length / 3) + 1) * 4 + 1;
+  buf = malloc(alloclen);
+  if (! buf)
+    osfail();
+
+  result = sasl_encode64(buffer, length, buf, alloclen, &len);
+  if (result != SASL_OK)
+    saslfail(result, "Encoding data in base64", NULL);
+  printf("S: %s\n", buf);
+  free(buf);
+}
+
+static unsigned
+samp_recv()
+{
+  unsigned len;
+  int result;
+  
+  if (! fgets(buf, SAMPLE_SEC_BUF_SIZE, stdin))
+    fail("Unable to parse input");
+
+  if (strncmp(buf, "C: ", 3)!=0)
+    fail("Line must start with 'C: '");
+    
+  result = sasl_decode64(buf + 3, (unsigned) strlen(buf + 3), buf,
+                        SAMPLE_SEC_BUF_SIZE, &len);
+  if (result != SASL_OK)
+    saslfail(result, "Decoding data from base64", NULL);
+  buf[len] = '\0';
+  printf("got '%s'\n", buf);
+  return len;
+}
+
+
+int
+main(int argc, char *argv[])
+{
+  int c = 0;
+  int errflag = 0;
+  int result;
+  sasl_security_properties_t secprops;
+  sasl_ssf_t extssf = 0;
+  const char *ext_authid = NULL;
+  char *options, *value;
+  unsigned len, count;
+  const char *data;
+  int serverlast = 0;
+  sasl_ssf_t *ssf;
+
+#ifdef WIN32
+  /* initialize winsock */
+    WSADATA wsaData;
+
+    result = WSAStartup( MAKEWORD(2, 0), &wsaData );
+    if ( result != 0) {
+       saslfail(SASL_FAIL, "Initializing WinSockets", NULL);
+    }
+#endif
+
+  progname = strrchr(argv[0], HIER_DELIMITER);
+  if (progname)
+    progname++;
+  else
+    progname = argv[0];
+
+  /* Init defaults... */
+  memset(&secprops, 0L, sizeof(secprops));
+  secprops.maxbufsize = SAMPLE_SEC_BUF_SIZE;
+  secprops.max_ssf = UINT_MAX;
+
+  verbose = 0;
+  while ((c = getopt(argc, argv, "vlhb:e:m:f:i:p:s:d:u:?")) != EOF)
+    switch (c) {
+    case 'v':
+       verbose = 1;
+       break;
+    case 'b':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)bit_subopts, &value)) {
+       case OPT_MIN:
+         if (! value)
+           errflag = 1;
+         else
+           secprops.min_ssf = atoi(value);
+         break;
+       case OPT_MAX:
+         if (! value)
+           errflag = 1;
+         else
+           secprops.max_ssf = atoi(value);
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+      break;
+
+    case 'e':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)ext_subopts, &value)) {
+       case OPT_EXT_SSF:
+         if (! value)
+           errflag = 1;
+         else
+           extssf = atoi(value);
+         break;
+       case OPT_MAX:
+         if (! value)
+           errflag = 1;
+         else
+           ext_authid = value;
+         break;
+       default:
+         errflag = 1;
+         break;
+         } 
+      break;
+
+    case 'm':
+      mech = optarg;
+      break;
+
+    case 'f':
+      options = optarg;
+      while (*options != '\0') {
+       switch(getsubopt(&options, (const char * const *)flag_subopts, &value)) {
+       case OPT_NOPLAIN:
+         secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
+         break;
+       case OPT_NOACTIVE:
+         secprops.security_flags |= SASL_SEC_NOACTIVE;
+         break;
+       case OPT_NODICT:
+         secprops.security_flags |= SASL_SEC_NODICTIONARY;
+         break;
+       case OPT_FORWARDSEC:
+         secprops.security_flags |= SASL_SEC_FORWARD_SECRECY;
+         break;
+       case OPT_NOANONYMOUS:
+         secprops.security_flags |= SASL_SEC_NOANONYMOUS;
+         break;
+       case OPT_PASSCRED:
+         secprops.security_flags |= SASL_SEC_PASS_CREDENTIALS;
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+       if (value) errflag = 1;
+       }
+      break;
+
+    case 'l':
+       serverlast = SASL_SUCCESS_DATA;
+       break;
+
+    case 'i':
+      options = optarg;
+      while (*options != '\0')
+       switch(getsubopt(&options, (const char * const *)ip_subopts, &value)) {
+       case OPT_IP_LOCAL:
+         if (! value)
+           errflag = 1;
+         else
+           iplocal = value;
+         break;
+       case OPT_IP_REMOTE:
+         if (! value)
+           errflag = 1;
+         else
+           ipremote = value;
+         break;
+       default:
+         errflag = 1;
+         break;
+         }
+      break;
+
+    case 'p':
+      searchpath = optarg;
+      break;
+
+    case 's':
+      service = optarg;
+      break;
+
+    case 'd':
+      localdomain = optarg;
+      break;
+
+    case 'u':
+      userdomain = optarg;
+      break;
+
+    default:           
+      errflag = 1;
+      break;
+    }
+
+  if (optind != argc) {
+    
+    errflag = 1;
+  }
+
+  if (errflag) {
+    fprintf(stderr, "%s: Usage: %s [-b min=N,max=N] [-e ssf=N,id=ID] [-m MECH] [-f FLAGS] [-i local=IP,remote=IP] [-p PATH] [-d DOM] [-u DOM] [-s NAME]\n"
+           "\t-b ...\t#bits to use for encryption\n"
+           "\t\tmin=N\tminumum #bits to use (1 => integrity)\n"
+           "\t\tmax=N\tmaximum #bits to use\n"
+           "\t-e ...\tassume external encryption\n"
+           "\t\tssf=N\texternal mech provides N bits of encryption\n"
+           "\t\tid=ID\texternal mech provides authentication id ID\n"
+           "\t-m MECH\tforce use of MECH for security\n"
+           "\t-f ...\tset security flags\n"
+           "\t\tnoplain\t\trequire security vs. passive attacks\n"
+           "\t\tnoactive\trequire security vs. active attacks\n"
+           "\t\tnodict\t\trequire security vs. passive dictionary attacks\n"
+           "\t\tforwardsec\trequire forward secrecy\n"
+           "\t\tmaximum\t\trequire all security flags\n"
+           "\t\tpasscred\tattempt to receive client credentials\n"
+           "\t-i ...\tset IP addresses (required by some mechs)\n"
+           "\t\tlocal=IP;PORT\tset local address to IP, port PORT\n"
+           "\t\tremote=IP;PORT\tset remote address to IP, port PORT\n"
+           "\t-p PATH\tcolon-seperated search path for mechanisms\n"
+           "\t-s NAME\tservice name to pass to mechanisms\n"
+           "\t-d DOM\tlocal server domain\n"
+           "\t-u DOM\tuser domain\n"
+           "\t-l\tenable server-send-last\n",
+           progname, progname);
+    exit(EXIT_FAILURE);
+  }
+
+  result = sasl_server_init(callbacks, "sample");
+  if (result != SASL_OK)
+    saslfail(result, "Initializing libsasl", NULL);
+
+  atexit(&sasl_done);
+
+  result = sasl_server_new(service,
+                          localdomain,
+                          userdomain,
+                          iplocal,
+                          ipremote,
+                          NULL,
+                          serverlast,
+                          &conn);
+  if (result != SASL_OK)
+    saslfail(result, "Allocating sasl connection state", NULL);
+  
+  atexit(&free_conn);
+
+  if(extssf) {
+      result = sasl_setprop(conn,
+                           SASL_SSF_EXTERNAL,
+                           &extssf);
+
+      if (result != SASL_OK)
+         saslfail(result, "Setting external SSF", NULL);
+  }
+  
+  if(ext_authid) {
+      result = sasl_setprop(conn,
+                           SASL_AUTH_EXTERNAL,
+                           &ext_authid);
+
+      if (result != SASL_OK)
+         saslfail(result, "Setting external authid", NULL);
+  }
+
+  result = sasl_setprop(conn,
+                       SASL_SEC_PROPS,
+                       &secprops);
+
+  if (result != SASL_OK)
+    saslfail(result, "Setting security properties", NULL);
+
+  if (mech) {
+    printf("Forcing use of mechanism %s\n", mech);
+    data = strdup(mech);
+    if (! data)
+      osfail();
+    len = (unsigned) strlen(data);
+    count = 1;
+  } else {
+    puts("Generating client mechanism list...");
+    result = sasl_listmech(conn,
+                          ext_authid,
+                          NULL,
+                          " ",
+                          NULL,
+                          &data,
+                          &len,
+                          &count);
+    if (result != SASL_OK)
+      saslfail(result, "Generating client mechanism list", NULL);
+  }
+  
+  printf("Sending list of %d mechanism(s)\n", count);
+  samp_send(data, len);
+
+  if(mech) {
+      free((void *)data);
+  }
+
+  puts("Waiting for client mechanism...");
+  len = samp_recv();
+  if (mech && strcasecmp(mech, buf))
+    fail("Client chose something other than the mandatory mechanism");
+  if (strlen(buf) < len) {
+    /* Hmm, there's an initial response here */
+    data = buf + strlen(buf) + 1;
+    len = len - strlen(buf) - 1;
+  } else {
+    data = NULL;
+    len = 0;
+  }
+  result = sasl_server_start(conn,
+                            buf,
+                            data,
+                            len,
+                            &data,
+                            &len);
+  if (result != SASL_OK && result != SASL_CONTINUE)
+    saslfail(result, "Starting SASL negotiation", sasl_errstring(result,NULL,NULL));
+
+  while (result == SASL_CONTINUE) {
+    if (data) {
+      puts("Sending response...");
+      samp_send(data, len);
+    } else
+      fail("No data to send--something's wrong");
+    puts("Waiting for client reply...");
+    len = samp_recv();
+    data = NULL;
+    result = sasl_server_step(conn, buf, len,
+                             &data, &len);
+    if (result != SASL_OK && result != SASL_CONTINUE)
+      saslfail(result, "Performing SASL negotiation", sasl_errstring(result,NULL,NULL));
+  }
+  puts("Negotiation complete");
+
+  if(serverlast&&data) {
+      printf("might need additional send:\n");
+      samp_send(data,len);
+  }
+
+  result = sasl_getprop(conn, SASL_USERNAME, (const void **)&data);
+  if (result != SASL_OK)
+    sasldebug(result, "username", NULL);
+  else
+    printf("Username: %s\n", data ? data : "(NULL)");
+
+  result = sasl_getprop(conn, SASL_DEFUSERREALM, (const void **)&data);
+  if (result != SASL_OK)
+    sasldebug(result, "realm", NULL);
+  else
+    printf("Realm: %s\n", data ? data : "(NULL)");
+
+  result = sasl_getprop(conn, SASL_SSF, (const void **)&ssf);
+  if (result != SASL_OK)
+    sasldebug(result, "ssf", NULL);
+  else
+    printf("SSF: %d\n", *ssf);
+#define CLIENT_MSG1 "client message 1"
+#define SERVER_MSG1 "srv message 1"
+  result=sasl_encode(conn,SERVER_MSG1,sizeof(SERVER_MSG1),
+       &data,&len);
+  if (result != SASL_OK)
+      saslfail(result, "sasl_encode", NULL);
+  printf("sending encrypted message '%s'\n",SERVER_MSG1);
+  samp_send(data,len);
+  printf("Waiting for encrypted message...\n");
+  len=samp_recv();
+ {
+       unsigned int recv_len;
+       const char *recv_data;
+       result=sasl_decode(conn,buf,len,&recv_data,&recv_len);
+       if (result != SASL_OK)
+      saslfail(result, "sasl_encode", NULL);
+    printf("recieved decoded message '%s'\n",recv_data);
+    if(strcmp(recv_data,CLIENT_MSG1)!=0)
+       saslfail(1,"recive decoded server message",NULL);
+ }
+
+#ifdef WIN32
+  WSACleanup();
+#endif
+
+  return (EXIT_SUCCESS);
+}
diff --git a/sample/server.c b/sample/server.c
new file mode 100644 (file)
index 0000000..e0af99c
--- /dev/null
@@ -0,0 +1,428 @@
+/* $Id: server.c,v 1.9 2004/03/29 14:56:40 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <sasl.h>
+
+#include "common.h"
+
+#if !defined(IPV6_BINDV6ONLY) && defined(IN6P_IPV6_V6ONLY)
+#define IPV6_BINDV6ONLY IN6P_BINDV6ONLY
+#endif
+#if !defined(IPV6_V6ONLY) && defined(IPV6_BINDV6ONLY)
+#define        IPV6_V6ONLY     IPV6_BINDV6ONLY
+#endif
+#ifndef IPV6_BINDV6ONLY
+#undef      IPV6_V6ONLY
+#endif
+
+/* create a socket listening on port 'port' */
+/* if af is PF_UNSPEC more than one socket may be returned */
+/* the returned list is dynamically allocated, so caller needs to free it */
+int *listensock(const char *port, const int af)
+{
+    struct addrinfo hints, *ai, *r;
+    int err, maxs, *sock, *socks;
+    const int on = 1;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_PASSIVE;
+    hints.ai_family = af;
+    hints.ai_socktype = SOCK_STREAM;
+    err = getaddrinfo(NULL, port, &hints, &ai);
+    if (err) {
+       fprintf(stderr, "%s\n", gai_strerror(err));
+       exit(EX_USAGE);
+    }
+
+    /* Count max number of sockets we may open */
+    for (maxs = 0, r = ai; r; r = r->ai_next, maxs++)
+       ;
+    socks = malloc((maxs + 1) * sizeof(int));
+    if (!socks) {
+       fprintf(stderr, "couldn't allocate memory for sockets\n");
+       freeaddrinfo(ai);
+       exit(EX_OSERR);
+    }
+
+    socks[0] = 0;      /* num of sockets counter at start of array */
+    sock = socks + 1;
+    for (r = ai; r; r = r->ai_next) {
+       fprintf(stderr, "trying %d, %d, %d\n",r->ai_family, r->ai_socktype, r->ai_protocol);
+       *sock = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+       if (*sock < 0) {
+           perror("socket");
+           continue;
+       }
+       if (setsockopt(*sock, SOL_SOCKET, SO_REUSEADDR, 
+                      (void *) &on, sizeof(on)) < 0) {
+           perror("setsockopt(SO_REUSEADDR)");
+           close(*sock);
+           continue;
+       }
+#if defined(IPV6_V6ONLY) && !(defined(__FreeBSD__) && __FreeBSD__ < 3)
+       if (r->ai_family == AF_INET6) {
+           if (setsockopt(*sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+                          (void *) &on, sizeof(on)) < 0) {
+               perror("setsockopt (IPV6_BINDV6ONLY)");
+               close(*sock);
+               continue;
+           }
+       }
+#endif
+       if (bind(*sock, r->ai_addr, r->ai_addrlen) < 0) {
+           perror("bind");
+           close(*sock);
+           continue;
+       }
+
+       if (listen(*sock, 5) < 0) {
+           perror("listen");
+           close(*sock);
+           continue;
+       }
+
+       socks[0]++;
+       sock++;
+    }
+
+    freeaddrinfo(ai);
+
+    if (socks[0] == 0) {
+       fprintf(stderr, "Couldn't bind to any socket\n");
+       free(socks);
+       exit(EX_OSERR);
+    }
+
+    return socks;
+}
+
+void usage(void)
+{
+    fprintf(stderr, "usage: server [-p port] [-s service] [-m mech]\n");
+    exit(EX_USAGE);
+}
+
+/* globals because i'm lazy */
+char *mech;
+
+/* do the sasl negotiation; return -1 if it fails */
+int mysasl_negotiate(FILE *in, FILE *out, sasl_conn_t *conn)
+{
+    char buf[8192];
+    char chosenmech[128];
+    const char *data;
+    int len;
+    int r = SASL_FAIL;
+    const char *userid;
+    
+    /* generate the capability list */
+    if (mech) {
+       dprintf(2, "forcing use of mechanism %s\n", mech);
+       data = strdup(mech);
+       len = strlen(data);
+    } else {
+       int count;
+
+       dprintf(1, "generating client mechanism list... ");
+       r = sasl_listmech(conn, NULL, NULL, " ", NULL,
+                         &data, &len, &count);
+       if (r != SASL_OK) saslfail(r, "generating mechanism list");
+       dprintf(1, "%d mechanisms\n", count);
+    }
+
+    /* send capability list to client */
+    send_string(out, data, len);
+
+    dprintf(1, "waiting for client mechanism...\n");
+    len = recv_string(in, chosenmech, sizeof chosenmech);
+    if (len <= 0) {
+       printf("client didn't choose mechanism\n");
+       fputc('N', out); /* send NO to client */
+       fflush(out);
+       return -1;
+    }
+
+    if (mech && strcasecmp(mech, chosenmech)) {
+       printf("client didn't choose mandatory mechanism\n");
+       fputc('N', out); /* send NO to client */
+       fflush(out);
+       return -1;
+    }
+
+    len = recv_string(in, buf, sizeof(buf));
+    if(len != 1) {
+       saslerr(r, "didn't receive first-send parameter correctly");
+       fputc('N', out);
+       fflush(out);
+       return -1;
+    }
+
+    if(buf[0] == 'Y') {
+        /* receive initial response (if any) */
+        len = recv_string(in, buf, sizeof(buf));
+
+        /* start libsasl negotiation */
+        r = sasl_server_start(conn, chosenmech, buf, len,
+                             &data, &len);
+    } else {
+       r = sasl_server_start(conn, chosenmech, NULL, 0,
+                             &data, &len);
+    }
+    
+    if (r != SASL_OK && r != SASL_CONTINUE) {
+       saslerr(r, "starting SASL negotiation");
+       fputc('N', out); /* send NO to client */
+       fflush(out);
+       return -1;
+    }
+
+    while (r == SASL_CONTINUE) {
+       if (data) {
+           dprintf(2, "sending response length %d...\n", len);
+           fputc('C', out); /* send CONTINUE to client */
+           send_string(out, data, len);
+       } else {
+           dprintf(2, "sending null response...\n");
+           fputc('C', out); /* send CONTINUE to client */
+           send_string(out, "", 0);
+       }
+
+       dprintf(1, "waiting for client reply...\n");
+       len = recv_string(in, buf, sizeof buf);
+       if (len < 0) {
+           printf("client disconnected\n");
+           return -1;
+       }
+
+       r = sasl_server_step(conn, buf, len, &data, &len);
+       if (r != SASL_OK && r != SASL_CONTINUE) {
+           saslerr(r, "performing SASL negotiation");
+           fputc('N', out); /* send NO to client */
+           fflush(out);
+           return -1;
+       }
+    }
+
+    if (r != SASL_OK) {
+       saslerr(r, "incorrect authentication");
+       fputc('N', out); /* send NO to client */
+       fflush(out);
+       return -1;
+    }
+
+    fputc('O', out); /* send OK to client */
+    fflush(out);
+    dprintf(1, "negotiation complete\n");
+
+    r = sasl_getprop(conn, SASL_USERNAME, (const void **) &userid);
+    printf("successful authentication '%s'\n", userid);
+
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    int c;
+    char *port = "12345";
+    char *service = "rcmd";
+    int *l, maxfd=0;
+    int r, i;
+    sasl_conn_t *conn;
+
+    while ((c = getopt(argc, argv, "p:s:m:")) != EOF) {
+       switch(c) {
+       case 'p':
+           port = optarg;
+           break;
+
+       case 's':
+           service = optarg;
+           break;
+
+       case 'm':
+           mech = optarg;
+           break;
+
+       default:
+           usage();
+           break;
+       }
+    }
+
+    /* initialize the sasl library */
+    r = sasl_server_init(NULL, "sample");
+    if (r != SASL_OK) saslfail(r, "initializing libsasl");
+
+    /* get a listening socket */
+    if ((l = listensock(port, PF_UNSPEC)) == NULL) {
+       saslfail(SASL_FAIL, "allocating listensock");
+    }
+
+    for (i = 1; i <= l[0]; i++) {
+       if (l[i] > maxfd)
+           maxfd = l[i];
+    }
+
+    for (;;) {
+       char localaddr[NI_MAXHOST | NI_MAXSERV],
+            remoteaddr[NI_MAXHOST | NI_MAXSERV];
+       char myhostname[1024+1];
+       char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+       struct sockaddr_storage local_ip, remote_ip;
+       int niflags, error;
+       int salen;
+       int nfds, fd = -1;
+       FILE *in, *out;
+       fd_set readfds;
+
+       FD_ZERO(&readfds);
+       for (i = 1; i <= l[0]; i++)
+           FD_SET(l[i], &readfds);
+
+       nfds = select(maxfd + 1, &readfds, 0, 0, 0);
+       if (nfds <= 0) {
+           if (nfds < 0 && errno != EINTR)
+               perror("select");
+           continue;
+       }
+
+       for (i = 1; i <= l[0]; i++) 
+           if (FD_ISSET(l[i], &readfds)) {
+               fd = accept(l[i], NULL, NULL);
+               break;
+           }
+
+       if (fd < 0) {
+           if (errno != EINTR)
+               perror("accept");
+           continue;
+       }
+
+       printf("accepted new connection\n");
+
+       /* set ip addresses */
+       salen = sizeof(local_ip);
+       if (getsockname(fd, (struct sockaddr *)&local_ip, &salen) < 0) {
+           perror("getsockname");
+       }
+       niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+       if (((struct sockaddr *)&local_ip)->sa_family == AF_INET6)
+           niflags |= NI_WITHSCOPEID;
+#endif
+       error = getnameinfo((struct sockaddr *)&local_ip, salen, hbuf,
+                           sizeof(hbuf), pbuf, sizeof(pbuf), niflags);
+       if (error != 0) {
+           fprintf(stderr, "getnameinfo: %s\n", gai_strerror(error));
+           strcpy(hbuf, "unknown");
+           strcpy(pbuf, "unknown");
+       }
+        snprintf(localaddr, sizeof(localaddr), "%s;%s", hbuf, pbuf);
+
+       salen = sizeof(remote_ip);
+       if (getpeername(fd, (struct sockaddr *)&remote_ip, &salen) < 0) {
+           perror("getpeername");
+       }
+
+       niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+       if (((struct sockaddr *)&remote_ip)->sa_family == AF_INET6)
+           niflags |= NI_WITHSCOPEID;
+#endif
+       error = getnameinfo((struct sockaddr *)&remote_ip, salen, hbuf,
+                           sizeof(hbuf), pbuf, sizeof(pbuf), niflags);
+       if (error != 0) {
+           fprintf(stderr, "getnameinfo: %s\n", gai_strerror(error));
+           strcpy(hbuf, "unknown");
+           strcpy(pbuf, "unknown");
+       }
+       snprintf(remoteaddr, sizeof(remoteaddr), "%s;%s", hbuf, pbuf);
+
+       r = gethostname(myhostname, sizeof(myhostname)-1);
+       if(r == -1) saslfail(r, "getting hostname");
+
+       r = sasl_server_new(service, myhostname, NULL, localaddr, remoteaddr,
+                           NULL, 0, &conn);
+       if (r != SASL_OK) saslfail(r, "allocating connection state");
+
+       /* set external properties here
+          sasl_setprop(conn, SASL_SSF_EXTERNAL, &extprops); */
+
+       /* set required security properties here
+          sasl_setprop(conn, SASL_SEC_PROPS, &secprops); */
+
+       in = fdopen(fd, "r");
+       out = fdopen(fd, "w");
+
+       r = mysasl_negotiate(in, out, conn);
+       if (r == SASL_OK) {
+           /* send/receive data */
+
+
+       }
+
+       printf("closing connection\n");
+       fclose(in);
+       fclose(out);
+       close(fd);
+       sasl_dispose(&conn);
+    }
+
+    sasl_done();
+}
diff --git a/saslauthd/AUTHORS b/saslauthd/AUTHORS
new file mode 100644 (file)
index 0000000..ecb1bec
--- /dev/null
@@ -0,0 +1,23 @@
+Tim Martin <tmartin@andrew.cmu.edu> wrote, debugged, and tested most of the
+code.
+
+Rob Siemborski <rjs3@andrew.cmu.edu> wrote the self-contained autoconf system.
+
+Larry Greenfield <leg+sasl@andrew.cmu.edu> talked a lot.
+
+Igor Brezac <igor@ipass.net> has done a good deal of work on the saslauthd
+LDAP module.
+
+Jeremy Rumpf <jrumpf@heavyload.net> implemented the credential cache, unified
+the different IPC methods under a common framework.
+
+Fabian Knittel <fknittel@gmx.de> wrote auth_pam plugin, based on
+Debian's pwcheck_pam daemon by Michael-John Turner <mj@debian.org>.
+
+saslauthd was originally contributed by Lyndon Nerenberg on
+behalf of MessagingDirect Ltd.
+
+getaddrinfo.c was written by Hajimu UMEMOTO <ume@mahoroba.org>
+which is based on the IPv6 code written by KIKUCHI Takahiro
+<kick@kyoto.wide.ad.jp>
+
diff --git a/saslauthd/COPYING b/saslauthd/COPYING
new file mode 100644 (file)
index 0000000..2b2c5b9
--- /dev/null
@@ -0,0 +1,44 @@
+/* CMU libsasl
+ * Tim Martin
+ * Rob Earhart
+ * Rob Siemborski
+ */
+/* 
+ * Copyright (c) 2001 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.
+ */
diff --git a/saslauthd/ChangeLog b/saslauthd/ChangeLog
new file mode 100644 (file)
index 0000000..d0fa31b
--- /dev/null
@@ -0,0 +1 @@
+Currently saslauthd changes are tracked in the main SASL ChangeLog.
diff --git a/saslauthd/INSTALL b/saslauthd/INSTALL
new file mode 100644 (file)
index 0000000..ed6ed2c
--- /dev/null
@@ -0,0 +1,3 @@
+Follow the install documentation for SASL.  (saslauthd will install as 
+a part of the regular Cyrus SASL distribution as long as you configure
+SASL with --with-saslauthd)
diff --git a/saslauthd/LDAP_SASLAUTHD b/saslauthd/LDAP_SASLAUTHD
new file mode 100644 (file)
index 0000000..86f24e5
--- /dev/null
@@ -0,0 +1,293 @@
+auth_ldap module for saslauthd
+------------------------------
+
+Saslauthd can use an LDAP directory for authentication/authorization.
+
+Sections:
+1. Build saslauthd with ldap support
+2. Start saslauthd with ldap
+3. Testing
+4. Parameters
+5. Examples
+6. Notes
+7. Todo
+8. Feedback
+8. Author
+
+
+1. BUILD SASLAUTHD WITH LDAP SUPPORT
+------------------------------------
+
+Ensure that you have the OpenLDAP (http://www.openldap.org) libraries 2.1 or
+higher.  Fetch the latest cyrus-sasl package, 2.1.17 or higher,
+ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.
+
+Unpack cyrus-sasl:
+gzip -dc cyrus-sasl-2.1.17.tar.gz | tar xf -
+or
+tar zxf cyrus-sasl-2.1.17.tar.gz (if your tar supportz gzip)
+
+cd cyrus-sasl-2.1.17
+./configure --with-ldap  (you may need to add other options, check doc/index.html for more)
+make
+make install
+
+
+2. START SASLAUTHD WITH LDAP
+----------------------------
+
+Create /usr/local/etc/saslauthd.conf and add the following (modify to fit your
+environment):
+ldap_servers: ldap://10.1.1.15/ ldap://10.1.1.25/
+ldap_bind_dn: cn=operator,ou=Profile,o=foo.com
+ldap_password: secret
+
+Do not specify ldap_bind_*/ldap_password if you want to bind anonymously to
+your ldap server(s). 
+
+Run saslauthd:
+saslauthd -a ldap
+
+If you want to specify a different configuration file, you can do something
+like:
+saslauthd -a ldap -O /etc/saslauthd.conf
+
+For more command line options, check 'man saslauthd'
+
+
+3. TESTING
+----------
+
+First build testsaslauthd:
+cd $sasl_src/saslauthd
+make testsaslauthd
+
+Run test utility:
+./testsaslauthd -u igor -p secret
+0: OK "Success."
+
+If you get output other then Success, turn debug level for the auth syslog
+facility and check the syslog file.  Hopefully this will give you enough
+information to make adjustements in the startup and/or configuration files.  
+
+
+4. PARAMETERS
+-------------
+
+The following are available ldap parameters.  There are quite a few of those,
+but only ldap_servers may need to be specified. The defaults for all other
+parameters are adequate for most installations.  
+
+Do not use quotes (\"\') in the parameter values.  The defaults are specified
+within the first set of <>.  There may be a second set of <> which provide
+available values.
+
+ldap_auth_method: <bind|fastbind> <bind|custom|fastbind>
+       Specify an authentication method.
+
+    The bind method uses the LDAP bind facility to verify the password.  The
+    bind method is not available when ldap_use_sasl is turned on.  In that case
+    saslauthd will use fastbind.
+
+    'bind' is the default auth method. When ldap_use_sasl is enabled,
+    'fastbind' is the default.
+
+    The custom method uses userPassword attribute to verify the password.
+    Suppored hashes: crypt, md5, smd5, sha and ssha.  Cleartext is supported as
+    well.
+
+    The fastbind method (when 'ldap_use_sasl: no') does away with the search
+    and an extra anonymous bind in auth_bind, but makes two assumptions:
+         1. Expanding the ldap_filter expression gives the user's fully-qualified DN
+         2. There is no cost to staying bound as a named user
+
+ldap_bind_dn: <none>
+       Specify DN (distinguished name) to bind to the LDAP directory.  Do not
+       specify this parameter for the anonymous bind.
+
+ldap_bind_pw: <none>
+       Alias for ldap_password.
+
+ldap_default_domain: <none>
+       Alias for ldap_default_realm.
+
+ldap_default_realm: <none>
+       The default realm is assigned to the %r token when realm is not
+       available.  See ldap_filter for more.
+
+ldap_deref: <none> <search|find|always|never>
+       Specify how aliases dereferencing is handled during search.
+
+ldap_filter: <uid=%u>
+       Specify a filter.  The following tokens can be used in the filter string:
+
+       %%   = %
+       %u   = user
+       %U   = user portion of %u (%U = test when %u = test@domain.tld)
+       %d   = domain portion of %u if available (%d = domain.tld when %u =
+              %test@domain.tld), otherwise same as %r
+       %1-9 = domain tokens (%1 = tld, %2 = domain when %d = domain.tld)
+       %s   = service
+       %r   = realm
+       %D   = user DN (available for group checks)
+       
+       The %u token has to be used at minimum for the filter to be useful.  If
+       ldap_auth_method is 'bind', the filter will search for the DN
+       (distinguished name) attribute.  Otherwise, the search will look for
+       the 'ldap_password_attr' (see below) attribute.
+
+ldap_group_attr: <uniqueMember>
+    Specify what attribute to compare the user DN against in the group. If
+    ldap_group_dn is not specified, this parameter is ignored.  If
+    ldap_group_match_method is not attr, this parameter is ignored.
+ldap_group_dn: <none>
+    If specified, the user has to be part of the group in order to authenticate
+    successfully.  Tokens described in 'ldap_filter' (see above) can be used
+    for substitution.
+
+ldap_group_filter: <none>
+    Specify a filter. If a filter match is found then the user is in the group.
+    Tokens described in 'ldap_filter' (see above) can be used for for
+    substitution. If ldap_group_dn is not specified, this parameter is ignored.
+    If ldap_group_match_method is not filter, this parameter is ignored.
+
+ldap_group_match_method: <attr> <attr|filter>
+    Specify whether the group match method uses ldap_group_attr or
+    ldap_group_search.  If ldap_group_dn is not specified, this parameter is
+    ignored.
+
+ldap_group_search_base: <if not specified, it defaults to ldap_search_base>
+    Specify a starting point for the group search: e.g. dc=foo,dc=com.  Tokens
+    described in 'ldap_filter' (see below) can be used for substitution.
+
+ldap_group_scope: <sub> <sub|one|base>
+       Group search scope.
+
+ldap_password: <none>
+       Specify the password for ldap_bind_dn or ldap_id if
+       ldap_use_sasl is turned on.  Do not specify this parameter for the
+       anonymous bind.
+
+ldap_password_attr: <userPassword>
+        Specify what password attribute to use for password verification.
+ldap_referrals: <no>
+       Specify whether or not the client should follow referrals.
+
+ldap_restart: <yes>
+       Specify whether or not LDAP I/O operations are automatically restarted
+       if they abort prematurely.
+
+ldap_id: <none>
+       Specify the authentication ID for SASL bind.
+
+ldap_authz_id: <none>
+       Specify the proxy authorization ID for SASL bind.
+
+ldap_mech: <none>
+       Specify the authentication mechanism for SASL bind.
+
+ldap_realm: <none>
+       Specify the realm of authentication ID for SASL bind.
+
+ldap_scope: <sub> <sub|one|base>
+       Search scope.
+
+ldap_search_base: <none>
+       Specify a starting point for the search: e.g. dc=foo,dc=com.  Tokens
+       described in 'ldap_filter' (see below) can be used for substitution.
+
+ldap_servers: <ldap://localhost/>
+       Specify URI(s) refering to LDAP server(s), e.g. ldaps://10.1.1.2:999/.
+       You can specify multiple servers separated by a space.
+
+ldap_start_tls: <no>
+       Use StartTLS extended operation.  Do not use ldaps: ldap_servers when
+       this option is turned on.
+
+ldap_time_limit: <5>
+       Specify a number of seconds for a search request to complete.
+
+ldap_timeout: <5>
+       Specify a number of seconds a search can take before timing out.
+
+ldap_tls_check_peer: <no> <yes|no>
+       Require and verify server certificate.  If this option is yes,
+       you must specify ldap_tls_cacert_file or ldap_tls_cacert_dir.
+
+ldap_tls_cacert_file: <none>
+       File containing CA (Certificate Authority) certificate(s).
+
+ldap_tls_cacert_dir: <none>
+       Path to directory with CA (Certificate Authority) certificates.
+
+ldap_tls_ciphers: <DEFAULT>
+       List of SSL/TLS ciphers to allow.  The format of the string is
+       described in ciphers(1).
+
+ldap_tls_cert: <none>
+       File containing the client certificate.
+
+ldap_tls_key: <none>
+       File containing the private client key.
+
+ldap_use_sasl: <no>
+       Use SASL bind rather than simple bind when connecting to the ldap
+       server.
+
+ldap_version: <3> <2|3>
+       Specify the LDAP protocol version.  If ldap_start_tls and/or
+       ldap_use_sasl are enabled, ldap_version will be automatiacally set to
+       3.
+
+5. NOTES
+--------
+
+For better performance ensure that the attributes specified in ldap_filter are
+indexed.
+
+My testing shows that 'custom' is 2-3 times faster than 'bind'
+ldap_auth_method.  The 'fastbind' auth_method is just as fast or faster.  The
+slower performace of the 'bind' auth_method is caused by two extra calls to
+ldap_bind() per each authentication.
+
+SASL bind should be used with the 'fastbind' auth_method:
+
+ldap_servers: ldaps://10.1.1.2/
+ldap_use_sasl: yes
+ldap_mech: DIGEST_MD5
+ldap_auth_method: fastbind
+
+At this time this is not the best performing solution because openldap (2.1.x)
+cannot reuse existing connection for multiple ldap_sasl_bind()s.  This will
+hopefully change when openldap 2.2 comes out.
+
+6. TODO
+-------
+
+- Port to other ldap libraries
+- There may be bind problems when following referrals.  Normally this is not an
+  issue.
+- Allow to specify an attribute other than userPassword for use in the custom
+  authentication method. (Done)
+- Add more password hashes such as md5, sha etc (Done)
+- Make a suggestion (possibly another authentication method?) (added fastbind)
+  thanks to Simon Brady <simon.brady@otago.ac.nz>
+
+
+7. FEEDBACK
+-----------
+
+Feedback is much appreciated!  Please drop me a note if you are successfully
+using ldap-enabled saslauthd.  Any code improvements and/or suggestion are welcome.
+
+If you have questions, send email to cyrus-sasl@lists.andrew.cmu.edu.  Please
+include relevant information about your saslauthd setup: at minimum provide
+your saslauth.conf, output from syslog and which directory server you're using.
+
+
+8. AUTHOR
+---------
+
+Igor Brezac <igor@ipass.net>.
diff --git a/saslauthd/Makefile.am b/saslauthd/Makefile.am
new file mode 100644 (file)
index 0000000..ce1e92b
--- /dev/null
@@ -0,0 +1,39 @@
+AUTOMAKE_OPTIONS = 1.7
+sbin_PROGRAMS  = saslauthd testsaslauthd
+EXTRA_PROGRAMS  = saslcache
+
+saslauthd_SOURCES = mechanisms.c globals.h \
+                   mechanisms.h auth_dce.c auth_dce.h auth_getpwent.c \
+                   auth_getpwent.h auth_krb5.c auth_krb5.h auth_krb4.c \
+                   auth_krb4.h auth_pam.c auth_pam.h auth_rimap.c auth_httpform.c \
+                   auth_rimap.h auth_shadow.c auth_shadow.h auth_sia.c auth_httpform.h \
+                   auth_sia.h auth_sasldb.c auth_sasldb.h lak.c lak.h \
+                   auth_ldap.c auth_ldap.h cache.c cache.h cfile.c cfile.h \
+                   krbtf.c krbtf.h utils.c utils.h \
+                    ipc_unix.c ipc_doors.c saslauthd-main.c saslauthd-main.h \
+                   md5.c saslauthd_md5.h md5global.h 
+EXTRA_saslauthd_sources = getaddrinfo.c getnameinfo.c
+saslauthd_DEPENDENCIES = saslauthd-main.o @LTLIBOBJS@
+saslauthd_LDADD        = @SASL_KRB_LIB@ \
+                 @GSSAPIBASE_LIBS@ @GSSAPI_LIBS@ @LIB_CRYPT@ @LIB_SIA@ \
+                 @LIB_SOCKET@ @SASL_DB_LIB@ @LIB_PAM@ @LDAP_LIBS@ @LTLIBOBJS@
+
+testsaslauthd_SOURCES = testsaslauthd.c utils.c
+testsaslauthd_LDADD = @LIB_SOCKET@
+
+saslcache_SOURCES = saslcache.c
+
+EXTRA_DIST     = saslauthd.8 saslauthd.mdoc config include \
+                 getnameinfo.c getaddrinfo.c LDAP_SASLAUTHD
+INCLUDES       = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/../include
+DEFS            = @DEFS@ -DSASLAUTHD_CONF_FILE_DEFAULT=\"@sysconfdir@/saslauthd.conf\" -I. -I$(srcdir) -I..
+
+
+dist-hook: saslauthd.8
+
+saslauthd.8: saslauthd.mdoc
+       nroff -mdoc $(srcdir)/saslauthd.mdoc > $(srcdir)/saslauthd.8
+
+install-data-local: saslauthd.8
+       $(mkinstalldirs) $(DESTDIR)$(mandir)/man8
+       $(INSTALL_DATA) $(srcdir)/saslauthd.8 $(DESTDIR)$(mandir)/man8/saslauthd.8
diff --git a/saslauthd/Makefile.in b/saslauthd/Makefile.in
new file mode 100644 (file)
index 0000000..9903a65
--- /dev/null
@@ -0,0 +1,628 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@ -DSASLAUTHD_CONF_FILE_DEFAULT=\"@sysconfdir@/saslauthd.conf\" -I. -I$(srcdir) -I..
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDAP_LIBS = @LDAP_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_PAM = @LIB_PAM@
+LIB_SIA = @LIB_SIA@
+LIB_SOCKET = @LIB_SOCKET@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAIN_COMPAT_OBJ = @MAIN_COMPAT_OBJ@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AUTOMAKE_OPTIONS = 1.7
+sbin_PROGRAMS = saslauthd testsaslauthd
+EXTRA_PROGRAMS = saslcache
+
+saslauthd_SOURCES = mechanisms.c globals.h \
+                   mechanisms.h auth_dce.c auth_dce.h auth_getpwent.c \
+                   auth_getpwent.h auth_krb5.c auth_krb5.h auth_krb4.c \
+                   auth_krb4.h auth_pam.c auth_pam.h auth_rimap.c auth_httpform.c \
+                   auth_rimap.h auth_shadow.c auth_shadow.h auth_sia.c auth_httpform.h \
+                   auth_sia.h auth_sasldb.c auth_sasldb.h lak.c lak.h \
+                   auth_ldap.c auth_ldap.h cache.c cache.h cfile.c cfile.h \
+                   krbtf.c krbtf.h utils.c utils.h \
+                    ipc_unix.c ipc_doors.c saslauthd-main.c saslauthd-main.h \
+                   md5.c saslauthd_md5.h md5global.h 
+
+EXTRA_saslauthd_sources = getaddrinfo.c getnameinfo.c
+saslauthd_DEPENDENCIES = saslauthd-main.o @LTLIBOBJS@
+saslauthd_LDADD = @SASL_KRB_LIB@ \
+                 @GSSAPIBASE_LIBS@ @GSSAPI_LIBS@ @LIB_CRYPT@ @LIB_SIA@ \
+                 @LIB_SOCKET@ @SASL_DB_LIB@ @LIB_PAM@ @LDAP_LIBS@ @LTLIBOBJS@
+
+
+testsaslauthd_SOURCES = testsaslauthd.c utils.c
+testsaslauthd_LDADD = @LIB_SOCKET@
+
+saslcache_SOURCES = saslcache.c
+
+EXTRA_DIST = saslauthd.8 saslauthd.mdoc config include \
+                 getnameinfo.c getaddrinfo.c LDAP_SASLAUTHD
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include -I$(top_srcdir)/../include
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = saslauthd.h
+CONFIG_CLEAN_FILES =
+EXTRA_PROGRAMS = saslcache$(EXEEXT)
+sbin_PROGRAMS = saslauthd$(EXEEXT) testsaslauthd$(EXEEXT)
+PROGRAMS = $(sbin_PROGRAMS)
+
+am_saslauthd_OBJECTS = mechanisms.$(OBJEXT) auth_dce.$(OBJEXT) \
+       auth_getpwent.$(OBJEXT) auth_krb5.$(OBJEXT) auth_krb4.$(OBJEXT) \
+       auth_pam.$(OBJEXT) auth_rimap.$(OBJEXT) auth_httpform.$(OBJEXT) \
+       auth_shadow.$(OBJEXT) auth_sia.$(OBJEXT) auth_sasldb.$(OBJEXT) \
+       lak.$(OBJEXT) auth_ldap.$(OBJEXT) cache.$(OBJEXT) \
+       cfile.$(OBJEXT) krbtf.$(OBJEXT) utils.$(OBJEXT) \
+       ipc_unix.$(OBJEXT) ipc_doors.$(OBJEXT) saslauthd-main.$(OBJEXT) \
+       md5.$(OBJEXT)
+saslauthd_OBJECTS = $(am_saslauthd_OBJECTS)
+saslauthd_LDFLAGS =
+am_saslcache_OBJECTS = saslcache.$(OBJEXT)
+saslcache_OBJECTS = $(am_saslcache_OBJECTS)
+saslcache_LDADD = $(LDADD)
+saslcache_DEPENDENCIES =
+saslcache_LDFLAGS =
+am_testsaslauthd_OBJECTS = testsaslauthd.$(OBJEXT) utils.$(OBJEXT)
+testsaslauthd_OBJECTS = $(am_testsaslauthd_OBJECTS)
+testsaslauthd_DEPENDENCIES =
+testsaslauthd_LDFLAGS =
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I.
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = $(DEPDIR)/getaddrinfo.Plo \
+@AMDEP_TRUE@   $(DEPDIR)/getnameinfo.Plo ./$(DEPDIR)/auth_dce.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_getpwent.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_httpform.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_krb4.Po ./$(DEPDIR)/auth_krb5.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_ldap.Po ./$(DEPDIR)/auth_pam.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_rimap.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_sasldb.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/auth_shadow.Po ./$(DEPDIR)/auth_sia.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/cache.Po ./$(DEPDIR)/cfile.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/ipc_doors.Po ./$(DEPDIR)/ipc_unix.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/krbtf.Po ./$(DEPDIR)/lak.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/md5.Po ./$(DEPDIR)/mechanisms.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/saslauthd-main.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/saslcache.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/testsaslauthd.Po ./$(DEPDIR)/utils.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(saslauthd_SOURCES) $(saslcache_SOURCES) \
+       $(testsaslauthd_SOURCES)
+DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/configure AUTHORS \
+       COPYING ChangeLog INSTALL Makefile.am NEWS aclocal.m4 \
+       config/config.guess config/config.sub config/depcomp \
+       config/install-sh config/ltconfig config/ltmain.sh \
+       config/missing config/mkinstalldirs configure configure.in \
+       getaddrinfo.c getnameinfo.c saslauthd.h.in
+SOURCES = $(saslauthd_SOURCES) $(saslcache_SOURCES) $(testsaslauthd_SOURCES)
+
+all: saslauthd.h
+       $(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
+
+$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure:  $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+$(ACLOCAL_M4):  configure.in 
+       cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+saslauthd.h: stamp-h1
+       @if test ! -f $@; then \
+         rm -f stamp-h1; \
+         $(MAKE) stamp-h1; \
+       else :; fi
+
+stamp-h1: $(srcdir)/saslauthd.h.in $(top_builddir)/config.status
+       @rm -f stamp-h1
+       cd $(top_builddir) && $(SHELL) ./config.status saslauthd.h
+
+$(srcdir)/saslauthd.h.in:  $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       touch $(srcdir)/saslauthd.h.in
+
+distclean-hdr:
+       -rm -f saslauthd.h stamp-h1
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(sbindir)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
+          $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-sbinPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
+         rm -f $(DESTDIR)$(sbindir)/$$f; \
+       done
+
+clean-sbinPROGRAMS:
+       -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+saslauthd$(EXEEXT): $(saslauthd_OBJECTS) $(saslauthd_DEPENDENCIES) 
+       @rm -f saslauthd$(EXEEXT)
+       $(LINK) $(saslauthd_LDFLAGS) $(saslauthd_OBJECTS) $(saslauthd_LDADD) $(LIBS)
+saslcache$(EXEEXT): $(saslcache_OBJECTS) $(saslcache_DEPENDENCIES) 
+       @rm -f saslcache$(EXEEXT)
+       $(LINK) $(saslcache_LDFLAGS) $(saslcache_OBJECTS) $(saslcache_LDADD) $(LIBS)
+testsaslauthd$(EXEEXT): $(testsaslauthd_OBJECTS) $(testsaslauthd_DEPENDENCIES) 
+       @rm -f testsaslauthd$(EXEEXT)
+       $(LINK) $(testsaslauthd_LDFLAGS) $(testsaslauthd_OBJECTS) $(testsaslauthd_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getaddrinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/getnameinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_dce.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_getpwent.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_httpform.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_krb4.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_krb5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_ldap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_pam.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_rimap.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_sasldb.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_shadow.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/auth_sia.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfile.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_doors.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_unix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krbtf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lak.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mechanisms.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saslauthd-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saslcache.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsaslauthd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utils.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES) saslauthd.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS) saslauthd.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES) saslauthd.h.in $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS) saslauthd.h.in $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = .
+distdir = $(PACKAGE)-$(VERSION)
+
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+
+distdir: $(DISTFILES)
+       $(am__remove_distdir)
+       mkdir $(distdir)
+       $(mkinstalldirs) $(distdir)/config
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+       $(MAKE) $(AM_MAKEFLAGS) \
+         top_distdir="$(top_distdir)" distdir="$(distdir)" \
+         dist-hook
+       -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+         ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+         ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+       || chmod -R a+r $(distdir)
+dist-gzip: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+dist dist-all: distdir
+       $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+       $(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       $(am__remove_distdir)
+       GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
+       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       mkdir $(distdir)/_build
+       mkdir $(distdir)/_inst
+       chmod a-w $(distdir)
+       dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+         && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+         && cd $(distdir)/_build \
+         && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+           $(DISTCHECK_CONFIGURE_FLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+         && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+               distuninstallcheck \
+         && chmod -R a-w "$$dc_install_base" \
+         && ({ \
+              (cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+              && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+                   distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+             } || { rm -rf "$$dc_destdir"; exit 1; }) \
+         && rm -rf "$$dc_destdir" \
+         && $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
+         && rm -f $(distdir).tar.gz \
+         && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+       $(am__remove_distdir)
+       @echo "$(distdir).tar.gz is ready for distribution" | \
+         sed 'h;s/./=/g;p;x;p;x'
+distuninstallcheck:
+       @cd $(distuninstallcheck_dir) \
+       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+          || { echo "ERROR: files left after uninstall:" ; \
+               if test -n "$(DESTDIR)"; then \
+                 echo "  (check DESTDIR support)"; \
+               fi ; \
+               $(distuninstallcheck_listfiles) ; \
+               exit 1; } >&2
+distcleancheck: distclean
+       @if test '$(srcdir)' = . ; then \
+         echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+         exit 1 ; \
+       fi
+       @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+         || { echo "ERROR: files left in build directory after distclean:" ; \
+              $(distcleancheck_listfiles) ; \
+              exit 1; } >&2
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) saslauthd.h
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(sbindir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(DEPDIR) ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic distclean-hdr \
+       distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local
+
+install-exec-am: install-sbinPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf $(top_srcdir)/autom4te.cache
+       -rm -rf $(DEPDIR) ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-sbinPROGRAMS ctags dist dist-all dist-gzip distcheck \
+       distclean distclean-compile distclean-generic distclean-hdr \
+       distclean-tags distcleancheck distdir distuninstallcheck dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-data-local install-exec install-exec-am \
+       install-info install-info-am install-man install-sbinPROGRAMS \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-sbinPROGRAMS
+
+
+dist-hook: saslauthd.8
+
+saslauthd.8: saslauthd.mdoc
+       nroff -mdoc $(srcdir)/saslauthd.mdoc > $(srcdir)/saslauthd.8
+
+install-data-local: saslauthd.8
+       $(mkinstalldirs) $(DESTDIR)$(mandir)/man8
+       $(INSTALL_DATA) $(srcdir)/saslauthd.8 $(DESTDIR)$(mandir)/man8/saslauthd.8
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/saslauthd/NEWS b/saslauthd/NEWS
new file mode 100644 (file)
index 0000000..79b9a36
--- /dev/null
@@ -0,0 +1,3 @@
+New in v1.1.0
+-----------------
+- saslauthd now configures as a separate package.
diff --git a/saslauthd/README b/saslauthd/README
new file mode 100644 (file)
index 0000000..f3184b6
--- /dev/null
@@ -0,0 +1,4 @@
+This directory contains the saslauthd daemon.  Similar to pwcheck, it
+allows password verification from a separate process.
+
+For more information, consult the main Cyrus SASL documentation.
diff --git a/saslauthd/aclocal.m4 b/saslauthd/aclocal.m4
new file mode 100644 (file)
index 0000000..a186b35
--- /dev/null
@@ -0,0 +1,2990 @@
+# generated automatically by aclocal 1.7.9 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# AM_CONDITIONAL                                              -*- Autoconf -*-
+
+# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 5
+
+AC_PREREQ(2.52)
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+        [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.])
+fi])])
+
+# Do all the work for Automake.                            -*- Autoconf -*-
+
+# This macro actually does too much some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 10
+
+AC_PREREQ([2.54])
+
+# Autoconf 2.50 wants to disallow AM_ names.  We explicitly allow
+# the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_MISSING_PROG(AMTAR, tar)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# Copyright 2002  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION so it can be traced.
+# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+        [AM_AUTOMAKE_VERSION([1.7.9])])
+
+# Helper functions for option handling.                    -*- Autoconf -*-
+
+# Copyright 2001, 2002  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+#  -*- Autoconf -*-
+
+
+# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 3
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# AM_AUX_DIR_EXPAND
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+# Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_AUX_DIR_EXPAND], [
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+AC_SUBST(install_sh)])
+
+# AM_PROG_INSTALL_STRIP
+
+# Copyright 2001 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+#                                                          -*- Autoconf -*-
+# Copyright (C) 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# serial 5                                             -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      : > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking Speeds up one-time builds
+  --enable-dependency-tracking  Do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])
+])
+
+# Generate code to set up dependency tracking.   -*- Autoconf -*-
+
+# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+#serial 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n -e '/^U = / s///p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n -e '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Check to see how 'make' treats includes.     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# serial 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+dnl init_automake.m4--cmulocal automake setup macro
+dnl Rob Earhart
+dnl $Id: init_automake.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+
+AC_DEFUN([CMU_INIT_AUTOMAKE], [
+       AC_REQUIRE([AM_INIT_AUTOMAKE])
+       ACLOCAL="$ACLOCAL -I \$(top_srcdir)/cmulocal"
+       ])
+
+dnl
+dnl $Id: c-attribute.m4,v 1.3 2003/10/08 20:35:24 rjs3 Exp $
+dnl
+
+dnl
+dnl Test for __attribute__
+dnl
+
+AC_DEFUN([CMU_C___ATTRIBUTE__], [
+AC_MSG_CHECKING(for __attribute__)
+AC_CACHE_VAL(ac_cv___attribute__, [
+AC_TRY_COMPILE([
+#include <stdlib.h>
+],
+[
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+  exit(1);
+}
+],
+ac_cv___attribute__=yes,
+ac_cv___attribute__=no)])
+if test "$ac_cv___attribute__" = "yes"; then
+  AC_DEFINE(HAVE___ATTRIBUTE__, 1, [define if your compiler has __attribute__])
+fi
+AC_MSG_RESULT($ac_cv___attribute__)
+])
+
+
+dnl
+dnl Additional macros for configure.in packaged up for easier theft.
+dnl $Id: cyrus.m4,v 1.4 2003/10/08 20:35:24 rjs3 Exp $
+dnl tjs@andrew.cmu.edu 6-may-1998
+dnl
+
+dnl It would be good if ANDREW_ADD_LIBPATH could detect if something was
+dnl already there and not redundantly add it if it is.
+
+dnl add -L(arg), and possibly (runpath switch)(arg), to LDFLAGS
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH], [
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$1 ${LDFLAGS}"
+  else
+       LDFLAGS="-L$1 $andrew_runpath_switch$1 ${LDFLAGS}"
+  fi
+])
+
+dnl add -L(1st arg), and possibly (runpath switch)(1st arg), to (2nd arg)
+dnl (so the runpath for shared libraries is set).
+AC_DEFUN([CMU_ADD_LIBPATH_TO], [
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       $2="-L$1 ${$2}"
+  else
+       $2="-L$1 ${$2} $andrew_runpath_switch$1"
+  fi
+])
+
+dnl runpath initialization
+AC_DEFUN([CMU_GUESS_RUNPATH_SWITCH], [
+   # CMU GUESS RUNPATH SWITCH
+  AC_CACHE_CHECK(for runpath switch, andrew_runpath_switch, [
+    # first, try -R
+    SAVE_LDFLAGS="${LDFLAGS}"
+    LDFLAGS="-R /usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-R"], [
+       LDFLAGS="-Wl,-rpath,/usr/lib"
+    AC_TRY_LINK([],[],[andrew_runpath_switch="-Wl,-rpath,"],
+    [andrew_runpath_switch="none"])
+    ])
+  LDFLAGS="${SAVE_LDFLAGS}"
+  ])])
+
+dnl bsd_sockets.m4--which socket libraries do we need? 
+dnl Derrick Brashear
+dnl from Zephyr
+dnl $Id: bsd_sockets.m4,v 1.10 2005/04/26 19:14:07 shadow Exp $
+
+dnl Hacked on by Rob Earhart to not just toss stuff in LIBS
+dnl It now puts everything required for sockets into LIB_SOCKET
+
+AC_DEFUN([CMU_SOCKETS], [
+       save_LIBS="$LIBS"
+       LIB_SOCKET=""
+       AC_CHECK_FUNC(connect, :,
+               AC_CHECK_LIB(nsl, gethostbyname,
+                            LIB_SOCKET="-lnsl $LIB_SOCKET")
+               AC_CHECK_LIB(socket, connect,
+                            LIB_SOCKET="-lsocket $LIB_SOCKET")
+       )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNC(res_search, :,
+               LIBS="-lresolv $LIB_SOCKET $save_LIBS"
+               AC_TRY_LINK([[
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>]],[[
+const char host[12]="openafs.org";
+u_char ans[1024];
+res_search( host, C_IN, T_MX, (u_char *)&ans, sizeof(ans));
+return 0;
+]], LIB_SOCKET="-lresolv $LIB_SOCKET")
+        )
+       LIBS="$LIB_SOCKET $save_LIBS"
+       AC_CHECK_FUNCS(dn_expand dns_lookup)
+       LIBS="$save_LIBS"
+       AC_SUBST(LIB_SOCKET)
+       ])
+
+dnl
+dnl macros for configure.in to detect openssl
+dnl $Id: openssl.m4,v 1.11 2006/05/17 18:30:19 murch Exp $
+dnl
+
+AC_DEFUN([CMU_HAVE_OPENSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(openssl,[  --with-openssl=PATH     use OpenSSL from PATH],
+       with_openssl=$withval, with_openssl="yes")
+
+       save_CPPFLAGS=$CPPFLAGS
+       save_LDFLAGS=$LDFLAGS
+
+       if test -d $with_openssl; then
+         CPPFLAGS="${CPPFLAGS} -I${with_openssl}/include"
+         CMU_ADD_LIBPATH(${with_openssl}/$CMU_LIB_SUBDIR)
+       fi
+
+case "$with_openssl" in
+       no)
+         with_openssl="no";;
+       *) 
+         dnl if openssl has been compiled with the rsaref2 libraries,
+         dnl we need to include the rsaref libraries in the crypto check
+                LIB_RSAREF=""
+               AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                       cmu_have_rsaref=yes;
+                       [AC_CHECK_LIB(RSAglue, RSAPublicEncrypt,
+                               LIB_RSAREF="-lRSAglue -lrsaref",
+                               LIB_RSAREF="-lrsaref")],
+                       cmu_have_rsaref=no)
+
+               AC_CHECK_HEADER(openssl/evp.h, [
+                       AC_CHECK_LIB(crypto, EVP_DigestInit,
+                                       with_openssl="yes",
+                                       with_openssl="no", $LIB_RSAREF)],
+                       with_openssl=no)
+               ;;
+esac
+
+       if test "$with_openssl" != "no"; then
+               AC_DEFINE(HAVE_OPENSSL,[],[Do we have OpenSSL?])
+       else
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+       fi
+])
+
+dnl $Id: common.m4,v 1.13 2006/02/25 18:29:46 cg2v Exp $
+
+AC_DEFUN([CMU_TEST_LIBPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_lib, <<- *>>, <<__p>>))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/lib$2.a" -a \! -r "$1/lib$2.so" -a \! -r "$1/lib$2.sl" -a \! -r "$1/lib$2.dylib"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+AC_DEFUN([CMU_TEST_INCPATH], [
+changequote(<<, >>)
+define(<<CMU_AC_CV_FOUND>>, translit(ac_cv_found_$2_inc, [ *], [_p]))
+changequote([, ])
+if test "$CMU_AC_CV_FOUND" = "yes"; then
+  if test \! -r "$1/$2.h"; then
+    CMU_AC_CV_FOUND=no
+  fi
+fi
+])
+
+dnl CMU_CHECK_HEADER_NOCACHE(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+AC_DEFUN([CMU_CHECK_HEADER_NOCACHE],
+[dnl Do the transliteration at runtime so arg 1 can be a shell variable.
+ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
+AC_MSG_CHECKING([for $1])
+AC_TRY_CPP([#include <$1>], eval "ac_cv_header_$ac_safe=yes",
+  eval "ac_cv_header_$ac_safe=no")
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  AC_MSG_RESULT(yes)
+  ifelse([$2], , :, [$2])
+else
+  AC_MSG_RESULT(no)
+ifelse([$3], , , [$3
+])dnl
+fi
+])
+
+AC_DEFUN([CMU_FIND_LIB_SUBDIR],
+[dnl
+AC_ARG_WITH([lib-subdir], AC_HELP_STRING([--with-lib-subdir=DIR],[Find libraries in DIR instead of lib]))
+AC_CHECK_SIZEOF(long)
+AC_CACHE_CHECK([what directory libraries are found in], [ac_cv_cmu_lib_subdir],
+[test "X$with_lib_subdir" = "Xyes" && with_lib_subdir=
+test "X$with_lib_subdir" = "Xno" && with_lib_subdir=
+if test "X$with_lib_subdir" = "X" ; then
+  ac_cv_cmu_lib_subdir=lib
+  if test $ac_cv_sizeof_long -eq 4 ; then
+    test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32
+  fi
+  if test $ac_cv_sizeof_long -eq 8 ; then
+    test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64
+  fi
+else
+  ac_cv_cmu_lib_subdir=$with_lib_subdir
+fi])
+AC_SUBST(CMU_LIB_SUBDIR, $ac_cv_cmu_lib_subdir)
+])
+
+dnl checking for kerberos 4 libraries (and DES)
+
+AC_DEFUN([SASL_DES_CHK], [
+AC_ARG_WITH(des, [  --with-des=DIR          with DES (look in DIR) [yes] ],
+       with_des=$withval,
+       with_des=yes)
+
+LIB_DES=""
+if test "$with_des" != no; then
+  if test -d $with_des; then
+    CPPFLAGS="$CPPFLAGS -I${with_des}/include"
+    LDFLAGS="$LDFLAGS -L${with_des}/lib"
+  fi
+
+  if test "$with_openssl" != no; then
+    dnl check for openssl installing -lcrypto, then make vanilla check
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+
+    dnl same test again, different symbol name
+    if test "$with_des" = no; then
+      AC_CHECK_LIB(crypto, DES_cbc_encrypt, [
+        AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)],
+        with_des=no, $LIB_RSAREF)
+    fi
+  fi
+
+  if test "$with_des" = no; then
+    AC_CHECK_LIB(des, des_cbc_encrypt, [LIB_DES="-ldes";
+                                        with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des425, des_cbc_encrypt, [LIB_DES="-ldes425";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+     AC_CHECK_LIB(des524, des_cbc_encrypt, [LIB_DES="-ldes524";
+                                       with_des=yes], with_des=no)
+  fi
+
+  if test "$with_des" = no; then
+    dnl if openssl is around, we might be able to use that for des
+
+    dnl if openssl has been compiled with the rsaref2 libraries,
+    dnl we need to include the rsaref libraries in the crypto check
+    LIB_RSAREF=""
+    AC_CHECK_LIB(rsaref, RSAPublicEncrypt,
+                 LIB_RSAREF="-lRSAglue -lrsaref"; cmu_have_rsaref=yes,
+                 cmu_have_rsaref=no)
+
+    AC_CHECK_LIB(crypto, des_cbc_encrypt, [
+       AC_CHECK_HEADER(openssl/des.h, [AC_DEFINE(WITH_SSL_DES,[],[Use OpenSSL DES Implementation])
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes],
+                       with_des=no)], 
+        with_des=no, $LIB_RSAREF)
+  fi
+fi
+
+if test "$with_des" != no; then
+  AC_DEFINE(WITH_DES,[],[Use DES])
+fi
+
+AC_SUBST(LIB_DES)
+])
+
+AC_DEFUN([SASL_KERBEROS_V4_CHK], [
+  AC_REQUIRE([SASL_DES_CHK])
+
+  AC_ARG_ENABLE(krb4, [  --enable-krb4           enable KERBEROS_V4 authentication [[no]] ],
+    krb4=$enableval,
+    krb4=no)
+
+  if test "$krb4" != no; then
+    dnl In order to compile kerberos4, we need libkrb and libdes.
+    dnl (We've already gotten libdes from SASL_DES_CHK)
+    dnl we might need -lresolv for kerberos
+    AC_CHECK_LIB(resolv,res_search)
+
+    dnl if we were ambitious, we would look more aggressively for the
+    dnl krb4 install
+    if test -d ${krb4}; then
+       AC_CACHE_CHECK(for Kerberos includes, cyrus_krbinclude, [
+         for krbhloc in include/kerberosIV include/kerberos include
+         do
+           if test -f ${krb4}/${krbhloc}/krb.h ; then
+             cyrus_krbinclude=${krb4}/${krbhloc}
+             break
+           fi
+         done
+         ])
+
+       if test -n "${cyrus_krbinclude}"; then
+         CPPFLAGS="$CPPFLAGS -I${cyrus_krbinclude}"
+       fi
+       LDFLAGS="$LDFLAGS -L$krb4/lib"
+    fi
+
+    if test "$with_des" != no; then
+      AC_CHECK_HEADER(krb.h, [
+        AC_CHECK_LIB(com_err, com_err, [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR="-lcom_err"; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES -lcom_err)], [
+         AC_CHECK_LIB(krb, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb"; krb4lib="yes"],
+                     krb4lib=no, $LIB_DES)])], krb4="no")
+
+      if test "$krb4" != "no" -a "$krb4lib" = "no"; then
+       AC_CHECK_LIB(krb4, krb_mk_priv,
+                     [COM_ERR=""; SASL_KRB_LIB="-lkrb4"; krb4=yes],
+                     krb4=no, $LIB_DES)
+      fi
+      if test "$krb4" = no; then
+          AC_WARN(No Kerberos V4 found)
+      fi
+    else
+      AC_WARN(No DES library found for Kerberos V4 support)
+      krb4=no
+    fi
+  fi
+
+  if test "$krb4" != no; then
+    cmu_save_LIBS="$LIBS"
+    LIBS="$LIBS $SASL_KRB_LIB"
+    AC_CHECK_FUNCS(krb_get_err_text)
+    LIBS="$cmu_save_LIBS"
+  fi
+
+  AC_MSG_CHECKING(KERBEROS_V4)
+  if test "$krb4" != no; then
+    AC_MSG_RESULT(enabled)
+    SASL_MECHS="$SASL_MECHS libkerberos4.la"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/kerberos4.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS kerberos4.o"
+    AC_DEFINE(STATIC_KERBEROS4,[],[User KERBEROS_V4 Staticly])
+    AC_DEFINE(HAVE_KRB,[],[Do we have Kerberos 4 Support?])
+    SASL_KRB_LIB="$SASL_KRB_LIB $LIB_DES $COM_ERR"
+  else
+    AC_MSG_RESULT(disabled)
+  fi
+  AC_SUBST(SASL_KRB_LIB)
+])
+
+
+# sasl2.m4--sasl2 libraries and includes
+# Rob Siemborski
+# $Id: sasl2.m4,v 1.52 2006/05/18 19:25:00 murch Exp $
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL_GSSAPI_CHK],
+[AC_REQUIRE([SASL2_CRYPT_CHK])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_ENABLE([gssapi],
+              [AC_HELP_STRING([--enable-gssapi=<DIR>],
+                              [enable GSSAPI authentication [yes]])],
+              [gssapi=$enableval],
+              [gssapi=yes])
+AC_ARG_WITH([gss_impl],
+            [AC_HELP_STRING([--with-gss_impl={heimdal|mit|cybersafe|seam|auto}],
+                            [choose specific GSSAPI implementation [[auto]]])],
+            [gss_impl=$withval],
+            [gss_impl=auto])
+
+if test "$gssapi" != no; then
+  platform=
+  case "${host}" in
+    *-*-linux*)
+      platform=__linux
+      ;;
+    *-*-hpux*)
+      platform=__hpux
+      ;;
+    *-*-irix*)
+      platform=__irix
+      ;;
+    *-*-solaris2*)
+# When should we use __sunos?
+      platform=__solaris
+      ;;
+    *-*-aix*)
+      platform=__aix
+      ;;
+    *)
+      AC_WARN([The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script])
+      if test "$gss_impl" = "cybersafe"; then
+        AC_ERROR([CyberSafe was forced, cannot continue as platform is not supported])
+      fi
+      ;;
+  esac
+
+  cmu_saved_CPPFLAGS=$CPPFLAGS
+
+  if test -d ${gssapi}; then
+    CPPFLAGS="$CPPFLAGS -I$gssapi/include"
+# We want to keep -I in our CPPFLAGS, but only if we succeed
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    LDFLAGS="$LDFLAGS -L$gssapi/lib"
+
+    if test -n "$platform"; then
+      if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+        CPPFLAGS="$CPPFLAGS -D$platform"
+        if test -d "${gssapi}/appsec-sdk/include"; then
+          CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+        fi
+      fi
+    fi
+  fi
+  AC_CHECK_HEADER([gssapi.h],
+                  [AC_DEFINE(HAVE_GSSAPI_H,,
+                             [Define if you have the gssapi.h header file])],
+                  [AC_CHECK_HEADER([gssapi/gssapi.h],,
+                                   [AC_WARN([Disabling GSSAPI - no include files found]); gssapi=no])])
+
+  CPPFLAGS=$cmu_saved_CPPFLAGS
+
+fi
+
+if test "$gssapi" != no; then
+  # We need to find out which gssapi implementation we are
+  # using. Supported alternatives are: MIT Kerberos 5,
+  # Heimdal Kerberos 5 (http://www.pdc.kth.se/heimdal),
+  # CyberSafe Kerberos 5 (http://www.cybersafe.com/)
+  # and Sun SEAM (http://wwws.sun.com/software/security/kerberos/)
+  #
+  # The choice is reflected in GSSAPIBASE_LIBS
+
+  AC_CHECK_LIB(resolv,res_search)
+  if test -d ${gssapi}; then
+     gssapi_dir="${gssapi}/lib"
+     GSSAPIBASE_LIBS="-L$gssapi_dir"
+     GSSAPIBASE_STATIC_LIBS="-L$gssapi_dir"
+  else
+     # FIXME: This is only used for building cyrus, and then only as
+     # a real hack.  it needs to be fixed.
+     gssapi_dir="/usr/local/lib"
+  fi
+
+  # Check a full link against the Heimdal libraries.
+  # If this fails, check a full link against the MIT libraries.
+  # If this fails, check a full link against the CyberSafe libraries.
+  # If this fails, check a full link against the Solaris 8 and up libgss.
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "heimdal"; then
+    gss_failed=0
+    AC_CHECK_LIB(gssapi,gss_unwrap,gss_impl="heimdal",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "mit"; then
+    # check for libkrb5support first
+    AC_CHECK_LIB(krb5support,krb5int_getspecific,K5SUP=-lkrb5support K5SUPSTATIC=$gssapi_dir/libkrb5support.a,,${LIB_SOCKET})
+
+    gss_failed=0
+    AC_CHECK_LIB(gssapi_krb5,gss_unwrap,gss_impl="mit",gss_failed=1,
+                 ${GSSAPIBASE_LIBS} -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP} ${LIB_SOCKET})
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  # For Cybersafe one has to set a platform define in order to make compilation work
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    cmu_saved_GSSAPIBASE_LIBS=$GSSAPIBASE_LIBS
+# FIXME - Note that the libraries are in .../lib64 for 64bit kernels
+    if test -d "${gssapi}/appsec-rt/lib"; then
+      GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -L${gssapi}/appsec-rt/lib"
+    fi
+    CPPFLAGS="$CPPFLAGS -D$platform"
+    if test -d "${gssapi}/appsec-sdk/include"; then
+      CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+    fi
+
+    gss_failed=0
+
+# Check for CyberSafe with two libraries first, than fall back to a single 
+# library (older CyberSafe)
+
+    unset ac_cv_lib_gss_csf_gss_acq_user
+    AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe03",
+                 [unset ac_cv_lib_gss_csf_gss_acq_user;
+                  AC_CHECK_LIB(gss,csf_gss_acq_user,gss_impl="cybersafe",
+                               gss_failed=1,$GSSAPIBASE_LIBS -lgss)],
+                 [${GSSAPIBASE_LIBS} -lgss -lcstbk5])
+
+    if test "$gss_failed" = "1"; then
+# Restore variables
+      GSSAPIBASE_LIBS=$cmu_saved_GSSAPIBASE_LIBS
+      CPPFLAGS=$cmu_saved_CPPFLAGS
+
+      if test "$gss_impl" != "auto"; then
+        gss_impl="failed"
+      fi
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "seam"; then
+    gss_failed=0
+    AC_CHECK_LIB(gss,gss_unwrap,gss_impl="seam",gss_failed=1,-lgss)
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "mit"; then
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}"
+  elif test "$gss_impl" = "heimdal"; then
+    CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}"
+  elif test "$gss_impl" = "cybersafe03"; then
+# Version of CyberSafe with two libraries
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss -lcstbk5"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "cybersafe"; then
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "seam"; then
+    GSSAPIBASE_LIBS=-lgss
+    # there is no static libgss on Solaris 8 and up
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "failed"; then
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - specified library not found])
+  else
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    AC_WARN([Disabling GSSAPI - no library])
+  fi
+fi
+
+#
+# Cybersafe defines both GSS_C_NT_HOSTBASED_SERVICE and GSS_C_NT_USER_NAME
+# in gssapi\rfckrb5.h
+#
+if test "$gssapi" != "no"; then
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(hostbased_service_gss_nt_yes,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_HOSTBASED_SERVICE
+                    hostbased_service_gss_nt_yes
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])],
+                 [AC_WARN([Cybersafe define not found])])
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_HOSTBASED_SERVICE, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_HOSTBASED_SERVICE,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE])])
+  fi
+
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    AC_EGREP_CPP(user_name_yes_gss_nt,
+                 [#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_USER_NAME
+                   user_name_yes_gss_nt
+                  #endif],
+                 [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                            [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])],
+                 [AC_WARN([Cybersafe define not found])])
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    AC_EGREP_HEADER(GSS_C_NT_USER_NAME, gssapi/gssapi.h,
+                    [AC_DEFINE(HAVE_GSS_C_NT_USER_NAME,,
+                               [Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME])])
+  fi
+fi
+
+GSSAPI_LIBS=""
+AC_MSG_CHECKING([GSSAPI])
+if test "$gssapi" != no; then
+  AC_MSG_RESULT([with implementation ${gss_impl}])
+  AC_CHECK_LIB(resolv,res_search,GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lresolv")
+  SASL_MECHS="$SASL_MECHS libgssapiv2.la"
+  SASL_STATIC_OBJS="$SASL_STATIC_OBJS gssapi.o"
+  SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/gssapi.c"
+
+  cmu_save_LIBS="$LIBS"
+  LIBS="$LIBS $GSSAPIBASE_LIBS"
+  AC_CHECK_FUNCS(gsskrb5_register_acceptor_identity)
+  LIBS="$cmu_save_LIBS"
+else
+  AC_MSG_RESULT([disabled])
+fi
+AC_SUBST(GSSAPI_LIBS)
+AC_SUBST(GSSAPIBASE_LIBS)
+])# SASL_GSSAPI_CHK
+
+
+# SASL_SET_GSSAPI_LIBS
+# --------------------
+AC_DEFUN([SASL_SET_GSSAPI_LIBS],
+[SASL_GSSAPI_LIBS_SET="yes"
+])
+
+
+# CMU_SASL2
+# ---------
+# What we want to do here is setup LIB_SASL with what one would
+# generally want to have (e.g. if static is requested, make it that,
+# otherwise make it dynamic.
+#
+# We also want to create LIB_DYN_SASL and DYNSASLFLAGS.
+#
+# Also sets using_static_sasl to "no" "static" or "staticonly"
+#
+AC_DEFUN([CMU_SASL2],
+[AC_REQUIRE([SASL_GSSAPI_CHK])
+
+AC_ARG_WITH(sasl,
+            [AC_HELP_STRING([--with-sasl=DIR],[Compile with libsasl2 in <DIR>])],
+            with_sasl="$withval",
+            with_sasl="yes")
+
+AC_ARG_WITH(staticsasl,
+            [AC_HELP_STRING([--with-staticsasl=DIR],
+                            [Compile with staticly linked libsasl2 in <DIR>])],
+            [with_staticsasl="$withval";
+             if test $with_staticsasl != "no"; then
+               using_static_sasl="static"
+             fi],
+            [with_staticsasl="no"; using_static_sasl="no"])
+
+SASLFLAGS=""
+LIB_SASL=""
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+cmu_saved_LDFLAGS=$LDFLAGS
+cmu_saved_LIBS=$LIBS
+
+if test ${with_staticsasl} != "no"; then
+  if test -d ${with_staticsasl}; then
+    if test -d ${with_staticsasl}/lib64 ; then
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib64
+    else
+      ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    fi
+    ac_cv_sasl_where_lib=${with_staticsasl}/lib
+    ac_cv_sasl_where_inc=${with_staticsasl}/include
+
+    SASLFLAGS="-I$ac_cv_sasl_where_inc"
+    LIB_SASL="-L$ac_cv_sasl_where_lib"
+    CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+    LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+  else
+    with_staticsasl="/usr"
+  fi
+
+  AC_CHECK_HEADER(sasl/sasl.h,
+                  [AC_CHECK_HEADER(sasl/saslutil.h,
+                                   [for i42 in lib64 lib; do
+                                      if test -r ${with_staticsasl}/$i42/libsasl2.a; then
+                                        ac_cv_found_sasl=yes
+                                        AC_MSG_CHECKING([for static libsasl])
+                                        LIB_SASL="$LIB_SASL ${with_staticsasl}/$i42/libsasl2.a"
+                                      fi
+                                    done
+                                    if test ! "$ac_cv_found_sasl" = "yes"; then
+                                      AC_MSG_CHECKING([for static libsasl])
+                                      AC_ERROR([Could not find ${with_staticsasl}/lib*/libsasl2.a])
+                                    fi])])
+
+  AC_MSG_RESULT([found])
+
+  if test "x$SASL_GSSAPI_LIBS_SET" = "x"; then
+    LIB_SASL="$LIB_SASL $GSSAPIBASE_STATIC_LIBS"
+  else
+    SASL_GSSAPI_LIBS_SET=""
+    cmu_saved_LIBS="$GSSAPIBASE_STATIC_LIBS $cmu_saved_LIBS" 
+  fi
+fi
+
+if test -d ${with_sasl}; then
+  ac_cv_sasl_where_lib=${with_sasl}/lib
+  ac_cv_sasl_where_inc=${with_sasl}/include
+
+  DYNSASLFLAGS="-I$ac_cv_sasl_where_inc"
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, LIB_DYN_SASL)
+  fi
+  LIB_DYN_SASL="$LIB_DYN_SASL -lsasl2"
+  CPPFLAGS="${cmu_saved_CPPFLAGS} -I${ac_cv_sasl_where_inc}"
+  LDFLAGS="${cmu_saved_LDFLAGS} -L${ac_cv_sasl_where_lib}"
+fi
+
+# be sure to check for a SASLv2 specific function
+AC_CHECK_HEADER(sasl/sasl.h,
+                [AC_CHECK_HEADER(sasl/saslutil.h,
+                                 [AC_CHECK_LIB(sasl2, prop_get, 
+                                               ac_cv_found_sasl=yes,
+                                               ac_cv_found_sasl=no)],
+                                 ac_cv_found_sasl=no)],
+                ac_cv_found_sasl=no)
+
+if test "$ac_cv_found_sasl" = "yes"; then
+  if test "$ac_cv_sasl_where_lib" != ""; then
+    CMU_ADD_LIBPATH_TO($ac_cv_sasl_where_lib, DYNLIB_SASL)
+  fi
+  DYNLIB_SASL="$DYNLIB_SASL -lsasl2"
+  if test "$using_static_sasl" != "static"; then
+    LIB_SASL=$DYNLIB_SASL
+    SASLFLAGS=$DYNSASLFLAGS
+  fi
+else
+  DYNLIB_SASL=""
+  DYNSASLFLAGS=""
+  using_static_sasl="staticonly"
+fi
+
+if test "x$SASL_GSSAPI_LIBS_SET" != "x"; then
+  SASL_GSSAPI_LIBS_SET=""
+  cmu_saved_LIBS="$GSSAPIBASE_LIBS $cmu_saved_LIBS" 
+fi
+
+LIBS="$cmu_saved_LIBS"
+LDFLAGS="$cmu_saved_LDFLAGS"
+CPPFLAGS="$cmu_saved_CPPFLAGS"
+
+AC_SUBST(LIB_DYN_SASL)
+AC_SUBST(DYNSASLFLAGS)
+AC_SUBST(LIB_SASL)
+AC_SUBST(SASLFLAGS)
+])# CMU_SASL2
+
+
+# CMU_SASL2_REQUIRED
+# ------------------
+AC_DEFUN([CMU_SASL2_REQUIRED],
+[AC_REQUIRE([CMU_SASL2])
+if test "$ac_cv_found_sasl" != "yes"; then
+  AC_ERROR([Cannot continue without libsasl2.
+Get it from ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.])
+fi])
+
+
+# CMU_SASL2_REQUIRE_VER
+# ---------------------
+AC_DEFUN([CMU_SASL2_REQUIRE_VER],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$CPPFLAGS $SASLFLAGS"
+
+AC_TRY_CPP([
+#include <sasl/sasl.h>
+
+#ifndef SASL_VERSION_MAJOR
+#error SASL_VERSION_MAJOR not defined
+#endif
+#ifndef SASL_VERSION_MINOR
+#error SASL_VERSION_MINOR not defined
+#endif
+#ifndef SASL_VERSION_STEP
+#error SASL_VERSION_STEP not defined
+#endif
+
+#if SASL_VERSION_MAJOR < $1 || SASL_VERSION_MINOR < $2 || SASL_VERSION_STEP < $3
+#error SASL version is less than $1.$2.$3
+#endif
+],,
+           [AC_ERROR([Incorrect SASL headers found.  This package requires SASL $1.$2.$3 or newer.])])
+
+CPPFLAGS=$cmu_saved_CPPFLAGS
+])# CMU_SASL2_REQUIRE_VER
+
+
+# CMU_SASL2_CHECKAPOP_REQUIRED
+# ----------------------------
+AC_DEFUN([CMU_SASL2_CHECKAPOP_REQUIRED],
+[AC_REQUIRE([CMU_SASL2_REQUIRED])
+
+cmu_saved_LDFLAGS=$LDFLAGS
+
+LDFLAGS="$LDFLAGS $LIB_SASL"
+
+AC_CHECK_LIB(sasl2, sasl_checkapop,
+             [AC_DEFINE(HAVE_APOP,[],[Does SASL support APOP?])],
+             [AC_MSG_ERROR([libsasl2 without working sasl_checkapop.  Cannot continue.])])
+
+LDFLAGS=$cmu_saved_LDFLAGS
+])# CMU_SASL2_CHECKAPOP_REQUIRED
+
+
+# SASL2_CRYPT_CHK
+# ---------------
+AC_DEFUN([SASL2_CRYPT_CHK],
+[AC_CHECK_FUNC(crypt, cmu_have_crypt=yes,
+               [AC_CHECK_LIB(crypt, crypt,
+                             LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes,
+                             cmu_have_crypt=no)])
+AC_SUBST(LIB_CRYPT)
+])# SASL2_CRYPT_CHK
+
+dnl Functions to check what database to use for libsasldb
+
+dnl Berkeley DB specific checks first..
+
+dnl Figure out what database type we're using
+AC_DEFUN([SASL_DB_CHECK], [
+cmu_save_LIBS="$LIBS"
+AC_ARG_WITH(dblib, [  --with-dblib=DBLIB      set the DB library to use [berkeley] ],
+  dblib=$withval,
+  dblib=auto_detect)
+
+CYRUS_BERKELEY_DB_OPTS()
+
+SASL_DB_LIB=""
+
+case "$dblib" in
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named.  arg.
+  berkeley)
+       CYRUS_BERKELEY_DB_CHK()
+       CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+       SASL_DB_INC=$BDB_INCADD
+       SASL_DB_LIB="${BDB_LIBADD}"
+       ;;
+  gdbm)
+       AC_ARG_WITH(gdbm,[  --with-gdbm=PATH        use gdbm from PATH],
+                    with_gdbm="${withval}")
+
+        case "$with_gdbm" in
+           ""|yes)
+               AC_CHECK_HEADER(gdbm.h, [
+                       AC_CHECK_LIB(gdbm, gdbm_open, SASL_DB_LIB="-lgdbm",
+                                           dblib="no")],
+                       dblib="no")
+               ;;
+           *)
+               if test -d $with_gdbm; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_gdbm}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_gdbm}/lib"
+                 SASL_DB_LIB="-lgdbm" 
+               else
+                 with_gdbm="no"
+               fi
+       esac
+       ;;
+  ndbm)
+       dnl We want to attempt to use -lndbm if we can, just in case
+       dnl there's some version of it installed and overriding libc
+       AC_CHECK_HEADER(ndbm.h, [
+                       AC_CHECK_LIB(ndbm, dbm_open, SASL_DB_LIB="-lndbm", [
+                               AC_CHECK_FUNC(dbm_open,,dblib="no")])],
+                               dblib="no")
+       ;;
+  auto_detect)
+        dnl How about berkeley db?
+       CYRUS_BERKELEY_DB_CHK()
+       if test "$dblib" = no; then
+         dnl How about ndbm?
+         AC_CHECK_HEADER(ndbm.h, [
+               AC_CHECK_LIB(ndbm, dbm_open,
+                            dblib="ndbm"; SASL_DB_LIB="-lndbm",
+                            dblib="weird")],
+                  dblib="no")
+         if test "$dblib" = "weird"; then
+           dnl Is ndbm in the standard library?
+            AC_CHECK_FUNC(dbm_open, dblib="ndbm", dblib="no")
+         fi
+
+         if test "$dblib" = no; then
+            dnl Can we use gdbm?
+           AC_CHECK_HEADER(gdbm.h, [
+               AC_CHECK_LIB(gdbm, gdbm_open, dblib="gdbm";
+                                            SASL_DB_LIB="-lgdbm", dblib="no")],
+                            dblib="no")
+         fi
+       else
+         dnl we took Berkeley
+         CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+         SASL_DB_INC=$BDB_INCADD
+          SASL_DB_LIB="${BDB_LIBADD}"
+       fi
+       ;;
+  none)
+       ;;
+  no)
+       ;;
+  *)
+       AC_MSG_WARN([Bad DB library implementation specified;])
+       AC_ERROR([Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"])
+       dblib=no
+       ;;
+esac
+LIBS="$cmu_save_LIBS"
+
+AC_MSG_CHECKING(DB library to use)
+AC_MSG_RESULT($dblib)
+
+SASL_DB_BACKEND="db_${dblib}.lo"
+SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
+SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_${dblib}.c ../sasldb/allockey.c"
+SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
+
+case "$dblib" in
+  gdbm) 
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_GDBM,[],[Use GDBM for SASLdb])
+    ;;
+  ndbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_NDBM,[],[Use NDBM for SASLdb])
+    ;;
+  berkeley)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+    AC_DEFINE(SASL_BERKELEYDB,[],[Use BerkeleyDB for SASLdb])
+    ;;
+  *)
+    AC_MSG_WARN([Disabling SASL authentication database support])
+    dnl note that we do not add libsasldb.la to SASL_MECHS, since it
+    dnl will just fail to load anyway.
+    SASL_DB_BACKEND="db_none.lo"
+    SASL_DB_BACKEND_STATIC="db_none.o"
+    SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_none.c"
+    SASL_DB_UTILS=""
+    SASL_DB_MANS=""
+    SASL_DB_LIB=""
+    ;;
+esac
+
+if test "$enable_static" = yes; then
+    if test "$dblib" != "none"; then
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sasldb.c $SASL_DB_BACKEND_STATIC_SRCS"
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS sasldb.o $SASL_DB_BACKEND_STATIC"
+      AC_DEFINE(STATIC_SASLDB,[],[Link SASLdb Staticly])
+    else
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS $SASL_DB_BACKEND_STATIC"
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS $SASL_DB_BACKEND_STATIC_SRCS"
+    fi
+fi
+
+AC_SUBST(SASL_DB_UTILS)
+AC_SUBST(SASL_DB_MANS)
+AC_SUBST(SASL_DB_BACKEND)
+AC_SUBST(SASL_DB_BACKEND_STATIC)
+AC_SUBST(SASL_DB_INC)
+AC_SUBST(SASL_DB_LIB)
+])
+
+dnl Figure out what database path we're using
+AC_DEFUN([SASL_DB_PATH_CHECK], [
+AC_ARG_WITH(dbpath, [  --with-dbpath=PATH      set the DB path to use [/etc/sasldb2] ],
+  dbpath=$withval,
+  dbpath=/etc/sasldb2)
+AC_MSG_CHECKING(DB path to use)
+AC_MSG_RESULT($dbpath)
+AC_DEFINE_UNQUOTED(SASL_DB_PATH, "$dbpath", [Path to default SASLdb database])])
+
+dnl $Id: berkdb.m4,v 1.20 2005/04/26 19:14:07 shadow Exp $
+
+AC_DEFUN([CMU_DB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <db.h>],
+[DB *db;
+db_create(&db, NULL, 0);
+db->open(db, "foo.db", NULL, DB_UNKNOWN, DB_RDONLY, 0644);],
+ac_cv_found_db_inc=yes,
+ac_cv_found_db_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_DB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db headers in $i)
+      CMU_DB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, db)
+      if test "$ac_cv_found_db_inc" = "yes"; then
+        ac_cv_db_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for lib files
+#
+
+AC_DEFUN([CMU_DB3_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+  LIBS="$saved_LIBS -L$1 -ldb-3"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_3_lib=yes],
+ac_cv_found_db_3_lib=no)
+LIBS=$saved_LIBS
+])
+AC_DEFUN([CMU_DB4_LIB_WHERE1], [
+AC_REQUIRE([CMU_AFS])
+AC_REQUIRE([CMU_KRB4])
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -ldb-4"
+AC_TRY_LINK([#include <db.h>],
+[db_env_create(NULL, 0);],
+[ac_cv_found_db_4_lib=yes],
+ac_cv_found_db_4_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_DB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for db libraries in $i)
+if test "$enable_db4" = "yes"; then
+      CMU_DB4_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-4])
+      ac_cv_found_db_lib=$ac_cv_found_db_4_lib
+else
+      CMU_DB3_LIB_WHERE1($i)
+      CMU_TEST_LIBPATH($i, [db-3])
+      ac_cv_found_db_lib=$ac_cv_found_db_3_lib
+fi
+      if test "$ac_cv_found_db_lib" = "yes" ; then
+        ac_cv_db_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_USE_DB], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_ARG_WITH(db,
+       [  --with-db=PREFIX      Compile with db support],
+       [if test "X$with_db" = "X"; then
+               with_db=yes
+       fi])
+AC_ARG_WITH(db-lib,
+       [  --with-db-lib=dir     use db libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-lib])
+       fi])
+AC_ARG_WITH(db-include,
+       [  --with-db-include=dir use db headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-db-include])
+       fi])
+AC_ARG_ENABLE(db4,
+       [  --enable-db4          use db 4.x libraries])
+       
+       if test "X$with_db" != "X"; then
+         if test "$with_db" != "yes"; then
+           ac_cv_db_where_lib=$with_db/$CMU_LIB_SUBDIR
+           ac_cv_db_where_inc=$with_db/include
+         fi
+       fi
+
+       if test "X$with_db_lib" != "X"; then
+         ac_cv_db_where_lib=$with_db_lib
+       fi
+       if test "X$ac_cv_db_where_lib" = "X"; then
+         CMU_DB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR)
+       fi
+
+       if test "X$with_db_include" != "X"; then
+         ac_cv_db_where_inc=$with_db_include
+       fi
+       if test "X$ac_cv_db_where_inc" = "X"; then
+         CMU_DB_INC_WHERE(/usr/athena/include /usr/local/include)
+       fi
+
+       AC_MSG_CHECKING(whether to include db)
+       if test "X$ac_cv_db_where_lib" = "X" -o "X$ac_cv_db_where_inc" = "X"; then
+         ac_cv_found_db=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_db=yes
+         AC_MSG_RESULT(yes)
+         DB_INC_DIR=$ac_cv_db_where_inc
+         DB_LIB_DIR=$ac_cv_db_where_lib
+         DB_INC_FLAGS="-I${DB_INC_DIR}"
+          if test "$enable_db4" = "yes"; then
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-4"
+          else
+            DB_LIB_FLAGS="-L${DB_LIB_DIR} -ldb-3"
+          fi
+          dnl Do not force configure.in to put these in CFLAGS and LIBS unconditionally
+          dnl Allow makefile substitutions....
+          AC_SUBST(DB_INC_FLAGS)
+          AC_SUBST(DB_LIB_FLAGS)
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${DB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${DB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${DB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${DB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${DB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
+
+
+dnl ---- CUT HERE ---
+
+dnl These are the Cyrus Berkeley DB macros.  In an ideal world these would be
+dnl identical to the above.
+
+dnl They are here so that they can be shared between Cyrus IMAPd
+dnl and Cyrus SASL with relative ease.
+
+dnl The big difference between this and the ones above is that we don't assume
+dnl that we know the name of the library, and we try a lot of permutations
+dnl instead.  We also assume that DB4 is acceptable.
+
+dnl When we're done, there will be a BDB_LIBADD and a BDB_INCADD which should
+dnl be used when necessary.  We should probably be smarter about our RPATH
+dnl handling.
+
+dnl Call these with BERKELEY_DB_CHK.
+
+dnl We will also set $dblib to "berkeley" if we are successful, "no" otherwise.
+
+dnl this is unbelievably painful due to confusion over what db-3 should be
+dnl named and where the db-3 header file is located.  arg.
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK_LIB],
+[
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, LDFLAGS)
+           CMU_ADD_LIBPATH_TO($with_bdb_lib, BDB_LIBADD)
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           AC_TRY_LINK([#include <db.h>],
+           [db_create(NULL, NULL, 0);],
+           BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db,
+            dblib="no")
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           AC_TRY_LINK([#include <db.h>],
+           [db_open(NULL, 0, 0, 0, NULL, NULL, NULL);],
+           BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db,
+            dblib="no")
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_OPTS],
+[
+AC_ARG_WITH(bdb-libdir,
+       [  --with-bdb-libdir=DIR   Berkeley DB lib files are in DIR],
+       with_bdb_lib=$withval,
+       [ test "${with_bdb_lib+set}" = set || with_bdb_lib=none])
+AC_ARG_WITH(bdb-incdir,
+       [  --with-bdb-incdir=DIR   Berkeley DB include files are in DIR],
+       with_bdb_inc=$withval,
+       [ test "${with_bdb_inc+set}" = set || with_bdb_inc=none ])
+])
+
+AC_DEFUN([CYRUS_BERKELEY_DB_CHK],
+[
+       AC_REQUIRE([CYRUS_BERKELEY_DB_OPTS])
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+       dnl Note that FreeBSD puts it in a wierd place
+        dnl (but they should use with-bdb-incdir)
+        AC_CHECK_HEADER(db.h,
+                        [CYRUS_BERKELEY_DB_CHK_LIB()],
+                        dblib="no")
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+])
+
+dnl afs.m4--AFS libraries, includes, and dependencies
+dnl $Id: afs.m4,v 1.29 2005/04/26 19:14:07 shadow Exp $
+dnl Chaskiel Grundman
+dnl based on kerberos_v4.m4
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+
+AC_DEFUN([CMU_AFS_INC_WHERE1], [
+cmu_save_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$cmu_save_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <afs/param.h>],
+[#ifndef SYS_NAME
+choke me
+#endif
+int foo;],
+ac_cv_found_afs_inc=yes,
+ac_cv_found_afs_inc=no)
+CPPFLAGS=$cmu_save_CPPFLAGS
+])
+
+AC_DEFUN([CMU_AFS_LIB_WHERE1], [
+save_LIBS="$LIBS"
+save_LDFLAGS="$LDFLAGS"
+
+LIBS="-lauth $1/afs/util.a $LIB_SOCKET $LIBS"
+LDFLAGS="-L$1 -L$1/afs $LDFLAGS"
+dnl suppress caching
+AC_TRY_LINK([],[afsconf_Open();], ac_cv_found_afs_lib=yes, ac_cv_found_afs_lib=no)
+LIBS="$save_LIBS"
+LDFLAGS="$save_LDFLAGS"
+])
+
+AC_DEFUN([CMU_AFS_WHERE], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+   for i in $1; do
+      AC_MSG_CHECKING(for AFS in $i)
+      CMU_AFS_INC_WHERE1("$i/include")
+      ac_cv_found_lwp_inc=$ac_cv_found_afs_inc
+      CMU_TEST_INCPATH($i/include, lwp) 
+      ac_cv_found_afs_inc=$ac_cv_found_lwp_inc
+      if test "$ac_cv_found_afs_inc" = "yes"; then
+        CMU_AFS_LIB_WHERE1("$i/$CMU_LIB_SUBDIR")
+        if test "$ac_cv_found_afs_lib" = "yes"; then
+          ac_cv_afs_where=$i
+          AC_MSG_RESULT(found)
+          break
+        else
+          AC_MSG_RESULT(not found)
+        fi
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_AFS], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(AFS,
+       [  --with-afs=PREFIX      Compile with AFS support],
+       [if test "X$with_AFS" = "X"; then
+               with_AFS=yes
+       fi])
+
+       if test "X$with_AFS" != "X"; then
+         ac_cv_afs_where=$with_AFS
+       fi
+       if test "X$ac_cv_afs_where" = "X"; then
+         CMU_AFS_WHERE(/usr/afsws /usr/local /usr/athena /Library/OpenAFS/Tools)
+       fi
+
+       AC_MSG_CHECKING(whether to include AFS)
+       if test "X$ac_cv_afs_where" = "Xno" -o "X$ac_cv_afs_where" = "X"; then
+         ac_cv_found_afs=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_afs=yes
+         AC_MSG_RESULT(yes)
+         AFS_INC_DIR="$ac_cv_afs_where/include"
+         AFS_LIB_DIR="$ac_cv_afs_where/$CMU_LIB_SUBDIR"
+         AFS_TOP_DIR="$ac_cv_afs_where"
+         AFS_INC_FLAGS="-I${AFS_INC_DIR}"
+          AFS_LIB_FLAGS="-L${AFS_LIB_DIR} -L${AFS_LIB_DIR}/afs"
+          cmu_save_LIBS="$LIBS"
+          cmu_save_CPPFLAGS="$CPPFLAGS"
+          CPPFLAGS="$CPPFLAGS ${AFS_INC_FLAGS}"
+         cmu_save_LDFLAGS="$LDFLAGS"
+         LDFLAGS="$cmu_save_LDFLAGS ${AFS_LIB_FLAGS}"
+                        
+          AC_CHECK_HEADERS(afs/stds.h)
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],AFS_DES_LIB="",AFS_DES_LIB="maybe")
+          if test "X$AFS_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],AFS_DES_LIB="yes")
+              if test "X$AFS_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                 AFS_LIBDES="-ldes"
+                 AFS_LIBDESA="${AFS_LIB_DIR}/libdes.a"
+             else
+                 LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                 AC_TRY_LINK([],
+                 [des_quad_cksum();],AFS_DES_LIB="libcrypto")
+                 if test "X$AFS_DES_LIB" = "Xlibcrypto"; then
+                     AC_MSG_RESULT([libcrypto])
+                     AFS_LIBDES="$LIBSSL_LIB_FLAGS"
+                     AFS_LIBDESA="$LIBSSL_LIB_FLAGS"
+                 else
+                     LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     AC_TRY_LINK([],
+                     [des_quad_cksum();],AFS_DES_LIB="libcrypto+descompat")
+                     if test "X$AFS_DES_LIB" = "Xlibcrypto+descompat"; then
+                         AC_MSG_RESULT([libcrypto+descompat])
+                         AFS_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                         AFS_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                     else
+                         AC_MSG_RESULT([unknown])
+                         AC_MSG_ERROR([Could not use -ldes])
+                     fi 
+                 fi 
+             fi 
+         else
+             AC_MSG_RESULT([no])
+          fi
+
+
+         AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS_STATIC="${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+         AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+         AFS_RX_LIBS="-lauth -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+          AFS_KTC_LIBS="-lauth ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcom_err ${AFS_LIB_DIR}/afs/util.a"
+
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_CHECK_FUNC(des_pcbc_init)
+          if test "X$ac_cv_func_des_pcbc_init" != "Xyes"; then
+           AC_CHECK_LIB(descompat, des_pcbc_init, AFS_DESCOMPAT_LIB="-ldescompat")
+           if test "X$AFS_DESCOMPAT_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_DESCOMPAT_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_DESCOMPAT_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_DESCOMPAT_LIB"
+           else
+
+           AC_MSG_CHECKING([if rxkad needs des_pcbc_init])
+           AC_TRY_LINK(,[tkt_DecodeTicket();],RXKAD_PROBLEM=no,RXKAD_PROBLEM=maybe)
+            if test "$RXKAD_PROBLEM" = "maybe"; then
+              AC_TRY_LINK([int des_pcbc_init() { return 0;}],
+              [tkt_DecodeTicket();],RXKAD_PROBLEM=yes,RXKAD_PROBLEM=error)
+              if test "$RXKAD_PROBLEM" = "yes"; then
+                    AC_MSG_RESULT([yes])
+                    AC_MSG_ERROR([cannot use rxkad])
+              else
+                    AC_MSG_RESULT([unknown])        
+                    AC_MSG_ERROR([Unknown error testing rxkad])
+              fi
+            else
+              AC_MSG_RESULT([no])
+            fi
+           fi
+          fi
+
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(flock)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_flock" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs flock])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int sigvec() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_FLOCK=no,AFS_FLOCK=yes)
+             if test $AFS_FLOCK = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, flock,:, [AC_CHECK_LIB(BSD, flock)])
+             fi
+          fi
+          LIBS="$cmu_save_LIBS"
+          AC_CHECK_FUNC(sigvec)
+          LIBS="$cmu_save_LIBS ${AFS_CLIENT_LIBS} ${LIB_SOCKET}"
+          if test "X$ac_cv_func_sigvec" != "Xyes"; then
+             AC_MSG_CHECKING([if AFS needs sigvec])
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <ubik.h>
+#include <afs/cellconfig.h>
+#include <afs/auth.h>
+#include <afs/volser.h>
+struct ubik_client * cstruct;
+int flock() {return 0;}
+extern int UV_SetSecurity();],
+             [vsu_ClientInit(1,"","",0,
+                             &cstruct,UV_SetSecurity)],
+             AFS_SIGVEC=no,AFS_SIGVEC=yes)
+             if test $AFS_SIGVEC = "no"; then
+                AC_MSG_RESULT([no])
+             else
+               AC_MSG_RESULT([yes])
+               LDFLAGS="$LDFLAGS -L/usr/ucblib"
+               AC_CHECK_LIB(ucb, sigvec,:,[AC_CHECK_LIB(BSD, sigvec)])
+             fi
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_LIB_FLAGS="${AFS_LIB_FLAGS} -L/usr/ucblib -R/usr/ucblib"
+          fi
+          if test "$ac_cv_lib_ucb_flock" = "yes" -o "$ac_cv_lib_ucb_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lucb"
+          elif test "$ac_cv_lib_BSD_flock" = "yes" -o "$ac_cv_lib_BSD_sigvec" = "yes"; then
+             AFS_BSD_LIB="-lBSD"
+          fi
+          if test "X$AFS_BSD_LIB" != "X" ; then
+                AFS_CLIENT_LIBS_STATIC="$AFS_CLIENT_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_KTC_LIBS_STATIC="$AFS_KTC_LIBS_STATIC $AFS_BSD_LIB"
+                AFS_CLIENT_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_RX_LIBS="$AFS_CLIENT_LIBS $AFS_BSD_LIB"
+                AFS_KTC_LIBS="$AFS_KTC_LIBS $AFS_BSD_LIB"
+          fi
+
+          AC_MSG_CHECKING([if libaudit is needed])
+         AFS_LIBAUDIT=""
+          LIBS="$cmu_save_LIBS $AFS_CLIENT_LIBS ${LIB_SOCKET}"
+          AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+          [afsconf_SuperUser();],AFS_AUDIT_LIB="",AFS_AUDIT_LIB="maybe")
+          if test "X$AFS_AUDIT_LIB" != "X"; then
+          LIBS="$cmu_save_LIBS -lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB $LIB_SOCKET"
+             AC_TRY_LINK([#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif
+#include <afs/cellconfig.h>
+#include <afs/auth.h>],
+             [afsconf_SuperUser();],AFS_AUDIT_LIB="yes")
+             if test "X$AFS_AUDIT_LIB" = "Xyes"; then
+                 AC_MSG_RESULT([yes])
+                AFS_LIBAUDIT="-laudit"
+                AFS_CLIENT_LIBS_STATIC="${AFS_LIB_DIR}/afs/libvolser.a ${AFS_LIB_DIR}/afs/libvldb.a ${AFS_LIB_DIR}/afs/libkauth.a ${AFS_LIB_DIR}/afs/libprot.a ${AFS_LIB_DIR}/libubik.a ${AFS_LIB_DIR}/afs/libauth.a ${AFS_LIB_DIR}/afs/libaudit.a ${AFS_LIB_DIR}/librxkad.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/afs/libsys.a ${AFS_LIB_DIR}/librx.a ${AFS_LIB_DIR}/liblwp.a ${AFS_LIBDESA} ${AFS_LIB_DIR}/afs/libcmd.a ${AFS_LIB_DIR}/afs/libcom_err.a ${AFS_LIB_DIR}/afs/util.a"
+                 AFS_CLIENT_LIBS="-lvolser -lvldb -lkauth -lprot -lubik -lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+                 AFS_RX_LIBS="-lauth -laudit -lrxkad -lrx ${AFS_LIB_DIR}/afs/libsys.a -lrx -llwp ${AFS_LIBDES} -lcmd -lcom_err ${AFS_LIB_DIR}/afs/util.a $AFS_BSD_LIB $AFS_DESCOMPAT_LIB"
+             else
+                 AC_MSG_RESULT([unknown])
+                 AC_MSG_ERROR([Could not use -lauth while testing for -laudit])
+             fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+
+         AC_CHECK_FUNCS(VL_ProbeServer)
+          AC_MSG_CHECKING([if new-style afs_ integer types are defined])
+          AC_CACHE_VAL(ac_cv_afs_int32,
+dnl The next few lines contain a quoted argument to egrep
+dnl It is critical that there be no leading or trailing whitespace
+dnl or newlines
+[AC_EGREP_CPP(dnl
+changequote(<<,>>)dnl
+<<(^|[^a-zA-Z_0-9])afs_int32[^a-zA-Z_0-9]>>dnl
+changequote([,]), [#include <afs/param.h>
+#ifdef HAVE_AFS_STDS_H
+#include <afs/stds.h>
+#endif],
+ac_cv_afs_int32=yes, ac_cv_afs_int32=no)])
+          AC_MSG_RESULT($ac_cv_afs_int32)
+          if test $ac_cv_afs_int32 = yes ; then
+            AC_DEFINE(HAVE_AFS_INT32,, [AFS provides new "unambiguous" type names])
+          else
+            AC_DEFINE(afs_int16, int16, [it's a type definition])
+            AC_DEFINE(afs_int32, int32, [it's a type definition])
+            AC_DEFINE(afs_uint16, u_int16, [it's a type definition])
+            AC_DEFINE(afs_uint32, u_int32, [it's a type definition])
+          fi
+
+          CPPFLAGS="${cmu_save_CPPFLAGS}"
+          LDFLAGS="${cmu_save_LDFLAGS}"
+          LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(AFS_ENV,, [Use AFS. (find what needs this and nuke it)])
+          AC_DEFINE(AFS,, [Use AFS. (find what needs this and nuke it)])
+          AC_SUBST(AFS_CLIENT_LIBS_STATIC)
+          AC_SUBST(AFS_KTC_LIBS_STATIC)
+          AC_SUBST(AFS_CLIENT_LIBS)
+          AC_SUBST(AFS_RX_LIBS)
+          AC_SUBST(AFS_KTC_LIBS)
+          AC_SUBST(AFS_INC_FLAGS)
+          AC_SUBST(AFS_LIB_FLAGS)
+         AC_SUBST(AFS_TOP_DIR)
+         AC_SUBST(AFS_LIBAUDIT)
+         AC_SUBST(AFS_LIBDES)
+          AC_SUBST(AFS_LIBDESA)
+               fi
+       ])
+
+AC_DEFUN([CMU_NEEDS_AFS],
+[AC_REQUIRE([CMU_AFS])
+if test "$ac_cv_found_afs" != "yes"; then
+        AC_ERROR([Cannot continue without AFS])
+fi])
+
+dnl libssl.m4--Ssl libraries and includes
+dnl Derrick Brashear
+dnl from KTH kafs and Arla
+dnl $Id: libssl.m4,v 1.10 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+CMU_CHECK_HEADER_NOCACHE(openssl/ssl.h,
+ac_cv_found_libssl_inc=yes,
+ac_cv_found_libssl_inc=no)
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_LIBSSL_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl headers in $i)
+      CMU_LIBSSL_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, ssl)
+      if test "$ac_cv_found_libssl_inc" = "yes"; then
+        ac_cv_libssl_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lssl -lcrypto $LIB_SOCKET"
+AC_TRY_LINK(,
+[SSL_write();],
+[ac_cv_found_ssl_lib=yes],
+ac_cv_found_ssl_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_LIBSSL_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for libssl libraries in $i)
+      CMU_LIBSSL_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, ssl)
+      if test "$ac_cv_found_ssl_lib" = "yes" ; then
+        ac_cv_libssl_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_LIBSSL], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_ARG_WITH(libssl,
+       [  --with-libssl=PREFIX      Compile with Libssl support],
+       [if test "X$with_libssl" = "X"; then
+               with_libssl=yes
+       fi])
+AC_ARG_WITH(libssl-lib,
+       [  --with-libssl-lib=dir     use libssl libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-lib])
+       fi])
+AC_ARG_WITH(libssl-include,
+       [  --with-libssl-include=dir use libssl headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-libssl-include])
+       fi])
+
+       if test "X$with_libssl" != "X"; then
+         if test "$with_libssl" != "yes" -a "$with_libssl" != no; then
+           ac_cv_libssl_where_lib=$with_libssl/$CMU_LIB_SUBDIR
+           ac_cv_libssl_where_inc=$with_libssl/include
+         fi
+       fi
+
+       if test "$with_libssl" != "no"; then 
+         if test "X$with_libssl_lib" != "X"; then
+           ac_cv_libssl_where_lib=$with_libssl_lib
+         fi
+         if test "X$ac_cv_libssl_where_lib" = "X"; then
+           CMU_LIBSSL_LIB_WHERE(/usr/local/$CMU_LIB_SUBDIR/openssl /usr/$CMU_LIB_SUBDIR/openssl /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+         fi
+
+         if test "X$with_libssl_include" != "X"; then
+           ac_cv_libssl_where_inc=$with_libssl_include
+         fi
+         if test "X$ac_cv_libssl_where_inc" = "X"; then
+           CMU_LIBSSL_INC_WHERE(/usr/local/include /usr/include)
+         fi
+       fi
+
+       AC_MSG_CHECKING(whether to include libssl)
+       if test "X$ac_cv_libssl_where_lib" = "X" -a "X$ac_cv_libssl_where_inc" = "X"; then
+         ac_cv_found_libssl=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_libssl=yes
+         AC_MSG_RESULT(yes)
+         LIBSSL_INC_DIR=$ac_cv_libssl_where_inc
+         LIBSSL_LIB_DIR=$ac_cv_libssl_where_lib
+         LIBSSL_INC_FLAGS="-I${LIBSSL_INC_DIR}"
+         LIBSSL_LIB_FLAGS="-L${LIBSSL_LIB_DIR} -lssl -lcrypto"
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${LIBSSL_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${LIBSSL_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${LIBSSL_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${LIBSSL_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       AC_SUBST(LIBSSL_INC_DIR)
+       AC_SUBST(LIBSSL_LIB_DIR)
+       AC_SUBST(LIBSSL_INC_FLAGS)
+       AC_SUBST(LIBSSL_LIB_FLAGS)
+       ])
+
+
+dnl kerberos_v4.m4--Kerberos 4 libraries and includes
+dnl Derrick Brashear
+dnl from KTH krb and Arla
+dnl $Id: kerberos_v4.m4,v 1.28 2005/04/26 19:14:08 shadow Exp $
+
+AC_DEFUN([CMU_KRB_SENDAUTH_PROTO], [
+AC_MSG_CHECKING(for krb_sendauth prototype)
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_sendauth (long options, int fd, KTEXT ktext, char *service,
+                  char *inst, char *realm, u_long checksum,
+                  MSG_DAT *msg_data, CREDENTIALS *cred,
+                  Key_schedule schedule, struct sockaddr_in *laddr,
+                  struct sockaddr_in *faddr, char *version);],
+[int foo = krb_sendauth(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); ],
+ac_cv_krb_sendauth_proto=no,
+ac_cv_krb_sendauth_proto=yes)
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+if test "$ac_cv_krb_sendauth_proto" = yes; then
+        AC_DEFINE(HAVE_KRB_SENDAUTH_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_sendauth_proto)
+])
+
+AC_DEFUN([CMU_KRB_SET_KEY_PROTO], [
+AC_MSG_CHECKING(for krb_set_key prototype)
+AC_CACHE_VAL(ac_cv_krb_set_key_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_set_key(char *key, int cvt);],
+[int foo = krb_set_key(0, 0);],
+ac_cv_krb_set_key_proto=no,
+ac_cv_krb_set_key_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_set_key_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_SET_KEY_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_set_key_proto)
+])
+
+AC_DEFUN([CMU_KRB4_32_DEFN], [
+AC_MSG_CHECKING(for KRB4_32 definition)
+AC_CACHE_VAL(ac_cv_krb4_32_defn, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+],
+[KRB4_32 foo = 1;],
+ac_cv_krb4_32_defn=yes,
+ac_cv_krb4_32_defn=no)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb4_32_defn" = yes; then
+       AC_DEFINE(HAVE_KRB4_32_DEFINE)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb4_32_defn)
+])
+
+AC_DEFUN([CMU_KRB_RD_REQ_PROTO], [
+AC_MSG_CHECKING(for krb_rd_req prototype)
+AC_CACHE_VAL(ac_cv_krb_rd_req_proto, [
+cmu_save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="${CPPFLAGS} ${KRB_INC_FLAGS}"
+AC_TRY_COMPILE(
+[#include <krb.h>
+int krb_rd_req(KTEXT authent, char *service, char *instance,
+unsigned KRB_INT32 from_addr, AUTH_DAT *ad, char *fn);],
+[int foo = krb_rd_req(0,0,0,0,0,0);],
+ac_cv_krb_rd_req_proto=no,
+ac_cv_krb_rd_req_proto=yes)
+])
+CPPFLAGS="${cmu_save_CPPFLAGS}"
+if test "$ac_cv_krb_rd_req_proto" = yes; then
+       AC_DEFINE(HAVE_KRB_RD_REQ_PROTO)dnl
+fi
+AC_MSG_RESULT($ac_cv_krb_rd_req_proto)
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE1], [
+saved_CPPFLAGS=$CPPFLAGS
+CPPFLAGS="$saved_CPPFLAGS -I$1"
+AC_TRY_COMPILE([#include <krb.h>],
+[struct ktext foo;],
+ac_cv_found_krb_inc=yes,
+ac_cv_found_krb_inc=no)
+if test "$ac_cv_found_krb_inc" = "no"; then
+  CPPFLAGS="$saved_CPPFLAGS -I$1 -I$1/kerberosIV"
+  AC_TRY_COMPILE([#include <krb.h>],
+  [struct ktext foo;],
+  [ac_cv_found_krb_inc=yes],
+  ac_cv_found_krb_inc=no)
+fi
+CPPFLAGS=$saved_CPPFLAGS
+])
+
+AC_DEFUN([CMU_KRB_INC_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos headers in $i)
+      CMU_KRB_INC_WHERE1($i)
+      CMU_TEST_INCPATH($i, krb)
+      if test "$ac_cv_found_krb_inc" = "yes"; then
+        ac_cv_krb_where_inc=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+#
+# Test for kerberos lib files
+#
+
+AC_DEFUN([CMU_KRB_LIB_WHERE1], [
+saved_LIBS=$LIBS
+LIBS="$saved_LIBS -L$1 -lkrb ${KRB_LIBDES}"
+AC_TRY_LINK(,
+[dest_tkt();],
+[ac_cv_found_krb_lib=yes],
+ac_cv_found_krb_lib=no)
+LIBS=$saved_LIBS
+])
+
+AC_DEFUN([CMU_KRB_LIB_WHERE], [
+   for i in $1; do
+      AC_MSG_CHECKING(for kerberos libraries in $i)
+      CMU_KRB_LIB_WHERE1($i)
+      dnl deal with false positives from implicit link paths
+      CMU_TEST_LIBPATH($i, krb)
+      if test "$ac_cv_found_krb_lib" = "yes" ; then
+        ac_cv_krb_where_lib=$i
+        AC_MSG_RESULT(found)
+        break
+      else
+        AC_MSG_RESULT(not found)
+      fi
+    done
+])
+
+AC_DEFUN([CMU_KRB4], [
+AC_REQUIRE([CMU_FIND_LIB_SUBDIR])
+AC_REQUIRE([CMU_SOCKETS])
+AC_REQUIRE([CMU_LIBSSL])
+AC_ARG_WITH(krb4,
+       [  --with-krb4=PREFIX      Compile with Kerberos 4 support],
+       [if test "X$with_krb4" = "X"; then
+               with_krb4=yes
+       fi])
+AC_ARG_WITH(krb4-lib,
+       [  --with-krb4-lib=dir     use kerberos 4 libraries in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-lib])
+       fi])
+AC_ARG_WITH(krb4-include,
+       [  --with-krb4-include=dir use kerberos 4 headers in dir],
+       [if test "$withval" = "yes" -o "$withval" = "no"; then
+               AC_MSG_ERROR([No argument for --with-krb4-include])
+       fi])
+
+       if test "X$with_krb4" != "X"; then
+         if test "$with_krb4" != "yes" -a "$with_krb4" != "no"; then
+           ac_cv_krb_where_lib=$with_krb4/$CMU_LIB_SUBDIR
+           ac_cv_krb_where_inc=$with_krb4/include
+         fi
+       fi
+       
+       if test "$with_krb4" != "no"; then
+         if test "X$with_krb4_lib" != "X"; then
+           ac_cv_krb_where_lib=$with_krb4_lib
+         fi
+         if test "X$with_krb4_include" != "X"; then
+           ac_cv_krb_where_inc=$with_krb4_include
+         fi
+         if test "X$ac_cv_krb_where_inc" = "X"; then
+           CMU_KRB_INC_WHERE(/usr/athena/include /usr/include/kerberosIV /usr/local/include /usr/include/kerberos)
+         fi
+
+          AC_MSG_CHECKING([if libdes is needed])
+          AC_TRY_LINK([],[des_quad_cksum();],KRB_DES_LIB="",KRB_DES_LIB="maybe")
+          if test "X$KRB_DES_LIB" != "X"; then
+              LIBS="$cmu_save_LIBS -ldes"
+              AC_TRY_LINK([], [des_quad_cksum();],KRB_DES_LIB="yes")
+              if test "X$KRB_DES_LIB" = "Xyes"; then
+                  AC_MSG_RESULT([yes])
+                  KRB_LIBDES="-ldes"
+                  KRB_LIBDESA='$(KRB_LIB_DIR)/libdes.a'
+              else
+                  LIBS="$cmu_save_LIBS $LIBSSL_LIB_FLAGS"
+                  AC_TRY_LINK([],
+                  [des_quad_cksum();],KRB_DES_LIB="libcrypto")
+                  if test "X$KRB_DES_LIB" = "Xlibcrypto"; then
+                      AC_MSG_RESULT([libcrypto])
+                      KRB_LIBDES="$LIBSSL_LIB_FLAGS"
+                      KRB_LIBDESA="$LIBSSL_LIB_FLAGS"
+                  else
+                      LIBS="$cmu_save_LIBS -L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      AC_TRY_LINK([],
+                      [des_quad_cksum();],KRB_DES_LIB="libcrypto+descompat")
+                      if test "X$KRB_DES_LIB" = "Xlibcrypto+descompat"; then
+                          AC_MSG_RESULT([libcrypto+descompat])
+                          KRB_LIBDES="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                          KRB_LIBDESA="-L$LIBSSL_LIB_DIR -ldescompat $LIBSSL_LIB_FLAGS"
+                      else
+                          AC_MSG_RESULT([unknown])
+                          AC_MSG_ERROR([Could not use -ldes])
+                      fi 
+                  fi 
+              fi 
+          else
+             AC_MSG_RESULT([no])
+          fi
+          if test "X$ac_cv_krb_where_lib" = "X"; then
+            CMU_KRB_LIB_WHERE(/usr/athena/$CMU_LIB_SUBDIR /usr/local/$CMU_LIB_SUBDIR /usr/$CMU_LIB_SUBDIR)
+          fi
+       fi
+         LIBS="${cmu_save_LIBS}"
+
+
+       AC_MSG_CHECKING([whether to include kerberos 4])
+       if test "X$ac_cv_krb_where_lib" = "X" -o "X$ac_cv_krb_where_inc" = "X"; then
+         ac_cv_found_krb=no
+         AC_MSG_RESULT(no)
+       else
+         ac_cv_found_krb=yes
+         AC_MSG_RESULT(yes)
+         KRB_INC_DIR=$ac_cv_krb_where_inc
+         KRB_LIB_DIR=$ac_cv_krb_where_lib
+         KRB_INC_FLAGS="-I${KRB_INC_DIR}"
+         KRB_LIB_FLAGS="-L${KRB_LIB_DIR} -lkrb ${KRB_LIBDES}"
+         LIBS="${cmu_save_LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_LIB(resolv, dns_lookup, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lresolv",,"${KRB_LIB_FLAGS}")
+         AC_CHECK_LIB(crypt, crypt, KRB_LIB_FLAGS="${KRB_LIB_FLAGS} -lcrypt",,"${KRB_LIB_FLAGS}")
+         LIBS="${LIBS} ${KRB_LIB_FLAGS}"
+         AC_CHECK_FUNCS(krb_get_int krb_life_to_time)
+          AC_SUBST(KRB_INC_FLAGS)
+          AC_SUBST(KRB_LIB_FLAGS)
+         LIBS="${cmu_save_LIBS}"
+         AC_DEFINE(HAVE_KRB4,,[Kerberos V4 is present])dnl zephyr uses this
+         AC_DEFINE(KERBEROS,,[Use kerberos 4. find out what needs this symbol])
+         if test "X$RPATH" = "X"; then
+               RPATH=""
+         fi
+         case "${host}" in
+           *-*-linux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-hpux*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,+b${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-irix*)
+             if test "X$RPATH" = "X"; then
+               RPATH="-Wl,-rpath,${KRB_LIB_DIR}"
+             else 
+               RPATH="${RPATH}:${KRB_LIB_DIR}"
+             fi
+             ;;
+           *-*-solaris2*)
+             if test "$ac_cv_prog_gcc" = yes; then
+               if test "X$RPATH" = "X"; then
+                 RPATH="-Wl,-R${KRB_LIB_DIR}"
+               else 
+                 RPATH="${RPATH}:${KRB_LIB_DIR}"
+               fi
+             else
+               RPATH="${RPATH} -R${KRB_LIB_DIR}"
+             fi
+             ;;
+         esac
+         AC_SUBST(RPATH)
+       fi
+       ])
+
+
+dnl See whether we can use IPv6 related functions
+dnl contributed by Hajimu UMEMOTO
+
+AC_DEFUN([IPv6_CHECK_FUNC], [
+AC_CHECK_FUNC($1, [dnl
+  ac_cv_lib_socket_$1=no
+  ac_cv_lib_inet6_$1=no
+], [dnl
+  AC_CHECK_LIB(socket, $1, [dnl
+    LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_$1=no
+  ], [dnl
+    AC_MSG_CHECKING([whether your system has IPv6 directory])
+    AC_CACHE_VAL(ipv6_cv_dir, [dnl
+      for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done])dnl
+    AC_MSG_RESULT($ipv6_cv_dir)
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_$1=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      AC_CHECK_LIB(inet6, $1, [dnl
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi],)dnl
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi])dnl
+])dnl
+ipv6_cv_$1=no
+if test $ac_cv_func_$1 = yes -o $ac_cv_lib_socket_$1 = yes \
+     -o $ac_cv_lib_inet6_$1 = yes
+then
+  ipv6_cv_$1=yes
+fi
+if test $ipv6_cv_$1 = no; then
+  if test $1 = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      AC_EGREP_HEADER(${ipv6_cv_pfx}$1, netdb.h,
+                     [AC_CHECK_FUNC(${ipv6_cv_pfx}$1)])
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}$1 = Xyes; then
+        AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo?])
+        ipv6_cv_$1=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_$1 = yes; then
+  ifelse([$2], , :, [$2])
+else
+  ifelse([$3], , :, [$3])
+fi])
+
+
+dnl See whether we have ss_family in sockaddr_storage
+AC_DEFUN([IPv6_CHECK_SS_FAMILY], [
+AC_MSG_CHECKING([whether you have ss_family in struct sockaddr_storage])
+AC_CACHE_VAL(ipv6_cv_ss_family, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+       [struct sockaddr_storage ss; int i = ss.ss_family;],
+       [ipv6_cv_ss_family=yes], [ipv6_cv_ss_family=no])])dnl
+if test $ipv6_cv_ss_family = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SS_FAMILY,[],[Is there an ss_family in sockaddr_storage?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_ss_family)])
+
+
+dnl whether you have sa_len in struct sockaddr
+AC_DEFUN([IPv6_CHECK_SA_LEN], [
+AC_MSG_CHECKING([whether you have sa_len in struct sockaddr])
+AC_CACHE_VAL(ipv6_cv_sa_len, [dnl
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>],
+              [struct sockaddr sa; int i = sa.sa_len;],
+              [ipv6_cv_sa_len=yes], [ipv6_cv_sa_len=no])])dnl
+if test $ipv6_cv_sa_len = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKADDR_SA_LEN,[],[Does sockaddr have an sa_len?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_sa_len)])
+
+
+dnl See whether sys/socket.h has socklen_t
+AC_DEFUN([IPv6_CHECK_SOCKLEN_T], [
+AC_MSG_CHECKING(for socklen_t)
+AC_CACHE_VAL(ipv6_cv_socklen_t, [dnl
+AC_TRY_LINK([#include <sys/types.h>
+#include <sys/socket.h>],
+           [socklen_t len = 0;],
+           [ipv6_cv_socklen_t=yes], [ipv6_cv_socklen_t=no])])dnl
+if test $ipv6_cv_socklen_t = yes; then
+  ifelse([$1], , AC_DEFINE(HAVE_SOCKLEN_T,[],[Do we have a socklen_t?]), [$1])
+else
+  ifelse([$2], , :, [$2])
+fi
+AC_MSG_RESULT($ipv6_cv_socklen_t)])
+
+
diff --git a/saslauthd/auth_dce.c b/saslauthd/auth_dce.c
new file mode 100644 (file)
index 0000000..42a2b60
--- /dev/null
@@ -0,0 +1,117 @@
+/* MODULE: auth_dce */
+
+/* COPYRIGHT
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * Authenticate against DCE.
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_dce.c,v 1.3 2001/12/04 02:06:54 rjs3 Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include <stdlib.h>
+#include <string.h>
+#include "mechanisms.h"
+
+#include "auth_dce.h"
+
+/* END PUBLIC DEPENDENCIES */
+
+# define RETURN(x) {return strdup(x);}
+\f
+/* FUNCTION: auth_dce */
+
+#ifdef AUTH_DCE
+
+char *                                 /* R: allocated response string */
+auth_dce(
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+    int reenter = 0;                   /* internal to authenticate() */
+    int rc;                            /* return code holder */
+    char *msg;                         /* response from authenticate() */
+    static char *reply;                        /* our reply string */
+    
+    int authenticate(char *, char *, int *, char **); /* DCE authenticator */
+
+    rc = authenticate(login, password, &reenter, &msg);
+    if (rc != 0) {
+       /*
+        * Failed. authenticate() has allocated storage for msg. We have
+        * to copy the message text into a static buffer and free the
+        * space allocated inside of authenticate().
+        */
+       if (reply != 0) {
+           free(reply);
+           reply = 0;
+       }
+       if (msg == 0)
+           RETURN("NO");
+       reply = malloc(strlen(msg) + sizeof("NO "));
+       if (reply == 0) {
+           if (msg != 0)
+               free(msg);
+           RETURN("NO (auth_dce malloc failure)");
+       }
+       strcpy(reply, "NO ");
+       strcat(reply, msg);
+       free(msg);
+       RETURN(reply);
+    } else {
+       if (msg != 0)
+           free(msg);
+       RETURN("OK");
+    }
+}
+
+#else /* !AUTH_DCE */
+
+char *
+auth_dce(
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+     return NULL;
+}
+
+#endif /* !AUTH_DCE */
+
+/* END FUNCTION: auth_dce */
+
+/* END MODULE: auth_dce */
diff --git a/saslauthd/auth_dce.h b/saslauthd/auth_dce.h
new file mode 100644 (file)
index 0000000..d96ee15
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT
+ */
+
+char *auth_dce(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/auth_getpwent.c b/saslauthd/auth_getpwent.c
new file mode 100644 (file)
index 0000000..a6f5f87
--- /dev/null
@@ -0,0 +1,91 @@
+/* MODULE: auth_getpwent */
+
+/* COPYRIGHT
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * crypt(3) based passwd file validation
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_getpwent.c,v 1.7 2005/01/27 04:39:52 shadow Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+#include <unistd.h>
+#include <string.h>
+#include <pwd.h>
+
+# ifdef WITH_DES
+#  ifdef WITH_SSL_DES
+#   include <openssl/des.h>
+#  else
+#   include <des.h>
+#  endif /* WITH_SSL_DES */
+# endif /* WITH_DES */
+
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+/* END PUBLIC DEPENDENCIES */
+
+#define RETURN(x) return strdup(x)
+\f
+/* FUNCTION: auth_getpwent */
+
+char *                                 /* R: allocated response string */
+auth_getpwent (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    struct passwd *pw;                 /* pointer to passwd file entry */
+    /* END VARIABLES */
+  
+    pw = getpwnam(login);
+    endpwent();
+
+    if (pw == NULL) {
+       RETURN("NO");
+    }
+
+    if (strcmp(pw->pw_passwd, (const char *)crypt(password, pw->pw_passwd))) {
+       RETURN("NO");
+    }
+
+    RETURN("OK");
+}
+
+/* END FUNCTION: auth_getpwent */
+
+/* END MODULE: auth_getpwent */
diff --git a/saslauthd/auth_getpwent.h b/saslauthd/auth_getpwent.h
new file mode 100644 (file)
index 0000000..0b25f0a
--- /dev/null
@@ -0,0 +1,28 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_getpwent(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/auth_httpform.c b/saslauthd/auth_httpform.c
new file mode 100644 (file)
index 0000000..45fb083
--- /dev/null
@@ -0,0 +1,607 @@
+/* MODULE: auth_httpform */
+
+/* COPYRIGHT
+ * Copyright (c) 2005 Pyx Engineering AG
+ * Copyright (c) 1998 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * Copyright 1998, 1999 Carnegie Mellon University
+ * 
+ *                       All Rights Reserved
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Carnegie Mellon
+ * University not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.
+ * 
+ * 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.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * Proxy authentication to a remote HTTP server.
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_httpform.c,v 1.2 2006/04/19 19:51:04 murch Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include <unistd.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#ifdef _AIX
+# include <strings.h>
+#endif /* _AIX */
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <netdb.h>
+
+#include "mechanisms.h"
+#include "utils.h"
+#include "cfile.h"
+#include "globals.h"
+#include "auth_httpform.h"
+/* END PUBLIC DEPENDENCIES */
+
+#ifndef MAX
+#define MAX(p,q) ((p >= q) ? p : q)
+#endif
+
+/* PRIVATE DEPENDENCIES */
+static cfile config = NULL;
+static const char *r_host = "localhost";  /* remote host (mech_option) */
+static const char *r_port = "80";       /* remote port (mech_option) */
+static const char *r_uri = NULL;        /* URI to call (mech_option) */
+static const char *formdata = NULL;     /* HTML form data (mech_option) */
+static struct addrinfo *ai = NULL;      /* remote host, as looked up    */
+/* END PRIVATE DEPENDENCIES */
+
+#define NETWORK_IO_TIMEOUT 30          /* network I/O timeout (seconds) */
+#define RESP_LEN 1000                  /* size of read response buffer  */
+
+#define TWO_CRLF "\r\n\r\n"
+#define CRLF "\r\n"
+#define SPACE " "
+
+#define HTTP_STATUS_SUCCESS "200"
+#define HTTP_STATUS_REFUSE "403"
+
+/* Common failure response strings for auth_httpform() */
+
+#define RESP_IERROR    "NO [ALERT] saslauthd internal error"
+#define RESP_UNAVAILABLE "NO [ALERT] The remote authentication server is currently unavailable"
+#define RESP_UNEXPECTED        "NO [ALERT] Unexpected response from remote authentication server"
+\f
+/* FUNCTION: sig_null */
+
+/* SYNOPSIS
+ * Catch and ignore a signal.
+ * END SYNOPSIS */
+
+static RETSIGTYPE                              /* R: OS dependent */
+sig_null (
+  /* PARAMETERS */
+  int sig                                      /* I: signal being caught */
+  /* END PARAMETERS */
+  )
+{
+    switch (sig) {
+       
+      case SIGALRM:
+       signal(SIGALRM, sig_null);
+       break;
+
+      case SIGPIPE:
+       signal(SIGPIPE, sig_null);
+       break;
+
+      default:
+       logger(L_INFO, "auth_httpform", "unexpected signal %d", sig);
+       break;
+    }
+#ifdef __APPLE__
+    return;
+#else /* __APPLE__ */
+# if RETSIGTYPE == void
+    return;
+# else /* RETSIGTYPE */
+    return 0;
+# endif /* RETSIGTYPE */
+#endif /* __APPLE__ */
+}
+
+/* END FUNCTION: sig_null */
+\f
+/* FUNCTION: url_escape */
+
+/* SYNOPSIS
+ * URL-escapes the given string 
+ * 
+ * Note: calling function must free memory.
+ * 
+ * END SYNOPSIS */
+static char *url_escape(
+  /* PARAMETERS */
+  const char *string
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    size_t length = strlen(string);
+    size_t alloc = length+50;   /* add some reserve */
+    char *out;
+    int outidx=0, inidx=0;
+    /* END VARIABLES */
+
+    out = malloc(alloc);
+    if (!out)
+        return NULL;
+
+    while (inidx < length) {
+        char in = string[inidx];
+        if (!(in >= 'a' && in <= 'z') &&
+            !(in >= 'A' && in <= 'Z') &&
+            !(in >= '0' && in <= '9') &&
+            in != '&' && in != '=' && in != '-' && in != '_') {
+
+            /* encode it */
+            if (outidx+3 > alloc) {
+                /* the size grows with two, since this'll become a %XX */
+                char *tmp = NULL;
+                alloc *= 2;
+                tmp = realloc(out, alloc);
+                if (!tmp) {
+                    free(out);
+                    return NULL;
+                } else {
+                    out = tmp;
+                }
+            }
+            
+            snprintf(&out[outidx], 4, "%%%02X", in);
+            outidx += 3;
+        } else {
+            /* just copy this */
+            out[outidx++] = in;
+        }
+
+        inidx++;
+    }
+    out[outidx] = 0; /* terminate it */
+    return out;
+}
+
+/* END FUNCTION: url_escape */
+\f
+/* FUNCTION: create_post_data */
+
+/* SYNOPSIS
+ * Replace %u, %p and %r in the form data read from the config file
+ * with the actual username and password.
+ * 
+ * Large parts of this functions have been shamelessly copied from
+ * the sql_create_statement() in the sql.c plugin code
+ * 
+ * Note: calling function must free memory.
+ * 
+ * END SYNOPSIS */
+
+static char *create_post_data(
+  /* PARAMETERS */
+  const char *formdata, 
+  const char *user,
+  const char *password,
+  const char *realm
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    const char *ptr, *line_ptr;
+    char *buf, *buf_ptr;
+    int filtersize;
+    int ulen, plen, rlen;
+    int numpercents=0;
+    int biggest;
+    size_t i;
+    /* END VARIABLES */
+    
+    /* calculate memory needed for creating the complete query string. */
+    ulen = strlen(user);
+    plen = strlen(password);
+    rlen = strlen(realm);
+    
+    /* what if we have multiple %foo occurrences in the input query? */
+    for (i = 0; i < strlen(formdata); i++) {
+        if (formdata[i] == '%') {
+            numpercents++;
+        }
+    }
+    
+    /* find the biggest of ulen, plen */
+    biggest = MAX(MAX(ulen, plen), rlen);
+    
+    /* don't forget the trailing 0x0 */
+    filtersize = strlen(formdata) + 1 + (numpercents*biggest)+1;
+    
+    /* ok, now try to allocate a chunk of that size */
+    buf = (char *) malloc(filtersize);
+    
+    if (!buf) {
+        logger(LOG_ERR, "auth_httpform:create_post_data", "failed to allocate memory");
+        return NULL;
+    }
+    
+    buf_ptr = buf;
+    line_ptr = formdata;
+    
+    /* replace the strings */
+    while ( (ptr = strchr(line_ptr, '%')) ) {
+        /* copy up to but not including the next % */
+        memcpy(buf_ptr, line_ptr, ptr - line_ptr); 
+        buf_ptr += ptr - line_ptr;
+        ptr++;
+        switch (ptr[0]) {
+        case '%':
+            buf_ptr[0] = '%';
+            buf_ptr++;
+            break;
+        case 'u':
+            memcpy(buf_ptr, user, ulen);
+            buf_ptr += ulen;
+            break;
+        case 'p':
+            memcpy(buf_ptr, password, plen);
+            buf_ptr += plen;
+            break;
+        case 'r':
+            memcpy(buf_ptr, realm, rlen);
+            buf_ptr += rlen;
+            break;
+        default:
+            buf_ptr[0] = '%';
+            buf_ptr[1] = ptr[0];
+            buf_ptr += 2;
+            break;
+        }
+        ptr++;
+        line_ptr = ptr;
+    }
+
+    /* don't forget the rest */    
+    memcpy(buf_ptr, line_ptr, strlen(line_ptr)+1);
+
+    return buf;
+}
+
+/* END FUNCTION: create_post_data */
+\f
+/* FUNCTION: build_sasl_response */
+
+/* SYNOPSIS
+ * Build a SASL response out of the HTTP response
+ * 
+ * Note: The returned string is malloced and will be free'd by the 
+ * saslauthd core
+ * 
+ * END SYNOPSIS */
+static char *build_sasl_response(
+  /* PARAMETERS */
+  const char *http_response
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    size_t length = 0;
+    char *c, *http_response_code, *http_response_string;
+    char *sasl_response;
+    /* END VARIABLES */
+    
+    /* parse the response, just the first line */
+    /* e.g. HTTP/1.1 200 OK */
+    /* e.g. HTTP/1.1 403 User unknown */
+    c = strpbrk(http_response, CRLF);
+    if (c != NULL) {
+        *c = '\0';                      /* tie off line termination */
+    }
+
+    /* isolate the HTTP response code and string */
+    http_response_code = strpbrk(http_response, SPACE) + 1;
+    http_response_string = strpbrk(http_response_code, SPACE) + 1;
+    *(http_response_string-1) = '\0';  /* replace space after code with 0 */
+
+    if (!strcmp(http_response_code, HTTP_STATUS_SUCCESS)) {
+        return strdup("OK remote authentication successful");
+    }
+    if (!strcmp(http_response_code, HTTP_STATUS_REFUSE)) {
+        /* return the HTTP response string as the SASL response */
+        length = strlen(http_response_string) + 3 + 1;
+        sasl_response = malloc(length);
+        if (sasl_response == NULL)
+            return NULL;
+            
+        snprintf(sasl_response, length, "NO %s", http_response_string);
+        return sasl_response;
+    }
+    
+    logger(L_INFO, "auth_httpform", "unexpected response to auth request: %s %s",
+           http_response_code, http_response_string);
+
+    return strdup(RESP_UNEXPECTED);
+}
+
+/* END FUNCTION: build_sasl_response */
+\f
+/* FUNCTION: auth_httpform_init */
+
+/* SYNOPSIS
+ * Validate the host and service names for the remote server.
+ * END SYNOPSIS */
+
+int
+auth_httpform_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    int rc;
+    char *configname = NULL;
+    struct addrinfo hints;
+    /* END VARIABLES */
+
+    /* name of config file may be given with -O option */
+    if (mech_option)
+        configname = mech_option;
+    else if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0)
+        configname = SASLAUTHD_CONF_FILE_DEFAULT;
+    /* open and read config file */
+    if (configname) {
+        char complaint[1024];
+
+        if (!(config = cfile_read(configname, complaint, sizeof (complaint)))) {
+            syslog(LOG_ERR, "auth_httpform_init %s", complaint);
+            return -1;
+        }
+    }
+
+    if (config) {
+        r_host = cfile_getstring(config, "httpform_host", r_host);
+        r_port = cfile_getstring(config, "httpform_port", r_port);
+        r_uri = cfile_getstring(config, "httpform_uri", r_uri);
+        formdata = cfile_getstring(config, "httpform_data", formdata);
+    }
+    
+    if (formdata == NULL || r_uri == NULL) {
+        syslog(LOG_ERR, "auth_httpform_init formdata and uri must be specified");
+        return -1;
+    }
+
+    /* lookup the host/port - taken from auth_rimap */
+    if (ai)
+        freeaddrinfo(ai);
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_CANONNAME;
+    if ((rc = getaddrinfo(r_host, r_port, &hints, &ai)) != 0) {
+        syslog(LOG_ERR, "auth_httpform_init: getaddrinfo %s/%s: %s",
+               r_host, r_port, gai_strerror(rc));
+        return -1;
+     }
+     
+    /* Make sure we have AF_INET or AF_INET6 addresses. */
+    if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
+        syslog(LOG_ERR, "auth_httpform_init: no IP address info for %s",
+               ai->ai_canonname ? ai->ai_canonname : r_host);
+        freeaddrinfo(ai);
+        ai = NULL;
+        return -1;
+    }
+
+    return 0;
+}
+
+/* END FUNCTION: auth_httpform_init */
+\f
+/* FUNCTION: auth_httpform */
+
+/* SYNOPSIS
+ * Proxy authenticate to a remote HTTP server with a form POST.
+ *
+ * This mechanism takes the plaintext authenticator and password, forms
+ * them into an HTTP POST request. If the HTTP server responds with a 200
+ * status code, the credentials are considered valid. If it responds with
+ * a 403 HTTP status code, the credentials are considered wrong. Any other
+ * HTTP status code is treated like a network error.
+ */
+
+/* XXX This should be extended to support SASL PLAIN authentication */
+
+char *                                 /* R: Allocated response string */
+auth_httpform (
+  /* PARAMETERS */
+  const char *user,                    /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,
+  const char *realm
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    int s=-1;                           /* socket to remote auth host   */
+    struct addrinfo *r;                 /* remote socket address info   */
+    char *req;                          /* request, with user and pw    */
+    char *escreq;                       /* URL-escaped request          */
+    char *c;                            /* scratch pointer              */
+    int rc;                             /* return code scratch area     */
+    char postbuf[RESP_LEN];             /* request buffer               */
+    int postlen;                        /* length of post request       */
+    char rbuf[RESP_LEN];                /* response read buffer         */
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    int saved_errno;
+    int niflags;
+    /* END VARIABLES */
+
+    /* sanity checks */
+    assert(user != NULL);
+    assert(password != NULL);
+
+    /*establish connection to remote */
+    for (r = ai; r; r = r->ai_next) {
+        s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+        if (s < 0)
+            continue;
+        if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
+            break;
+        close(s);
+        s = -1;
+        saved_errno = errno;
+        niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+        if (r->ai_family == AF_INET6)
+            niflags |= NI_WITHSCOPEID;
+#endif
+        if (getnameinfo(r->ai_addr, r->ai_addrlen, hbuf, sizeof(hbuf),
+                        pbuf, sizeof(pbuf), niflags) != 0) {
+            strlcpy(hbuf, "unknown", sizeof(hbuf));
+            strlcpy(pbuf, "unknown", sizeof(pbuf));
+        }
+        errno = saved_errno;
+        syslog(LOG_WARNING, "auth_httpform: connect %s[%s]/%s: %m",
+               ai->ai_canonname ? ai->ai_canonname : r_host, hbuf, pbuf);
+    }
+    if (s < 0) {
+        if (getnameinfo(ai->ai_addr, ai->ai_addrlen, NULL, 0,
+                        pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
+            strlcpy(pbuf, "unknown", sizeof(pbuf));
+        syslog(LOG_WARNING, "auth_httpform: couldn't connect to %s/%s",
+               ai->ai_canonname ? ai->ai_canonname : r_host, pbuf);
+        return strdup("NO [ALERT] Couldn't contact remote authentication server");
+    }
+
+    /* CLAIM: we now have a TCP connection to the remote HTTP server */
+
+    /*
+     * Install noop signal handlers. These just reinstall the handler
+     * and return so that we take an EINTR during network I/O.
+     */
+    (void) signal(SIGALRM, sig_null);
+    (void) signal(SIGPIPE, sig_null);
+    
+    /* build the HTTP request */
+    req = create_post_data(formdata, user, password, realm);
+    if (req == NULL) {
+        close(s);
+        syslog(LOG_WARNING, "auth_httpform: create_post_data == NULL");
+        return strdup(RESP_IERROR);
+    }
+    escreq = url_escape(req);
+    if (escreq == NULL) {
+        memset(req, 0, strlen(req));
+        free(req); 
+        close(s);
+        syslog(LOG_WARNING, "auth_httpform: url_escape == NULL");
+        return strdup(RESP_IERROR);
+    }
+
+    postlen = snprintf(postbuf, RESP_LEN-1,
+              "POST %s HTTP/1.1" CRLF
+              "Host: %s:%s" CRLF
+              "User-Agent: saslauthd" CRLF
+              "Accept: */*" CRLF
+              "Content-Type: application/x-www-form-urlencoded" CRLF
+              "Content-Length: %d" TWO_CRLF
+              "%s",
+              r_uri, r_host, r_port, strlen(escreq), escreq);
+
+    if (flags & VERBOSE) {
+        syslog(LOG_DEBUG, "auth_httpform: sending %s %s %s",
+               r_host, r_uri, escreq);
+    }
+    
+    /* send it */
+    alarm(NETWORK_IO_TIMEOUT);
+    rc = tx_rec(s, postbuf, postlen);
+    alarm(0);
+    
+    if (rc < postlen) {
+        syslog(LOG_WARNING, "auth_httpform: failed to send request");
+        memset(req, 0, strlen(req));
+        free(req); 
+        memset(escreq, 0, strlen(escreq));
+        free(escreq);
+        memset(postbuf, 0, postlen);
+        close(s);
+        return strdup(RESP_IERROR);
+    }
+
+    /* don't need these any longer */
+    memset(req, 0, strlen(req));
+    free(req); 
+    memset(escreq, 0, strlen(escreq));
+    free(escreq);
+    memset(postbuf, 0, postlen);
+
+    /* read and parse the response */
+    alarm(NETWORK_IO_TIMEOUT);
+    rc = read(s, rbuf, sizeof(rbuf));
+    alarm(0);
+    
+    close(s);                    /* we're done with the remote */
+
+    if (rc == -1) {
+        syslog(LOG_WARNING, "auth_httpform: read (response): %m");
+        return strdup(RESP_IERROR);
+    }
+
+    if (flags & VERBOSE) {
+        syslog(LOG_DEBUG, "auth_httpform: [%s] %s", user, rbuf);
+    }
+
+    rbuf[rc] = '\0';             /* make sure str-funcs find null */
+    return build_sasl_response(rbuf);
+}
+
+/* END FUNCTION: auth_httpform */
+
+/* END MODULE: auth_httpform */
diff --git a/saslauthd/auth_httpform.h b/saslauthd/auth_httpform.h
new file mode 100644 (file)
index 0000000..2a95e9c
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 2005 Pyx Engineering AG
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY PYX ENGINEERING AG ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL PYX ENGINEERING AG OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_httpform(const char *, const char *, const char *, const char *);
+int auth_httpform_init(void);
diff --git a/saslauthd/auth_krb4.c b/saslauthd/auth_krb4.c
new file mode 100644 (file)
index 0000000..39e2bd2
--- /dev/null
@@ -0,0 +1,295 @@
+/* MODULE: auth_krb4 */
+
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifdef __GNUC__
+#ident "$Id: auth_krb4.c,v 1.12 2005/02/01 12:26:34 mel Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include <unistd.h>
+#include "mechanisms.h"
+#include "globals.h"
+#include "cfile.h"
+#include "krbtf.h"
+
+#ifdef AUTH_KRB4
+
+# include <krb.h>
+
+# ifdef WITH_DES
+#  ifdef WITH_SSL_DES
+#   include <openssl/des.h>
+#  else
+#   include <des.h>
+#  endif /* WITH_SSL_DES */
+# endif /* WITH_DES */
+
+#endif /* AUTH_KRB4 */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include "auth_krb4.h"
+
+#ifdef DEADCODE
+extern int swap_bytes;                 /* from libkrb.a   */
+#endif /* DEADCODE */
+/* END PUBLIC DEPENDENCIES */
+
+/* PRIVATE DEPENDENCIES */
+#ifdef AUTH_KRB4
+static char default_realm[REALM_SZ];
+static cfile config = 0;
+static char myhostname[BUFSIZ];    /* Is BUFSIZ right here? */
+static char *srvtabname = "";      /* "" means "system default srvtab" */
+static char *verify_principal = "rcmd"; /* A principal in the default srvtab */
+#endif /* AUTH_KRB4 */
+/* END PRIVATE DEPENDENCIES */
+
+#define TF_NAME_LEN 128
+
+/* Kerberos for Macintosh doesn't define this, so we will. (Thanks Fink!) */
+#ifndef KRB_TICKET_GRANTING_TICKET
+#define KRB_TICKET_GRANTING_TICKET "krbtgt"
+#endif /* !defined(KRB_TICKET_GRANTING_TICKET) */
+
+\f
+/* FUNCTION: auth_krb4_init */
+
+/* SYNOPSIS
+ * Initialize the Kerberos IV authentication environment.
+ *
+ * krb4 proxy authentication has a side effect of creating a ticket
+ * file for the user we are authenticating. We keep these in a private
+ * directory so as not to override a system ticket file that may be
+ * in use.
+ *
+ * This function tries to create the directory, and initializes the
+ * global variable tf_dir with the pathname of the directory.
+ * END SYNOPSIS */
+
+int                                    /* R: -1 on failure, else 0 */
+auth_krb4_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+#ifdef AUTH_KRB4
+    /* VARIABLES */
+    int rc;                            /* return code holder */
+    char *configname = 0;
+    /* END VARIABLES */
+
+    if (mech_option)
+      configname = mech_option;
+    else if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0)
+      configname = SASLAUTHD_CONF_FILE_DEFAULT;
+
+    if (configname) {
+      char complaint[1024];
+
+      config = cfile_read(configname, complaint, sizeof(complaint));
+      if (!config) {
+       syslog(LOG_ERR, "auth_krb4_init %s", complaint);
+       return -1;
+      }
+    }
+
+    if (config) {
+      srvtabname = cfile_getstring(config, "krb4_srvtab", srvtabname);
+      verify_principal = cfile_getstring(config, "krb4_verify_principal",
+                                        verify_principal);
+    }
+    
+    if (krbtf_init() == -1) {
+      syslog(LOG_ERR, "auth_krb4_init krbtf_init failed");
+      return -1;
+    }
+
+    rc = krb_get_lrealm(default_realm, 1);
+    if (rc) {
+       syslog(LOG_ERR, "auth_krb4: krb_get_lrealm: %s",
+              krb_get_err_text(rc));
+       return -1;
+    }
+
+    if (gethostname(myhostname, sizeof(myhostname)) < 0) {
+      syslog(LOG_ERR, "auth_krb4: gethoanem(): %m");
+      return -1;
+    }
+    myhostname[sizeof(myhostname) - 1] = '\0';
+
+    return 0;
+#else /* ! AUTH_KRB4 */
+    return -1;
+#endif /* ! AUTH_KRB4 */
+}
+
+/* END FUNCTION: auth_krb4_init */
+\f
+/* FUNCTION: auth_krb4 */
+
+/* SYNOPSIS
+ * Authenticate against Kerberos IV.
+ * END SYNOPSIS */
+
+#ifdef AUTH_KRB4
+
+char *                                 /* R: allocated response string */
+auth_krb4 (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,
+  const char *realm_in
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    char aname[ANAME_SZ];              /* Kerberos principal */
+    const char *realm;                 /* Kerberos realm to authenticate in */
+    int rc;                            /* return code */
+    char tf_name[TF_NAME_LEN];         /* Ticket file name */
+    char *instance, *user_specified;
+    KTEXT_ST ticket;
+    AUTH_DAT kdata;
+    /* END VARIABLES */
+
+    /*
+     * Make sure we have a password. If this is NULL the call
+     * to krb_get_pw_in_tkt below would try to prompt for
+     * one interactively.
+     */
+    if (password == NULL) {
+       syslog(LOG_ERR, "auth_krb4: NULL password?");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (krbtf_name(tf_name, sizeof(tf_name)) != 0) {
+      syslog(LOG_ERR, "auth_krb4: could not generate ticket file name");
+      return strdup("NO saslauthd internal error");
+    }
+    krb_set_tkt_string(tf_name);
+
+    strncpy(aname, login, ANAME_SZ-1);
+    aname[ANAME_SZ-1] = '\0';
+
+    instance = "";
+
+    if (config) {
+      char keyname[1024];
+
+      snprintf(keyname, sizeof(keyname), "krb4_%s_instance", service);
+      instance = cfile_getstring(config, keyname, "");
+    }
+
+    user_specified = strchr(aname, '.');
+    if (user_specified) {
+      if (instance && instance[0]) {
+       /* sysadmin specified a (mandatory) instance */
+       if (strcmp(user_specified + 1, instance)) {
+         return strdup("NO saslauthd principal name error");
+       }
+       /* nuke instance from "aname"-- matches what's already in "instance" */
+       *user_specified = '\0';
+      } else {
+       /* sysadmin has no preference, so we shift
+        * instance name from "aname" to "instance"
+        */
+       *user_specified = '\0';
+       instance = user_specified + 1;
+      }
+    }
+
+    if(realm_in && *realm_in != '\0') {
+       realm = realm_in;
+    } else {
+       realm = default_realm;
+    }
+
+    rc = krb_get_pw_in_tkt(aname, instance, realm,
+                          KRB_TICKET_GRANTING_TICKET,
+                          realm, 1, password);
+
+    if (rc == INTK_BADPW || rc == KDC_PR_UNKNOWN) {
+       return strdup("NO");
+    } else if (rc != KSUCCESS) {
+      syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
+            krb_get_err_text(rc));
+
+      return strdup("NO saslauthd internal error");
+    }
+
+    /* if the TGT wasn't spoofed, it should entitle us to an rcmd ticket... */
+    rc = krb_mk_req(&ticket, verify_principal, myhostname, default_realm, 0);
+
+    if (rc != KSUCCESS) {
+      syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
+            krb_get_err_text(rc));
+      dest_tkt();
+      return strdup("NO saslauthd internal error");
+    }
+
+    /* .. and that ticket should match our secret host key */
+    rc = krb_rd_req(&ticket, verify_principal, myhostname, 0, &kdata, srvtabname);
+
+    if (rc != RD_AP_OK) {
+      syslog(LOG_ERR, "ERROR: auth_krb4: krb_rd_req:%s",
+            krb_get_err_text(rc));
+      dest_tkt();
+      return strdup("NO saslauthd internal error");
+    }
+
+    dest_tkt();
+
+    return strdup("OK");
+}
+
+#else /* ! AUTH_KRB4 */
+
+char *
+auth_krb4 (
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+    return NULL;
+}
+
+#endif /* ! AUTH_KRB4 */
+
+/* END FUNCTION: auth_krb4 */
+
+/* END MODULE: auth_krb4 */
diff --git a/saslauthd/auth_krb4.h b/saslauthd/auth_krb4.h
new file mode 100644 (file)
index 0000000..7de941e
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_krb4(const char *, const char *, const char *, const char *);
+int auth_krb4_init(void);
diff --git a/saslauthd/auth_krb5.c b/saslauthd/auth_krb5.c
new file mode 100644 (file)
index 0000000..eefe4cb
--- /dev/null
@@ -0,0 +1,461 @@
+/* MODULE: auth_krb5 */
+
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifdef __GNUC__
+#ident "$Id: auth_krb5.c,v 1.17 2005/02/14 05:50:49 shadow Exp $"
+#endif
+
+/* ok, this is  wrong but the most convenient way of doing 
+ * it for now. We assume (possibly incorrectly) that if GSSAPI exists then 
+ * the Kerberos 5 headers and libraries exist.   
+ * What really should be done is a configure.in check for krb5.h and use 
+ * that since none of this code is GSSAPI but rather raw Kerberos5.
+ */
+
+
+/* Also, at some point one would hope it would be possible to
+ * have less divergence between Heimdal and MIT Kerberos 5.
+ *
+ * As of the summer of 2003, the obvious issues are that
+ * MIT doesn't have krb5_verify_opt_*() and Heimdal doesn't
+ * have krb5_sname_to_principal().
+ */
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+#include "globals.h" /* mech_option */
+#include "cfile.h"
+#include "krbtf.h"
+
+#ifdef AUTH_KRB5
+# include <krb5.h>
+static cfile config = 0;
+static char *keytabname = NULL; /* "system default" */
+static char *verify_principal = "host"; /* a principal in the default keytab */
+#endif /* AUTH_KRB5 */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "auth_krb5.h"
+
+/* END PUBLIC DEPENDENCIES */
+
+int                                    /* R: -1 on failure, else 0 */
+auth_krb5_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+#ifdef AUTH_KRB5
+    int rc;
+    char *configname = 0;
+
+    if (krbtf_init() == -1) {
+       syslog(LOG_ERR, "auth_krb5_init krbtf_init failed");
+       return -1;
+    }
+
+    if (mech_option)
+       configname = mech_option;
+    else if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0)
+       configname = SASLAUTHD_CONF_FILE_DEFAULT;
+    if (configname) {
+       char complaint[1024];
+
+       if (!(config = cfile_read(configname, complaint, sizeof (complaint)))) {
+           syslog(LOG_ERR, "auth_krb5_init %s", complaint);
+           return -1;
+       }
+    }
+
+    if (config) {
+       keytabname = cfile_getstring(config, "krb5_keytab", keytabname);
+       verify_principal = cfile_getstring(config, "krb5_verify_principal", verify_principal);
+    }
+
+    return 0;
+
+#else
+    return -1;
+#endif
+}
+
+#ifdef AUTH_KRB5
+
+static int
+form_principal_name (
+  const char *user,
+  const char *service,
+  const char *realm,
+  char *pname,
+  int pnamelen
+  )
+{
+    const char *forced_instance = 0;
+       int plen;
+
+    if (config) {
+       char keyname[1024];
+
+       snprintf(keyname, sizeof (keyname), "krb5_%s_instance", service);
+       forced_instance = cfile_getstring(config, keyname, 0);
+    }
+
+    if (forced_instance) {
+       char *user_specified;
+
+       if (user_specified = strchr(user, '/')) {
+           if (strcmp(user_specified + 1, forced_instance)) {
+               /* user not allowed to override sysadmin */
+               return -1;
+           } else {
+               /* don't need to force--user already asked for it */
+               forced_instance = 0;
+           }
+       }
+    }
+
+    /* form user[/instance][@realm] */
+    plen = snprintf(pname, pnamelen, "%s%s%s%s%s",
+       user,
+       (forced_instance ? "/" : ""),
+       (forced_instance ? forced_instance : ""),
+       ((realm && realm[0]) ? "@" : ""),
+       ((realm && realm[0]) ? realm : "")
+       );
+    if ((plen <= 0) || (plen >= pnamelen))
+       return -1;
+
+    /* Perhaps we should uppercase the realm? */
+
+    return 0;
+}
+
+#ifdef KRB5_HEIMDAL
+
+char *                                 /* R: allocated response string */
+auth_krb5 (
+  /* PARAMETERS */
+  const char *user,                    /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,                  /* I: service authenticating to */
+  const char *realm                     /* I: user's realm */
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    krb5_context context;
+    krb5_ccache ccache = NULL;
+    krb5_keytab kt = NULL;
+    krb5_principal auth_user;
+    krb5_verify_opt opt;
+    char * result;
+    char tfname[2048];
+    char principalbuf[2048];
+    /* END VARIABLES */
+
+    if (!user || !password) {
+       syslog(LOG_ERR, "auth_krb5: NULL password or username?");
+       return strdup("NO saslauthd internal NULL password or username");
+    }
+
+    if (krb5_init_context(&context)) {
+       syslog(LOG_ERR, "auth_krb5: krb5_init_context");
+       return strdup("NO saslauthd internal krb5_init_context error");
+    }
+
+    if (form_principal_name(user, service, realm, principalbuf, sizeof (principalbuf))) {
+       syslog(LOG_ERR, "auth_krb5: form_principal_name");
+       return strdup("NO saslauthd principal name error");
+    }
+
+    if (krb5_parse_name (context, principalbuf, &auth_user)) {
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_parse_name");
+       return strdup("NO saslauthd internal krb5_parse_name error");
+    }
+
+    if (krbtf_name(tfname, sizeof (tfname)) != 0) {
+       syslog(LOG_ERR, "auth_krb5: could not generate ccache name");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (krb5_cc_resolve(context, tfname, &ccache)) {
+       krb5_free_principal(context, auth_user);
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_cc_resolve");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (keytabname) {
+       if (krb5_kt_resolve(context, keytabname, &kt)) {
+           krb5_free_principal(context, auth_user);
+           krb5_cc_destroy(context, ccache);
+           krb5_free_context(context);
+           syslog(LOG_ERR, "auth_krb5: krb5_kt_resolve");
+           return strdup("NO saslauthd internal error");
+       }
+    }
+    
+    krb5_verify_opt_init(&opt);
+    krb5_verify_opt_set_secure(&opt, 1);
+    krb5_verify_opt_set_ccache(&opt, ccache);
+    if (kt)
+       krb5_verify_opt_set_keytab(&opt,  kt);
+    krb5_verify_opt_set_service(&opt, verify_principal);
+    
+    if (krb5_verify_user_opt(context, auth_user, password, &opt)) {
+       result = strdup("NO krb5_verify_user_opt failed");
+    } else {
+        result = strdup("OK");
+    }
+    
+    krb5_free_principal(context, auth_user);
+    krb5_cc_destroy(context, ccache);
+    if (kt)
+       krb5_kt_close(context, kt);
+    krb5_free_context(context);
+
+    return result;
+}
+
+#else /* !KRB5_HEIMDAL */
+
+/* returns 0 for failure, 1 for success */
+static int k5support_verify_tgt(krb5_context context, 
+                               krb5_ccache ccache) 
+{
+    krb5_principal server;
+    krb5_data packet;
+    krb5_keyblock *keyblock = NULL;
+    krb5_auth_context auth_context = NULL;
+    krb5_error_code k5_retcode;
+    krb5_keytab kt = NULL;
+    char thishost[BUFSIZ];
+    int result = 0;
+    
+    memset(&packet, 0, sizeof(packet));
+
+    if (krb5_sname_to_principal(context, NULL, verify_principal,
+                               KRB5_NT_SRV_HST, &server)) {
+       return 0;
+    }
+
+    if (keytabname) {
+       if (krb5_kt_resolve(context, keytabname, &kt)) {
+           goto fini;
+       }
+    }
+    
+    if (krb5_kt_read_service_key(context, kt, server, 0,
+                                0, &keyblock)) {
+       goto fini;
+    }
+    
+    if (keyblock) {
+       krb5_free_keyblock(context, keyblock);
+    }
+    
+    /* this duplicates work done in krb5_sname_to_principal
+     * oh well.
+     */
+    if (gethostname(thishost, BUFSIZ) < 0) {
+       goto fini;
+    }
+    thishost[BUFSIZ-1] = '\0';
+    
+    k5_retcode = krb5_mk_req(context, &auth_context, 0, verify_principal, 
+                            thishost, NULL, ccache, &packet);
+    
+    if (auth_context) {
+       krb5_auth_con_free(context, auth_context);
+       auth_context = NULL;
+    }
+    
+    if (k5_retcode) {
+       goto fini;
+    }
+    
+    if (krb5_rd_req(context, &auth_context, &packet, 
+                   server, NULL, NULL, NULL)) {
+       goto fini;
+    }
+
+    if (auth_context) {
+      krb5_auth_con_free(context, auth_context);
+      auth_context = NULL;
+    }
+    
+    /* all is good now */
+    result = 1;
+ fini:
+    krb5_free_data_contents(context, &packet);
+    krb5_free_principal(context, server);
+    
+    return result;
+}
+
+/* FUNCTION: auth_krb5 */
+
+/* SYNOPSIS
+ * Authenticate against Kerberos V.
+ * END SYNOPSIS */
+
+char *                                 /* R: allocated response string */
+auth_krb5 (
+  /* PARAMETERS */
+  const char *user,                    /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,                 /* I: service authenticating to */
+  const char *realm                    /* I: user's realm */
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    krb5_context context;
+    krb5_ccache ccache = NULL;
+    krb5_principal auth_user;
+    krb5_creds creds;
+    krb5_get_init_creds_opt opts;
+    char * result;
+    char tfname[2048];
+    char principalbuf[2048];
+    krb5_error_code code;
+    /* END VARIABLES */
+
+    if (!user|| !password) {
+       syslog(LOG_ERR, "auth_krb5: NULL password or username?");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (krb5_init_context(&context)) {
+       syslog(LOG_ERR, "auth_krb5: krb5_init_context");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (form_principal_name(user, service, realm, principalbuf, sizeof (principalbuf))) {
+       syslog(LOG_ERR, "auth_krb5: form_principal_name");
+       return strdup("NO saslauthd principal name error");
+    }
+
+    if (krb5_parse_name (context, principalbuf, &auth_user)) {
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_parse_name");
+       return strdup("NO saslauthd internal error");
+    }
+    
+    if (krbtf_name(tfname, sizeof (tfname)) != 0) {
+       syslog(LOG_ERR, "auth_krb5: could not generate ticket file name");
+       return strdup("NO saslauthd internal error");
+    }
+
+    if (krb5_cc_resolve(context, tfname, &ccache)) {
+       krb5_free_principal(context, auth_user);
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_cc_resolve");
+       return strdup("NO saslauthd internal error");
+    }
+    
+    if (krb5_cc_initialize (context, ccache, auth_user)) {
+       krb5_free_principal(context, auth_user);
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_cc_initialize");
+       return strdup("NO saslauthd internal error");
+    }
+    
+    krb5_get_init_creds_opt_init(&opts);
+    /* 15 min should be more than enough */
+    krb5_get_init_creds_opt_set_tkt_life(&opts, 900); 
+    if (code = krb5_get_init_creds_password(context, &creds, 
+                                    auth_user, password, NULL, NULL, 
+                                    0, NULL, &opts)) {
+       krb5_cc_destroy(context, ccache);
+       krb5_free_principal(context, auth_user);
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_get_init_creds_password: %d", code);
+       return strdup("NO saslauthd internal error");
+    }
+    
+    /* at this point we should have a TGT. Let's make sure it is valid */
+    if (krb5_cc_store_cred(context, ccache, &creds)) {
+       krb5_free_principal(context, auth_user);
+       krb5_cc_destroy(context, ccache);
+       krb5_free_context(context);
+       syslog(LOG_ERR, "auth_krb5: krb5_cc_store_cred");
+       return strdup("NO saslauthd internal error");
+    }
+    
+    if (!k5support_verify_tgt(context, ccache)) {
+       syslog(LOG_ERR, "auth_krb5: k5support_verify_tgt");
+       result = strdup("NO saslauthd internal error");
+       goto fini;
+    }
+    
+    /* 
+     * fall through -- user is valid beyond this point  
+     */
+    
+    result = strdup("OK");
+ fini:
+/* destroy any tickets we had */
+    krb5_free_cred_contents(context, &creds);
+    krb5_free_principal(context, auth_user);
+    krb5_cc_destroy(context, ccache);
+    krb5_free_context(context);
+
+    return result;
+}
+
+#endif /* KRB5_HEIMDAL */
+
+#else /* ! AUTH_KRB5 */
+
+char *
+auth_krb5 (
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+    return NULL;
+}
+
+#endif /* ! AUTH_KRB5 */
+
+/* END FUNCTION: auth_krb5 */
+
+/* END MODULE: auth_krb5 */
diff --git a/saslauthd/auth_krb5.h b/saslauthd/auth_krb5.h
new file mode 100644 (file)
index 0000000..39a3a88
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_krb5(const char *, const char *, const char *, const char *);
+int auth_krb5_init(void);
diff --git a/saslauthd/auth_ldap.c b/saslauthd/auth_ldap.c
new file mode 100644 (file)
index 0000000..c8d2878
--- /dev/null
@@ -0,0 +1,129 @@
+/* MODULE: auth_ldap */
+/* COPYRIGHT
+ * Copyright (c) 2002-2002 Igor Brezac
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IGOR BREZAC OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * Authenticate against LDAP.
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_ldap.c,v 1.17 2004/12/08 12:12:27 mel Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+#include "mechanisms.h"
+
+/* END PUBLIC DEPENDENCIES */
+
+# define RETURN(x) {return strdup(x);}
+\f
+/* FUNCTION: auth_ldap */
+
+#ifdef AUTH_LDAP
+
+#include "lak.h"
+#include "globals.h"
+
+const char *SASLAUTHD_CONF_FILE = SASLAUTHD_CONF_FILE_DEFAULT;
+
+char *                                 /* R: allocated response string */
+auth_ldap(
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,
+  const char *realm
+  /* END PARAMETERS */
+  )
+{
+       static LAK *lak = NULL;
+       int rc = 0;
+
+       if (lak == NULL) {
+               rc = lak_init(SASLAUTHD_CONF_FILE, &lak);
+               if (rc != LAK_OK) {
+                       lak = NULL;
+                       RETURN("NO");
+               }
+       }
+
+       rc = lak_authenticate(lak, login, service, realm, password);
+       if (rc == LAK_OK) {
+               RETURN("OK");
+       } else {
+               RETURN("NO");
+       }
+}
+
+/* FUNCTION: auth_ldap_init */
+
+/* SYNOPSIS
+ * Validate the host and service names for the remote server.
+ * END SYNOPSIS */
+
+int
+auth_ldap_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    struct addrinfo hints;
+    int err;
+    char *c;                           /* scratch pointer               */
+    /* END VARIABLES */
+
+    if (mech_option != NULL) {
+       SASLAUTHD_CONF_FILE = mech_option;
+    }
+
+    return 0;
+}
+
+#else /* !AUTH_LDAP */
+
+char *
+auth_ldap(
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+     return NULL;
+}
+
+#endif /* !AUTH_LDAP */
+
+/* END FUNCTION: auth_ldap */
+
+/* END MODULE: auth_ldap */
diff --git a/saslauthd/auth_ldap.h b/saslauthd/auth_ldap.h
new file mode 100644 (file)
index 0000000..983a6fc
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 2002-2002 Igor Brezac
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IGOR BREZAC OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_ldap(const char *, const char *, const char *, const char *);
+int auth_ldap_init(void);
diff --git a/saslauthd/auth_pam.c b/saslauthd/auth_pam.c
new file mode 100644 (file)
index 0000000..5af938f
--- /dev/null
@@ -0,0 +1,253 @@
+/* MODULE: auth_pam */
+
+/* COPYRIGHT
+ * Copyright (c) 2000 Fabian Knittel.  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 any existing copyright
+ *    notice, and this entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ *
+ * 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.
+ *
+ * 2. Redistributions in binary form must reproduce all prior and current
+ *    copyright notices, this list of conditions, and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/*
+ * Pluggable Authentication Modules, PAM(8), based authentication module
+ * for saslauthd.
+ *
+ * Written by Fabian Knittel <fknittel@gmx.de>. Original implementation
+ * Debian's pwcheck_pam daemon by Michael-John Turner <mj@debian.org>.
+ */
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef AUTH_PAM
+
+# include <string.h>
+# include <syslog.h>
+#ifdef HAVE_SECURITY_PAM_APPL_H
+# include <security/pam_appl.h>
+#elif defined(HAVE_PAM_PAM_APPL_H)
+# include <pam/pam_appl.h>
+#endif
+
+# include "auth_pam.h"
+/* END PUBLIC DEPENDENCIES */
+
+
+/* Structure for application specific data passed through PAM
+ * to our conv call-back routine saslauthd_pam_conv. */
+typedef struct {
+    const char *login;                 /* plaintext authenticator */
+    const char *password;              /* plaintext password */
+    pam_handle_t *pamh;                        /* pointer to PAM handle */
+} pam_appdata;
+
+# define RETURN(x) return strdup(x)
+
+\f
+/* FUNCTION: saslauthd_pam_conv */
+
+/* SYNOPSIS
+ * Call-back function used by the PAM library to communicate with us. Each
+ * received message expects a response, pointed to by resp.
+ * END SYNOPSIS */
+
+static int                             /* R: PAM return code */
+saslauthd_pam_conv (
+  /* PARAMETERS */
+  int num_msg,                         /* I: number of messages */
+  const struct pam_message **msg,      /* I: pointer to array of messages */
+  struct pam_response **resp,          /* O: pointer to pointer of response */
+  void *appdata_ptr                    /* I: pointer to app specific data */
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    pam_appdata *my_appdata;           /* application specific data */
+    struct pam_response *my_resp;      /* response created by this func */
+    int i;                             /* loop counter */
+    const char *login_prompt;          /* string prompting for user-name */
+    int rc;                            /* return code holder */
+    /* END VARIABLES */
+
+    my_appdata = appdata_ptr;
+
+    my_resp = malloc(sizeof(struct pam_response) * num_msg);
+    if (my_resp == NULL)
+       return PAM_CONV_ERR;
+
+    for (i = 0; i < num_msg; i++)
+       switch (msg[i]->msg_style) {
+       /*
+        * We assume PAM_PROMPT_ECHO_OFF to be a request for password.
+        * This assumption might be unsafe.
+        *
+        * For PAM_PROMPT_ECHO_ON we first check whether the provided
+        * request string matches PAM_USER_PROMPT and, only if they do
+        * match, assume it to be a request for the login.
+        */
+       case PAM_PROMPT_ECHO_OFF:       /* password */
+           my_resp[i].resp = strdup(my_appdata->password);
+           if (my_resp[i].resp == NULL) {
+               syslog(LOG_DEBUG, "DEBUG: saslauthd_pam_conv: strdup failed");
+               goto ret_error;
+           }
+           my_resp[i].resp_retcode = PAM_SUCCESS;
+           break;
+
+       case PAM_PROMPT_ECHO_ON:        /* username? */
+           /* Recheck setting each time, as it might have been changed
+              in the mean-while. */
+           rc = pam_get_item(my_appdata->pamh, PAM_USER_PROMPT,
+                             (void *) &login_prompt);
+           if (rc != PAM_SUCCESS) {
+               syslog(LOG_DEBUG, "DEBUG: saslauthd_pam_conv: unable to read "
+                      "login prompt string: %s",
+                      pam_strerror(my_appdata->pamh, rc));
+               goto ret_error;
+           }
+
+           if (strcmp(msg[i]->msg, login_prompt) == 0) {
+               my_resp[i].resp = strdup(my_appdata->login);
+               my_resp[i].resp_retcode = PAM_SUCCESS;
+           } else {                    /* ignore */
+               syslog(LOG_DEBUG, "DEBUG: saslauthd_pam_conv: unknown prompt "
+                      "string: %s", msg[i]->msg);
+               my_resp[i].resp = NULL;
+               my_resp[i].resp_retcode = PAM_SUCCESS;
+           }
+           break;
+
+       case PAM_ERROR_MSG:             /* ignore */
+       case PAM_TEXT_INFO:             /* ignore */
+           my_resp[i].resp = NULL;
+           my_resp[i].resp_retcode = PAM_SUCCESS;
+           break;
+
+       default:                        /* error */
+           goto ret_error;
+       }
+    *resp = my_resp;
+    return PAM_SUCCESS;
+
+ret_error:
+    /*
+     * Free response structure. Don't free my_resp[i], as that
+     * isn't initialised yet.
+     */
+    {
+       int y;
+
+       for (y = 0; y < i; y++)
+           if (my_resp[y].resp != NULL)
+               free(my_resp[y].resp);
+       free(my_resp);
+    }
+    return PAM_CONV_ERR;
+}
+
+/* END FUNCTION: saslauthd_pam_conv */
+\f
+/* FUNCTION: auth_pam */
+
+char *                                 /* R: allocated response string */
+auth_pam (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service,                 /* I: service name */
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    pam_appdata my_appdata;            /* application specific data */
+    struct pam_conv my_conv;           /* pam conversion data */
+    pam_handle_t *pamh;                        /* pointer to PAM handle */
+    int rc;                            /* return code holder */
+    /* END VARIABLES */
+
+    my_appdata.login = login;
+    my_appdata.password = password;
+    my_appdata.pamh = NULL;
+
+    my_conv.conv = saslauthd_pam_conv;
+    my_conv.appdata_ptr = &my_appdata;
+
+    rc = pam_start(service, login, &my_conv, &pamh);
+    if (rc != PAM_SUCCESS) {
+       syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_start failed: %s",
+              pam_strerror(pamh, rc));
+       RETURN("NO PAM start error");
+    }
+
+    my_appdata.pamh = pamh;
+
+    rc = pam_authenticate(pamh, PAM_SILENT);
+    if (rc != PAM_SUCCESS) {
+       syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_authenticate failed: %s",
+              pam_strerror(pamh, rc));
+       pam_end(pamh, rc);
+       RETURN("NO PAM auth error");
+    }
+
+    rc = pam_acct_mgmt(pamh, PAM_SILENT);
+    if (rc != PAM_SUCCESS) {
+       syslog(LOG_DEBUG, "DEBUG: auth_pam: pam_acct_mgmt failed: %s",
+              pam_strerror(pamh, rc));
+       pam_end(pamh, rc);
+       RETURN("NO PAM acct error");
+    }
+
+    pam_end(pamh, PAM_SUCCESS);
+    RETURN("OK");
+}
+
+/* END FUNCTION: auth_pam */
+
+#else /* !AUTH_PAM */
+
+char *
+auth_pam(
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+    return NULL;
+}
+
+#endif /* !AUTH_PAM */
+
+/* END MODULE: auth_pam */
diff --git a/saslauthd/auth_pam.h b/saslauthd/auth_pam.h
new file mode 100644 (file)
index 0000000..4f57e8d
--- /dev/null
@@ -0,0 +1,35 @@
+/* COPYRIGHT
+ * Copyright (c) 2000 Fabian Knittel.  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 any existing copyright
+ *    notice, and this entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ *
+ * 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.
+ *
+ * 2. Redistributions in binary form must reproduce all prior and current
+ *    copyright notices, this list of conditions, and the following
+ *    disclaimer in the documentation and/or other materials provided
+ *    with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_pam(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/auth_rimap.c b/saslauthd/auth_rimap.c
new file mode 100644 (file)
index 0000000..9bc9e73
--- /dev/null
@@ -0,0 +1,490 @@
+/* MODULE: auth_rimap */
+
+/* COPYRIGHT
+ * Copyright (c) 1998 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * 
+ * Copyright 1998, 1999 Carnegie Mellon University
+ * 
+ *                       All Rights Reserved
+ * 
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the name of Carnegie Mellon
+ * University not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission.
+ * 
+ * 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.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * Proxy authentication to a remote IMAP (or IMSP) server.
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_rimap.c,v 1.12 2006/04/06 20:19:54 jeaton Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#ifdef _AIX
+# include <strings.h>
+#endif /* _AIX */
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <netdb.h>
+
+#include "auth_rimap.h"
+#include "utils.h"
+#include "globals.h"
+/* END PUBLIC DEPENDENCIES */
+
+/* PRIVATE DEPENDENCIES */
+static const char *r_host = NULL;       /* remote hostname (mech_option) */
+static struct addrinfo *ai = NULL;     /* remote authentication host    */
+/* END PRIVATE DEPENDENCIES */
+
+#define DEFAULT_REMOTE_SERVICE "imap"  /* getservbyname() name for remote
+                                          service we connect to.        */
+#define TAG "saslauthd"                        /* IMAP command tag */
+#define LOGIN_CMD (TAG " LOGIN ")      /* IMAP login command (with tag) */
+#define NETWORK_IO_TIMEOUT 30          /* network I/O timeout (seconds) */
+#define RESP_LEN 1000                  /* size of read response buffer  */
+
+/* Common failure response strings for auth_rimap() */
+
+#define RESP_IERROR    "NO [ALERT] saslauthd internal error"
+#define RESP_UNAVAILABLE "NO [ALERT] The remote authentication server is currently unavailable"
+#define RESP_UNEXPECTED        "NO [ALERT] Unexpected response from remote authentication server"
+\f
+/* FUNCTION: sig_null */
+
+/* SYNOPSIS
+ * Catch and ignore a signal.
+ * END SYNOPSIS */
+
+static RETSIGTYPE                              /* R: OS dependent */
+sig_null (
+  /* PARAMETERS */
+  int sig                                      /* I: signal being caught */
+  /* END PARAMETERS */
+  )
+{
+
+    switch (sig) {
+       
+      case SIGALRM:
+       signal(SIGALRM, sig_null);
+       break;
+
+      case SIGPIPE:
+       signal(SIGPIPE, sig_null);
+       break;
+
+      default:
+       syslog(LOG_WARNING, "auth_rimap: unexpected signal %d", sig);
+       break;
+    }
+#ifdef __APPLE__
+    return;
+#else /* __APPLE__ */
+# if RETSIGTYPE == void
+    return;
+# else /* RETSIGTYPE */
+    return 0;
+# endif /* RETSIGTYPE */
+#endif /* __APPLE__ */
+}
+
+/* END FUNCTION: sig_null */
+\f
+/* FUNCTION: qstring */
+
+/* SYNOPSIS
+ * Quote a string for transmission over the IMAP protocol.
+ * END SYNOPSIS */
+
+static char *                          /* R: the quoted string         */
+qstring (
+  /* PARAMETERS */
+  const char *s                                /* I: string to quote           */
+  /* END PARAMETERS */
+  )
+{
+    char *c;                           /* pointer to returned string   */
+    register const char *p1;           /* scratch pointers             */
+    register char *p2;                 /* scratch pointers             */
+    int len;                           /* length of array to malloc    */
+    int num_quotes;                    /* number of '"' chars in string*/
+
+    /* see of we have to deal with any '"' characters */
+    num_quotes = 0;
+    p1 = s;
+    while ((p1 = strchr(p1, '"')) != NULL) {
+       num_quotes++;
+    }
+    
+    if (!num_quotes) {
+       /*
+        * no double-quotes to escape, so just wrap the input string
+        * in double-quotes and return it.
+        */
+       len = strlen(s) + 2 + 1;
+       c = malloc(len);
+       if (c == NULL) {
+           return NULL;
+       }
+       *c = '"';
+        *(c+1) = '\0';
+       strcat(c, s);
+       strcat(c, "\"");
+       return c;
+    }
+    /*
+     * Ugh, we have to escape double quotes ...
+     */
+    len = strlen(s) + 2 + (2*num_quotes) + 1;
+    c = malloc(len);
+    if (c == NULL) {
+       return NULL;
+    }
+    p1 = s;
+    p2 = c;
+    *p2++ = '"';
+    while (*p1) {
+       if (*p1 == '"') {
+           *p2++ = '\\';               /* escape the '"' */
+       }
+       *p2++ = *p1++;
+    }
+    strcat(p2, "\"");
+    return c;
+}
+
+/* END FUNCTION: qstring */
+\f
+/* FUNCTION: auth_rimap_init */
+
+/* SYNOPSIS
+ * Validate the host and service names for the remote server.
+ * END SYNOPSIS */
+
+int
+auth_rimap_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+
+    /* VARIABLES */
+    struct addrinfo hints;
+    int err;
+    char *c;                           /* scratch pointer               */
+    /* END VARIABLES */
+
+    if (mech_option == NULL) {
+       syslog(LOG_ERR, "rimap_init: no hostname specified");
+       return -1;
+    } else {
+       r_host = mech_option;
+    }
+
+    /* Determine the port number to connect to.
+     *
+     * r_host has already been initialized to the hostname and optional port
+     * port name to connect to. The format of the string is:
+     *
+     *         hostname
+     * or
+     *         hostname/port
+     */
+
+    c = strchr(r_host, '/');           /* look for optional service  */
+    
+    if (c != NULL) {
+       *c++ = '\0';                    /* tie off hostname and point */
+                                       /* to service string          */
+    } else {
+       c = DEFAULT_REMOTE_SERVICE;
+    }
+
+    if (ai)
+       freeaddrinfo(ai);
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = PF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_CANONNAME;
+    if ((err = getaddrinfo(r_host, c, &hints, &ai)) != 0) {
+       syslog(LOG_ERR, "auth_rimap_init: getaddrinfo %s/%s: %s",
+              r_host, c, gai_strerror(err));
+       return -1;
+     }
+    /* Make sure we have AF_INET or AF_INET6 addresses. */
+    if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) {
+       syslog(LOG_ERR, "auth_rimap_init: no IP address info for %s",
+              ai->ai_canonname ? ai->ai_canonname : r_host);
+       freeaddrinfo(ai);
+       ai = NULL;
+       return -1;
+    }
+
+    return 0;
+}
+
+/* END FUNCTION: auth_rimap_init */
+\f
+/* FUNCTION: auth_rimap */
+
+/* SYNOPSIS
+ * Proxy authenticate to a remote IMAP server.
+ *
+ * This mechanism takes the plaintext authenticator and password, forms
+ * them into an IMAP LOGIN command, then attempts to authenticate to
+ * a remote IMAP server using those values. If the remote authentication
+ * succeeds the credentials are considered valid.
+ *
+ * NOTE: since IMSP uses the same form of LOGIN command as IMAP does,
+ * this driver will also work with IMSP servers.
+ */
+
+/* XXX This should be extended to support SASL PLAIN authentication */
+
+char *                                 /* R: Allocated response string */
+auth_rimap (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    int        s=-1;                           /* socket to remote auth host   */
+    struct addrinfo *r;                        /* remote socket address info   */
+    struct iovec iov[5];               /* for sending LOGIN command    */
+    char *qlogin;                      /* pointer to "quoted" login    */
+    char *qpass;                       /* pointer to "quoted" password */
+    char *c;                           /* scratch pointer              */
+    int rc;                            /* return code scratch area     */
+    char rbuf[RESP_LEN];               /* response read buffer         */
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    int saved_errno;
+    int niflags;
+    /* END VARIABLES */
+
+    /* sanity checks */
+    assert(login != NULL);
+    assert(password != NULL);
+
+    /*establish connection to remote */
+    for (r = ai; r; r = r->ai_next) {
+       s = socket(r->ai_family, r->ai_socktype, r->ai_protocol);
+       if (s < 0)
+           continue;
+       if (connect(s, r->ai_addr, r->ai_addrlen) >= 0)
+           break;
+       close(s);
+       s = -1;
+       saved_errno = errno;
+       niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+       if (r->ai_family == AF_INET6)
+           niflags |= NI_WITHSCOPEID;
+#endif
+       if (getnameinfo(r->ai_addr, r->ai_addrlen, hbuf, sizeof(hbuf),
+                       pbuf, sizeof(pbuf), niflags) != 0) {
+           strlcpy(hbuf, "unknown", sizeof(hbuf));
+           strlcpy(pbuf, "unknown", sizeof(pbuf));
+       }
+       errno = saved_errno;
+       syslog(LOG_WARNING, "auth_rimap: connect %s[%s]/%s: %m",
+              ai->ai_canonname ? ai->ai_canonname : r_host, hbuf, pbuf);
+    }
+    if (s < 0) {
+       if (getnameinfo(ai->ai_addr, ai->ai_addrlen, NULL, 0,
+                       pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0)
+           strlcpy(pbuf, "unknown", sizeof(pbuf));
+       syslog(LOG_WARNING, "auth_rimap: couldn't connect to %s/%s",
+              ai->ai_canonname ? ai->ai_canonname : r_host, pbuf);
+       return strdup("NO [ALERT] Couldn't contact remote authentication server");
+    }
+
+    /* CLAIM: we now have a TCP connection to the remote IMAP server */
+
+    /*
+     * Install noop signal handlers. These just reinstall the handler
+     * and return so that we take an EINTR during network I/O.
+     */
+    (void) signal(SIGALRM, sig_null);
+    (void) signal(SIGPIPE, sig_null);
+    
+    /* read and parse the IMAP banner */
+
+    alarm(NETWORK_IO_TIMEOUT);
+    rc = read(s, rbuf, sizeof(rbuf));
+    alarm(0);
+    if (rc == -1) {
+       syslog(LOG_WARNING, "auth_rimap: read (banner): %m");
+       (void) close(s);
+       return strdup("NO [ALERT] error synchronizing with remote authentication server");
+    }
+    rbuf[rc] = '\0';                   /* tie off response */
+    c = strpbrk(rbuf, "\r\n");
+    if (c != NULL) {
+       *c = '\0';                      /* tie off line termination */
+    }
+
+    if (!strncmp(rbuf, "* NO", sizeof("* NO")-1)) {
+       (void) close(s);
+       return strdup(RESP_UNAVAILABLE);
+    }
+    if (!strncmp(rbuf, "* BYE", sizeof("* BYE")-1)) {
+       (void) close(s);
+       return strdup(RESP_UNAVAILABLE);
+    }
+    if (strncmp(rbuf, "* OK", sizeof("* OK")-1)) {
+       syslog(LOG_WARNING,
+              "auth_rimap: unexpected response during initial handshake: %s",
+              rbuf);
+       (void) close(s);
+       return strdup(RESP_UNEXPECTED);
+    }
+    
+    /* build the LOGIN command */
+
+    qlogin = qstring(login);           /* quote login */
+    qpass = qstring(password);         /* quote password */
+    if (qlogin == NULL) {
+       if (qpass != NULL) {
+           memset(qpass, 0, strlen(qpass));
+           free(qpass);
+       }
+       (void) close(s);
+       syslog(LOG_WARNING, "auth_rimap: qstring(login) == NULL");
+       return strdup(RESP_IERROR);
+    }
+    if (qpass == NULL) {
+       if (qlogin != NULL) {
+           memset(qlogin, 0, strlen(qlogin));
+           free(qlogin);
+       }
+       (void) close(s);
+       syslog(LOG_WARNING, "auth_rimap: qstring(password) == NULL");
+       return strdup(RESP_IERROR);
+    }
+
+    iov[0].iov_base = LOGIN_CMD;
+    iov[0].iov_len  = sizeof(LOGIN_CMD) - 1;
+    iov[1].iov_base = qlogin;
+    iov[1].iov_len  = strlen(qlogin);
+    iov[2].iov_base = " ";
+    iov[2].iov_len  = sizeof(" ") - 1;
+    iov[3].iov_base = qpass;
+    iov[3].iov_len  = strlen(qpass);
+    iov[4].iov_base = "\r\n";
+    iov[4].iov_len  = sizeof("\r\n") - 1;
+
+    if (flags & VERBOSE) {
+       syslog(LOG_DEBUG, "auth_rimap: sending %s%s %s",
+              LOGIN_CMD, qlogin, qpass);
+    }
+    alarm(NETWORK_IO_TIMEOUT);
+    rc = retry_writev(s, iov, 5);
+    alarm(0);
+    if (rc == -1) {
+       syslog(LOG_WARNING, "auth_rimap: writev: %m");
+       memset(qlogin, 0, strlen(qlogin));
+       free(qlogin);
+       memset(qpass, 0, strlen(qlogin));
+       free(qpass);
+       (void)close(s);
+       return strdup(RESP_IERROR);
+    }
+
+    /* don't need these any longer */
+    memset(qlogin, 0, strlen(qlogin));
+    free(qlogin);
+    memset(qpass, 0, strlen(qlogin));
+    free(qpass);
+
+    /* read and parse the LOGIN response */
+
+    alarm(NETWORK_IO_TIMEOUT);
+    rc = read(s, rbuf, sizeof(rbuf));
+    alarm(0);
+    (void) close(s);                   /* we're done with the remote */
+    if (rc == -1) {
+       syslog(LOG_WARNING, "auth_rimap: read (response): %m");
+       return strdup(RESP_IERROR);
+    }
+
+    rbuf[rc] = '\0';                   /* tie off response */
+    c = strpbrk(rbuf, "\r\n");
+    if (c != NULL) {
+       *c = '\0';                      /* tie off line termination */
+    }
+
+     if (!strncmp(rbuf, TAG " OK", sizeof(TAG " OK")-1)) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "auth_rimap: [%s] %s", login, rbuf);
+       }
+       return strdup("OK remote authentication successful");
+    }
+    if (!strncmp(rbuf, TAG " NO", sizeof(TAG " NO")-1)) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "auth_rimap: [%s] %s", login, rbuf);
+       }
+       return strdup("NO remote server rejected your credentials");
+    }
+    syslog(LOG_WARNING, "auth_rimap: unexpected response to auth request: %s",
+          rbuf);
+    return strdup(RESP_UNEXPECTED);
+    
+}
+
+/* END FUNCTION: auth_rimap */
+
+/* END MODULE: auth_rimap */
diff --git a/saslauthd/auth_rimap.h b/saslauthd/auth_rimap.h
new file mode 100644 (file)
index 0000000..8eb101a
--- /dev/null
@@ -0,0 +1,29 @@
+/* COPYRIGHT
+ * Copyright (c) 1998 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_rimap(const char *, const char *, const char *, const char *);
+int auth_rimap_init(void);
diff --git a/saslauthd/auth_sasldb.c b/saslauthd/auth_sasldb.c
new file mode 100644 (file)
index 0000000..e1c6498
--- /dev/null
@@ -0,0 +1,171 @@
+/* MODULE: auth_sasldb */
+
+/* COPYRIGHT
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * crypt(3) based passwd file validation
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: auth_sasldb.c,v 1.5 2002/07/27 18:44:46 rjs3 Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <pwd.h>
+/* END PUBLIC DEPENDENCIES */
+
+#define RETURN(x) return strdup(x)
+\f
+
+#ifdef AUTH_SASLDB
+#include "../include/sasl.h"
+#include "../include/saslplug.h"
+#include "../sasldb/sasldb.h"
+
+static int
+vf(void *context __attribute__((unused)),
+   char *file  __attribute__((unused)),
+   int type  __attribute__((unused)))
+{
+    /* always say ok */ 
+    return SASL_OK;
+}
+
+static int lame_getcallback(sasl_conn_t *conn __attribute__((unused)),
+                           unsigned long callbackid,
+                           int (**pproc)(),
+                           void **pcontext)
+{
+    if(callbackid == SASL_CB_VERIFYFILE) {
+       *pproc = vf;
+       *pcontext = NULL;
+       return SASL_OK;
+    }
+       
+    return SASL_FAIL;
+}
+
+static void lame_log(sasl_conn_t *conn, int level, const char *fmt, ...) 
+{
+    return;
+}
+
+static void lame_seterror(sasl_conn_t *conn, unsigned flags,
+                         const char *fmt, ...) 
+{
+    return;
+}
+
+/* FUNCTION: init_lame_utils */
+/* This sets up a very minimal sasl_utils_t for use only with the
+ * database functions */
+static void init_lame_utils(sasl_utils_t *utils) 
+{
+    memset(utils, 0, sizeof(sasl_utils_t));
+
+    utils->malloc=(sasl_malloc_t *)malloc;
+    utils->calloc=(sasl_calloc_t *)calloc;
+    utils->realloc=(sasl_realloc_t *)realloc;
+    utils->free=(sasl_free_t *)free;
+
+    utils->getcallback=lame_getcallback;
+    utils->log=lame_log;
+    utils->seterror=lame_seterror;
+
+    return;
+}
+
+/* END FUNCTION: init_lame_utils */
+       
+#endif /* AUTH_SASLDB */
+
+/* FUNCTION: auth_sasldb */
+
+char *                                 /* R: allocated response string */
+auth_sasldb (
+  /* PARAMETERS */
+#ifdef AUTH_SASLDB
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm
+#else
+  const char *login __attribute__((unused)),/* I: plaintext authenticator */
+  const char *password __attribute__((unused)),  /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+#endif
+  /* END PARAMETERS */
+  )
+{
+#ifdef AUTH_SASLDB
+    /* VARIABLES */
+    char pw[1024];                     /* pointer to passwd file entry */
+    sasl_utils_t utils;
+    int ret, outsize;
+    const char *use_realm;
+    char realm_buf[MAXHOSTNAMELEN];
+    /* END VARIABLES */
+
+    init_lame_utils(&utils);
+
+    _sasl_check_db(&utils, (void *)0x1);
+
+    if(!realm || !strlen(realm)) {
+       ret = gethostname(realm_buf,MAXHOSTNAMELEN);
+       if(ret) RETURN("NO");
+       use_realm = realm_buf;
+    } else {
+       use_realm = realm;
+    }
+    
+
+    ret = _sasldb_getdata(&utils, (void *)0x1, login, use_realm,
+                         "userPassword", pw, 1024, &outsize);
+
+    if (ret != SASL_OK) {
+       RETURN("NO");
+    }
+
+    if (strcmp(pw, password)) {
+       RETURN("NO");
+    }
+
+    RETURN("OK");
+#else
+    RETURN("NO");
+#endif
+}
+
+/* END FUNCTION: auth_sasldb */
+
+/* END MODULE: auth_sasldb */
diff --git a/saslauthd/auth_sasldb.h b/saslauthd/auth_sasldb.h
new file mode 100644 (file)
index 0000000..633c360
--- /dev/null
@@ -0,0 +1,28 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_sasldb(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/auth_shadow.c b/saslauthd/auth_shadow.c
new file mode 100644 (file)
index 0000000..4083b56
--- /dev/null
@@ -0,0 +1,288 @@
+#define PWBUFSZ 256 /***SWB***/
+
+/* MODULE: auth_shadow */
+
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifdef __GNUC__
+#ident "$Id: auth_shadow.c,v 1.8 2006/04/19 19:36:25 murch Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+
+#ifdef AUTH_SHADOW
+
+# include <unistd.h>
+# include <stdlib.h>
+# include <string.h>
+# include <sys/types.h>
+# include <time.h>
+# include <pwd.h>
+# include <syslog.h>
+# ifndef HAVE_GETSPNAM
+
+# ifdef WITH_DES
+#  ifdef WITH_SSL_DES
+#   include <openssl/des.h>
+#  else
+#   include <des.h>
+#  endif /* WITH_SSL_DES */
+# endif /* WITH_DES */
+
+#endif /* ! HAVE_GETSPNAM */
+# ifdef HAVE_GETUSERPW
+#  include <userpw.h>
+#  include <usersec.h>
+# else /* ! HAVE_GETUSERPW */
+#  include <shadow.h>
+# endif /* ! HAVE_GETUSERPW */
+
+# include "auth_shadow.h"
+# include "globals.h"
+/* END PUBLIC DEPENDENCIES */
+\f
+/* FUNCTION: auth_shadow */
+
+/* SYNOPSIS
+ * Authenticate against the system shadow password database. Where
+ * possible (and if enabled by the command line arguments), enforce
+ * time-of-day and other login restrictions.
+ */
+
+char *                                 /* R: allocated response string */
+auth_shadow (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+
+/************************************************************************
+ *                                                                     *
+ * This is gross. Everyone wants to do this differently, thus we have   *
+ * to #ifdef the whole mess for each system type.                       *
+ *                                                                     *
+ ***********************************************************************/
+
+# ifdef HAVE_GETSPNAM
+
+ /***************
+ * getspnam_r() *
+ ***************/
+
+    /* VARIABLES */
+    long today;                                /* the current time */
+    char *cpw;                         /* pointer to crypt() result */
+    struct passwd      *pw;            /* return from getpwnam_r() */
+    struct spwd        *sp;            /* return from getspnam_r() */
+#  ifdef _REENTRANT
+    struct passwd pwbuf;
+    char pwdata[PWBUFSZ];              /* pwbuf indirect data goes in here */
+
+    struct spwd spbuf;
+    char spdata[PWBUFSZ];              /* spbuf indirect data goes in here */
+#  endif /* _REENTRANT */
+    /* END VARIABLES */
+
+#  define RETURN(x) return strdup(x)
+
+    /*
+     * "Magic" password field entries for SunOS.
+     *
+     * *LK* is hinted at in the shadow(4) man page, but the
+     * only definition for it (that I could find) is in the passmgmt(1M)
+     * man page.
+     *
+     * *NP* is documented in getspnam(3) and indicates the caller had
+     * insufficient permission to read the shadow password database
+     * (generally this is a NIS error).
+     */
+
+#  define SHADOW_PW_LOCKED "*LK*"      /* account locked (not used by us) */
+#  define SHADOW_PW_EPERM  "*NP*"      /* insufficient database perms */
+
+#  ifdef _REENTRANT
+#    ifdef GETXXNAM_R_5ARG
+       (void) getpwnam_r(login, &pwbuf, pwdata, sizeof(pwdata), &pw);
+#    else
+    pw = getpwnam_r(login, &pwbuf, pwdata, sizeof(pwdata));
+#    endif /* GETXXNAM_R_5ARG */
+#  else
+    pw = getpwnam(login);
+#  endif /* _REENTRANT */
+    endpwent();
+    if (pw == NULL) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "DEBUG: auth_shadow: getpwnam(%s) returned NULL", login);
+       }
+       RETURN("NO");
+    }
+
+    today = (long)time(NULL)/(24L*60*60);
+
+#  ifdef _REENTRANT
+#    ifdef GETXXNAM_R_5ARG
+       (void) getspnam_r(login, &spbuf, spdata, sizeof(spdata), &sp);
+#    else
+    sp = getspnam_r(login, &spbuf, spdata, sizeof(spdata));
+#    endif /* GETXXNAM_R_5ARG */
+#  else
+    sp = getspnam(login);
+#  endif /* _REENTRANT */
+    endspent();
+
+    if (sp == NULL) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "DEBUG: auth_shadow: getspnam(%s) returned NULL", login);
+       }
+       RETURN("NO");
+    }
+
+    if (!strcmp(sp->sp_pwdp, SHADOW_PW_EPERM)) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "DEBUG: auth_shadow: sp->sp_pwdp == SHADOW_PW_EPERM");
+       }
+       RETURN("NO Insufficient permission to access NIS authentication database (saslauthd)");
+    }
+
+    /*
+     * Note: no check for SHADOW_PW_LOCKED. Returning a "locked" notification
+     * would allow login-id namespace probes, and violates our policy of
+     * not returning any information about a login until we have validated
+     * the password.
+     */
+    cpw = strdup((const char *)crypt(password, sp->sp_pwdp));
+    if (strcmp(sp->sp_pwdp, cpw)) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "DEBUG: auth_shadow: pw mismatch: '%s' != '%s'",
+                  sp->sp_pwdp, cpw);
+       }
+       free(cpw);
+       RETURN("NO");
+    }
+    free(cpw);
+
+    /*
+     * The following fields will be set to -1 if:
+     *
+     * 1) They are not specified in the shadow database, or
+     * 2) The database is being served up by NIS.
+     */
+
+    if ((sp->sp_expire != -1) && (today > sp->sp_expire)) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "DEBUG: auth_shadow: account expired: %dl > %dl",
+                  today, sp->sp_expire);
+       }
+       RETURN("NO Account expired");
+    }
+
+    /* Remaining tests are relative to the last change date for the password */
+
+    if (sp->sp_lstchg != -1) {
+
+       if ((sp->sp_max != -1) && ((sp->sp_lstchg + sp->sp_max) < today)) {
+           if (flags & VERBOSE) {
+               syslog(LOG_DEBUG,
+                      "DEBUG: auth_shadow: password expired: %ld + %ld < %ld",
+                      sp->sp_lstchg, sp->sp_max, today);
+           }
+           RETURN("NO Password expired");
+       }
+    }
+    if (flags & VERBOSE) {
+       syslog(LOG_DEBUG, "DEBUG: auth_shadow: OK: %s", login);
+    }
+    RETURN("OK");
+
+
+# elif defined(HAVE_GETUSERPW)
+
+/*************
+ * AIX 4.1.4 *
+ ************/
+    /* VARIABLES */
+    struct userpw *upw;                                /* return from getuserpw() */
+    /* END VARIABLES */
+
+#  define RETURN(x) { endpwdb(); return strdup(x); }
+
+    if (setpwdb(S_READ) == -1) {
+       syslog(LOG_ERR, "setpwdb: %m");
+       RETURN("NO setpwdb() internal failure (saslauthd)");
+    }
+  
+    upw = getuserpw(login);
+  
+    if (upw == 0) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "auth_shadow: getuserpw(%s) == 0",
+                  login);
+       }
+       RETURN("NO");
+    }
+  
+    if (strcmp(upw->upw_passwd, crypt(password, upw->upw_passwd)) != 0) {
+       if (flags & VERBOSE) {
+           syslog(LOG_DEBUG, "auth_shadow: pw mismatch: %s != %s",
+                  password, upw->upw_passwd);
+       }
+       RETURN("NO");
+    }
+
+    RETURN("OK");
+  
+# else /* HAVE_GETUSERPW */
+
+#  error "unknown shadow authentication type"
+
+# endif /* ! HAVE_GETUSERPW */
+}
+
+#else /* !AUTH_SHADOW */
+
+char *
+auth_shadow (
+  const char *login __attribute__((unused)),
+  const char *passwd __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+    return NULL;
+}
+
+#endif /* !AUTH_SHADOW */
+
+/* END FUNCTION: auth_shadow */
+
+/* END MODULE: auth_shadow */
diff --git a/saslauthd/auth_shadow.h b/saslauthd/auth_shadow.h
new file mode 100644 (file)
index 0000000..b08c06e
--- /dev/null
@@ -0,0 +1,28 @@
+/* COPYRIGHT
+ * Copyright (c) 1997 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_shadow(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/auth_sia.c b/saslauthd/auth_sia.c
new file mode 100644 (file)
index 0000000..72268b2
--- /dev/null
@@ -0,0 +1,96 @@
+/* MODULE: auth_sia */
+
+/* COPYRIGHT
+ * Copyright (c) 1998 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifdef __GNUC__
+#ident "$Id: auth_sia.c,v 1.3 2001/12/04 02:06:55 rjs3 Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+
+#ifdef AUTH_SIA
+
+#include <string.h>
+#include <sia.h>
+#include <siad.h>
+
+#include "auth_sia.h"
+#include "globals.h"
+/* END PUBLIC DEPENDENCIES */
+\f
+/* FUNCTION: auth_sia */
+
+/* SYNOPSIS
+ * Authenticate against the Digital UNIX SIA environment.
+ */
+
+char *                                 /* R: allocated response string */
+auth_sia (
+  /* PARAMETERS */
+  const char *login,                   /* I: plaintext authenticator */
+  const char *password,                        /* I: plaintext password */
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  /* END PARAMETERS */
+  )
+{
+    /* VARIABLES */
+    int rc;
+    /* END VARIABLES */
+
+    rc = sia_validate_user(0, g_argc, g_argv, 0, login, 0, 0, 0, password);
+    if (rc == SIASUCCESS) {
+       return strdup("OK");
+    }
+    if (rc == SIAFAIL) {
+       return strdup("NO");
+    }
+    /* Shouldn't happen */
+    syslog(LOG_WARNING,
+          "auth_sia: impossible return (%d) from sia_validate_user", rc);
+    return strdup("NO (possible system error)");
+}
+
+#else /* ! AUTH_SIA */
+
+char *
+auth_sia(
+  const char *login __attribute__((unused)),
+  const char *password __attribute__((unused)),
+  const char *service __attribute__((unused)),
+  const char *realm __attribute__((unused))
+  )
+{
+    return NULL;
+}
+#endif
+
+/* END FUNCTION: auth_sia */
+
+/* END MODULE: auth_sia */
diff --git a/saslauthd/auth_sia.h b/saslauthd/auth_sia.h
new file mode 100644 (file)
index 0000000..56a328b
--- /dev/null
@@ -0,0 +1,28 @@
+/* COPYRIGHT
+ * Copyright (c) 1998 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+char *auth_sia(const char *, const char *, const char *, const char *);
diff --git a/saslauthd/cache.c b/saslauthd/cache.c
new file mode 100644 (file)
index 0000000..2b78464
--- /dev/null
@@ -0,0 +1,870 @@
+/*****************************************************************************
+ *
+ * cache.c
+ *
+ * Description:  Implements a credentail caching layer to ease the loading 
+ *               on the authentication mechanisms.
+ *
+ * Copyright (C) 2003 Jeremy Rumpf
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ *****************************************************************************/
+
+/****************************************
+ * includes
+ *****************************************/
+#include "saslauthd.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+
+#include "cache.h"
+#include "utils.h"
+#include "globals.h"
+#include "md5global.h"
+#include "saslauthd_md5.h"
+
+/****************************************
+ * module globals
+ *****************************************/
+static  struct mm_ctl  mm;
+static  struct lock_ctl        lock;
+static  struct bucket  *table = NULL;
+static  struct stats   *table_stats = NULL;
+static  unsigned int   table_size = 0;
+static  unsigned int   table_timeout = 0;
+
+/****************************************
+ * flags               global from saslauthd-main.c
+ * run_path            global from saslauthd-main.c
+ * tx_rec()            function from utils.c
+ * logger()            function from utils.c
+ *****************************************/
+
+/*************************************************************
+ * The initialization function. This function will setup
+ * the hash table's memory region, initialize the table, etc.
+ **************************************************************/
+int cache_init(void) {
+       int             bytes;
+       char            cache_magic[64];
+       void            *base;
+
+       if (!(flags & CACHE_ENABLED))
+               return 0;
+
+       memset(cache_magic, 0, sizeof(cache_magic));
+       strlcpy(cache_magic, CACHE_CACHE_MAGIC, sizeof(cache_magic));
+
+       /**************************************************************
+        * Compute the size of the hash table. This and a stats 
+        * struct will make up the memory region. 
+        **************************************************************/
+
+       if (table_size == 0)
+               table_size = CACHE_DEFAULT_TABLE_SIZE;
+
+       bytes = (table_size * CACHE_MAX_BUCKETS_PER * sizeof(struct bucket)) \
+               + sizeof(struct stats) + 256;
+
+
+       if ((base = cache_alloc_mm(bytes)) == NULL)
+               return -1;
+
+       if (table_timeout == 0)
+               table_timeout = CACHE_DEFAULT_TIMEOUT;
+
+       if (flags & VERBOSE) {
+               logger(L_DEBUG, L_FUNC, "bucket size: %d bytes",
+                      sizeof(struct bucket));
+               logger(L_DEBUG, L_FUNC, "stats size : %d bytes",
+                      sizeof(struct stats));
+               logger(L_DEBUG, L_FUNC, "timeout    : %d seconds",
+                      table_timeout);
+               logger(L_DEBUG, L_FUNC, "cache table: %d total bytes",
+                      bytes);
+               logger(L_DEBUG, L_FUNC, "cache table: %d slots",
+                      table_size);
+               logger(L_DEBUG, L_FUNC, "cache table: %d buckets",
+                      table_size * CACHE_MAX_BUCKETS_PER);
+       } 
+
+       /**************************************************************
+        * At the top of the region is the magic and stats struct. The
+        * slots follow. Due to locking, the counters in the stats
+        * struct will not be entirely accurate.
+        **************************************************************/
+
+       memset(base, 0, bytes);
+
+       memcpy(base, cache_magic, 64);
+       table_stats = (void *)((char *)base + 64);
+       table_stats->table_size = table_size;
+       table_stats->max_buckets_per = CACHE_MAX_BUCKETS_PER;
+       table_stats->sizeof_bucket = sizeof(struct bucket);
+       table_stats->timeout = table_timeout;
+       table_stats->bytes = bytes;
+
+       table = (void *)((char *)table_stats + 128);
+
+       /**************************************************************
+        * Last, initialize the hash table locking.
+        **************************************************************/
+
+       if (cache_init_lock() != 0)
+               return -1;
+
+       return 0;
+}      
+
+/*************************************************************
+ * Here we'll take some credentials and run them through
+ * the hash table. If we have a valid hit then all is good
+ * return CACHE_OK. If we don't get a hit, write the entry to
+ * the result pointer and expect a later call to
+ * cache_commit() to flush the bucket into the table.
+ **************************************************************/
+int cache_lookup(const char *user, const char *realm, const char *service, const char *password, struct cache_result *result) {
+
+       int                     user_length = 0;
+       int                     realm_length = 0;
+       int                     service_length = 0;
+       int                     hash_offset;
+       unsigned char           pwd_digest[16];
+       MD5_CTX                 md5_context;
+       time_t                  epoch;
+       time_t                  epoch_timeout;
+       struct bucket           *ref_bucket;
+       struct bucket           *low_bucket;
+       struct bucket           *high_bucket;
+       struct bucket           *read_bucket = NULL;
+       char                    userrealmserv[CACHE_MAX_CREDS_LENGTH];
+       static char             *debug = "[login=%s] [service=%s] [realm=%s]: %s";
+
+
+       if (!(flags & CACHE_ENABLED))
+               return CACHE_FAIL;
+
+       memset((void *)result, 0, sizeof(struct cache_result));
+       result->status = CACHE_NO_FLUSH;
+       
+       /**************************************************************
+        * Initial length checks
+        **************************************************************/
+
+       user_length = strlen(user) + 1;
+       realm_length = strlen(realm) + 1;
+       service_length = strlen(service) + 1;
+
+       if ((user_length + realm_length + service_length) > CACHE_MAX_CREDS_LENGTH) {
+               return CACHE_TOO_BIG;
+       }
+
+       /**************************************************************
+        * Any ideas on how not to call time() for every lookup?
+        **************************************************************/
+
+       epoch = time(NULL);
+       epoch_timeout = epoch - table_timeout;
+
+       /**************************************************************
+        * Get the offset into the hash table and the md5 sum of
+        * the password.
+        **************************************************************/
+
+       strlcpy(userrealmserv, user, sizeof(userrealmserv));
+       strlcat(userrealmserv, realm, sizeof(userrealmserv));
+       strlcat(userrealmserv, service, sizeof(userrealmserv));
+
+       hash_offset = cache_pjwhash(userrealmserv);
+
+       _saslauthd_MD5Init(&md5_context);
+       _saslauthd_MD5Update(&md5_context, password, strlen(password));
+       _saslauthd_MD5Final(pwd_digest, &md5_context);
+
+       /**************************************************************
+        * Loop through the bucket chain to try and find a hit.
+        *
+        * low_bucket = bucket at the start of the slot.
+        *
+        * high_bucket = last bucket in the slot.
+        * 
+        * read_bucket = Contains the matched bucket if found. 
+        *               Otherwise is NULL.
+        *
+        * Also, lock the slot first to avoid contention in the 
+        * bucket chain.
+        *
+        **************************************************************/
+
+       table_stats->attempts++;
+
+       if (cache_get_rlock(hash_offset) != 0) {
+               table_stats->misses++;
+               table_stats->lock_failures++;
+               return CACHE_FAIL;
+       }       
+
+       low_bucket = table + (CACHE_MAX_BUCKETS_PER * hash_offset);
+       high_bucket = low_bucket + CACHE_MAX_BUCKETS_PER;
+
+       for (ref_bucket = low_bucket; ref_bucket < high_bucket; ref_bucket++) {
+               if (strcmp(user, ref_bucket->creds + ref_bucket->user_offt) == 0 && \
+                   strcmp (realm, ref_bucket->creds + ref_bucket->realm_offt) == 0 && \
+                   strcmp(service, ref_bucket->creds + ref_bucket->service_offt) == 0) {
+                       read_bucket = ref_bucket;
+                       break;
+               }
+       }
+
+       /**************************************************************
+        * If we have our fish, check the password. If it's good,
+        * release the slot (row) lock and return CACHE_OK. Else,
+        * we'll write the entry to the result pointer. If we have a
+        * read_bucket, then tell cache_commit() to not rescan the 
+        * chain (CACHE_FLUSH). Else, have cache_commit() determine the
+        * best bucket to place the new entry (CACHE_FLUSH_WITH_RESCAN).
+        **************************************************************/
+
+       if (read_bucket != NULL && read_bucket->created > epoch_timeout) {
+
+               if (memcmp(pwd_digest, read_bucket->pwd_digest, 16) == 0) {
+
+                       if (flags & VERBOSE)
+                               logger(L_DEBUG, L_FUNC, debug, user, realm, service, "found with valid passwd");
+
+                       cache_un_lock(hash_offset);
+                       table_stats->hits++;
+                       return CACHE_OK;
+               }
+
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, debug, user, realm, service, "found with invalid passwd, update pending");
+
+               result->status = CACHE_FLUSH;
+
+       } else {
+
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, debug, user, realm, service, "not found, update pending");
+
+               result->status = CACHE_FLUSH_WITH_RESCAN;
+       }
+
+       result->hash_offset = hash_offset;
+       result->read_bucket = read_bucket;
+       
+       result->bucket.user_offt = 0;
+       result->bucket.realm_offt = user_length;
+       result->bucket.service_offt = user_length + realm_length;
+
+       strcpy(result->bucket.creds + result->bucket.user_offt, user);  
+       strcpy(result->bucket.creds + result->bucket.realm_offt, realm);        
+       strcpy(result->bucket.creds + result->bucket.service_offt, service);    
+
+       memcpy(result->bucket.pwd_digest, pwd_digest, 16);
+       result->bucket.created = epoch;
+
+       cache_un_lock(hash_offset);
+       table_stats->misses++;
+       return CACHE_FAIL;
+}
+
+
+/*************************************************************
+ * If it was later determined that the previous failed lookup
+ * is ok, flush the result->bucket out to it's permanent home
+ * in the hash table. 
+ **************************************************************/
+void cache_commit(struct cache_result *result) {
+       struct bucket           *write_bucket;
+       struct bucket           *ref_bucket;
+       struct bucket           *low_bucket;
+       struct bucket           *high_bucket;
+
+       if (!(flags & CACHE_ENABLED))
+               return;
+
+       if (result->status == CACHE_NO_FLUSH)
+               return;
+
+       if (cache_get_wlock(result->hash_offset) != 0) {
+               table_stats->lock_failures++;
+               return;
+       }       
+
+       if (result->status == CACHE_FLUSH) {
+               write_bucket = result->read_bucket;
+       } else {
+               /*********************************************************
+                * CACHE_FLUSH_WITH_RESCAN is the default action to take.
+                * Simply traverse the slot looking for the oldest bucket
+                * and mark it for writing.
+                **********************************************************/
+               low_bucket = table + (CACHE_MAX_BUCKETS_PER * result->hash_offset);
+               high_bucket = low_bucket + CACHE_MAX_BUCKETS_PER;
+               write_bucket = low_bucket;
+
+               for (ref_bucket = low_bucket; ref_bucket < high_bucket; ref_bucket++) {
+                       if (ref_bucket->created < write_bucket->created) 
+                               write_bucket = ref_bucket;
+               }
+       }
+
+       memcpy((void *)write_bucket, (void *)&(result->bucket), sizeof(struct bucket));
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "lookup committed");
+
+       cache_un_lock(result->hash_offset);
+       return;
+}
+
+
+/*************************************************************
+ * Hashing function. Algorithm is an adaptation of Peter
+ * Weinberger's (PJW) generic hashing algorithm, which
+ * is based on Allen Holub's version. 
+ **************************************************************/
+int cache_pjwhash(char *datum ) {
+    const int BITS_IN_int = ( sizeof(int) * CHAR_BIT );
+    const int THREE_QUARTERS = ((int) ((BITS_IN_int * 3) / 4));
+    const int ONE_EIGHTH = ((int) (BITS_IN_int / 8));
+    const int HIGH_BITS = ( ~((unsigned int)(~0) >> ONE_EIGHTH ));
+    
+    unsigned int            hash_value, i;
+    
+    for (hash_value = 0; *datum; ++datum) {
+       hash_value = (hash_value << ONE_EIGHTH) + *datum;
+       if ((i = hash_value & HIGH_BITS) != 0)
+           hash_value = (hash_value ^ (i >> THREE_QUARTERS)) & ~HIGH_BITS;
+    }
+    
+    return (hash_value % table_size);
+}
+
+/*************************************************************
+ * Allow someone to set the hash table size (in kilobytes).
+ * Since the hash table has to be prime, this won't be exact.
+ **************************************************************/
+void cache_set_table_size(const char *size) {
+       unsigned int    kilobytes;
+       unsigned int    bytes;
+       unsigned int    calc_bytes = 0;
+       unsigned int    calc_table_size = 1;
+
+       kilobytes = strtol(size, (char **)NULL, 10);
+
+       if (kilobytes <= 0) {
+               logger(L_ERR, L_FUNC,
+                      "cache size must be positive and non zero");
+               exit(1);
+       }
+
+       bytes = kilobytes * 1024;
+
+       calc_table_size =
+           bytes / (sizeof(struct bucket) * CACHE_MAX_BUCKETS_PER);
+
+       do {
+           calc_table_size = cache_get_next_prime(calc_table_size);
+           calc_bytes = calc_table_size *
+               sizeof(struct bucket) * CACHE_MAX_BUCKETS_PER; 
+       } while (calc_bytes < bytes);
+
+       table_size = calc_table_size;
+
+       return;
+}
+
+
+/*************************************************************
+ * Allow someone to set the table timeout (in seconds)
+ **************************************************************/
+void cache_set_timeout(const char *time) {
+       table_timeout = strtol(time, (char **)NULL, 10);
+
+       if (table_timeout <= 0) {
+               logger(L_ERR, L_FUNC, "cache timeout must be positive");
+               exit(1);
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Find the next closest prime relative to the number given.
+ * This is a variation of an implementation of the 
+ * Sieve of Erastothenes by Frank Pilhofer,
+ * http://www.fpx.de/fp/Software/Sieve.html. 
+ **************************************************************/
+unsigned int cache_get_next_prime(unsigned int number) {
+
+#define TEST(f,x)      (*(f+((x)>>4))&(1<<(((x)&15L)>>1)))
+#define SET(f,x)        *(f+((x)>>4))|=1<<(((x)&15)>>1)
+
+       unsigned char   *feld = NULL;
+       unsigned int    teste = 1;
+       unsigned int    max;
+       unsigned int    mom;
+       unsigned int    alloc;
+
+       max = number + 20000;
+
+       feld = malloc(alloc=(((max-=10000)>>4)+1));
+
+       if (feld == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+
+       memset(feld, 0, alloc);
+
+       while ((teste += 2) < max) {
+               if (!TEST(feld, teste)) {
+                       if (teste > number) {
+                               free(feld);
+                               return teste;
+                       }
+
+                       for (mom=3*teste; mom<max; mom+=teste<<1) SET (feld, mom);
+               }
+       }
+
+       /******************************************************
+        * A prime wasn't found in the maximum search range.
+        * Just return the original number.
+        ******************************************************/
+       
+       free(feld);
+       return number;
+}
+
+
+/*************************************************************
+ * Open the file that we'll mmap in as the shared memory
+ * segment. If something fails, return NULL.
+ **************************************************************/
+void *cache_alloc_mm(unsigned int bytes) {
+       int             file_fd;
+       int             rc;
+       int             chunk_count;
+       char            null_buff[1024];
+       size_t          mm_file_len;
+       
+       mm.bytes = bytes;
+
+       mm_file_len = strlen(run_path) + sizeof(CACHE_MMAP_FILE) + 1;
+       if (!(mm.file =
+            (char *)malloc(mm_file_len))) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               return NULL;
+       }
+
+       strlcpy(mm.file, run_path, mm_file_len);
+       strlcat(mm.file, CACHE_MMAP_FILE, mm_file_len);
+       
+       if ((file_fd =
+            open(mm.file, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) < 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not open mmap file: %s", mm.file);
+               logger(L_ERR, L_FUNC, "open: %s", strerror(rc));
+               return NULL;
+       }
+
+       memset(null_buff, 0, sizeof(null_buff));
+
+       chunk_count = (bytes / sizeof(null_buff)) + 1;
+
+       while (chunk_count > 0) {
+           if (tx_rec(file_fd, null_buff, sizeof(null_buff))
+               != (ssize_t)sizeof(null_buff)) {
+               rc = errno;
+               logger(L_ERR, L_FUNC,
+                      "failed while writing to mmap file: %s",
+                      mm.file);
+               close(file_fd);
+               return NULL;
+           }
+           
+           chunk_count--;
+       }       
+       
+       if ((mm.base = mmap(NULL, bytes, PROT_READ|PROT_WRITE,
+                           MAP_SHARED, file_fd, 0))== (void *)-1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not mmap shared memory segment");
+               logger(L_ERR, L_FUNC, "mmap: %s", strerror(rc));
+               close(file_fd);
+               return NULL;
+       }
+
+       close(file_fd);
+
+       if (flags & VERBOSE) {
+               logger(L_DEBUG, L_FUNC,
+                      "mmaped shared memory segment on file: %s", mm.file);
+       }
+
+       return mm.base;
+}
+
+
+/*************************************************************
+ * When we die we may need to perform some cleanup on the
+ * mmaped region. We assume we're the last process out here.
+ * Otherwise, deleting the file may cause SIGBUS signals to
+ * be generated for other processes.
+ **************************************************************/
+void cache_cleanup_mm(void) {
+       if (mm.base != NULL) {
+               munmap(mm.base, mm.bytes);
+               unlink(mm.file);
+
+               if (flags & VERBOSE) {
+                       logger(L_DEBUG, L_FUNC,
+                              "cache mmap file removed: %s", mm.file);
+               }
+       }
+
+       return;
+}
+
+/*****************************************************************
+ * The following is relative to the fcntl() locking method. Probably
+ * used when the Sys IV SHM Implementation is in effect.
+ ****************************************************************/
+#ifdef CACHE_USE_FCNTL
+
+/*************************************************************
+ * Setup the locking stuff required to implement the fcntl()
+ * style record locking of the hash table. Return 0 if
+ * everything is peachy, otherwise -1.
+ * __FCNTL Impl__
+ **************************************************************/
+int cache_init_lock(void) {
+       int     rc;
+       size_t  flock_file_len;
+
+       flock_file_len = strlen(run_path) + sizeof(CACHE_FLOCK_FILE) + 1;
+       if ((lock.flock_file = (char *)malloc(flock_file_len)) == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               return -1;
+       }
+
+       strlcpy(lock.flock_file, run_path, flock_file_len);
+       strlcat(lock.flock_file, CACHE_FLOCK_FILE, flock_file_len);
+
+       if ((lock.flock_fd = open(lock.flock_file, O_RDWR|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR)) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not open flock file: %s", lock.flock_file);
+               logger(L_ERR, L_FUNC, "open: %s", strerror(rc));
+               return -1;
+       }
+
+       if (flags & VERBOSE) 
+               logger(L_DEBUG, L_FUNC, "flock file opened at %s", lock.flock_file);
+
+       return 0;
+}
+
+
+/*************************************************************
+ * When the processes die we'll need to cleanup/delete
+ * the flock_file. More for correctness than anything.
+ * __FCNTL Impl__
+ **************************************************************/
+void cache_cleanup_lock(void) {
+
+
+       if (lock.flock_file != NULL) {
+               unlink(lock.flock_file);
+
+               if (flags & VERBOSE) 
+                       logger(L_DEBUG, L_FUNC, "flock file removed: %s", lock.flock_file);
+
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Attempt to get a write lock on a slot. Return 0 if 
+ * everything went ok, return -1 if something bad happened.
+ * This function is expected to block.
+ * __FCNTL Impl__
+ **************************************************************/
+int cache_get_wlock(unsigned int slot) {
+       struct flock    lock_st;
+       int             rc;
+
+       lock_st.l_type = F_WRLCK;
+       lock_st.l_start = slot;
+       lock_st.l_whence = SEEK_SET;
+       lock_st.l_len = 1;
+
+       errno = 0;
+
+       do {
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "attempting a write lock on slot: %d", slot);
+
+               rc = fcntl(lock.flock_fd, F_SETLKW, &lock_st);
+       } while (rc != 0 && errno == EINTR);
+
+       if (rc != 0) {  
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not acquire a write lock on slot: %d\n", slot);
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Attempt to get a read lock on a slot. Return 0 if 
+ * everything went ok, return -1 if something bad happened.
+ * This function is expected to block.
+ * __FCNTL Impl__
+ **************************************************************/
+int cache_get_rlock(unsigned int slot) {
+
+       struct flock    lock_st;
+       int             rc;
+
+
+       lock_st.l_type = F_RDLCK;
+       lock_st.l_start = slot;
+       lock_st.l_whence = SEEK_SET;
+       lock_st.l_len = 1;
+
+       errno = 0;
+
+       do {
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "attempting a read lock on slot: %d", slot);
+
+               rc = fcntl(lock.flock_fd, F_SETLKW, &lock_st);
+       } while (rc != 0 && errno == EINTR);
+
+       if (rc != 0) {  
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not acquire a read lock on slot: %d\n", slot);
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Releases a previously acquired lock on a slot.
+ * __FCNTL Impl__
+ **************************************************************/
+int cache_un_lock(unsigned int slot) {
+
+       struct flock    lock_st;
+       int             rc;
+
+
+       lock_st.l_type = F_UNLCK;
+       lock_st.l_start = slot;
+       lock_st.l_whence = SEEK_SET;
+       lock_st.l_len = 1;
+
+       errno = 0;
+
+       do {
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "attempting to release lock on slot: %d", slot);
+
+               rc = fcntl(lock.flock_fd, F_SETLKW, &lock_st);
+       } while (rc != 0 && errno == EINTR);
+
+       if (rc != 0) {  
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not release lock on slot: %d\n", slot);
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+#endif  /* CACHE_USE_FCNTL */
+
+/**********************************************************************
+ * The following is relative to the POSIX threads rwlock method of locking
+ * slots in the hash table. Used when the Doors IPC is in effect, thus
+ * -lpthreads is evident.
+ ***********************************************************************/
+
+#ifdef CACHE_USE_PTHREAD_RWLOCK
+
+/*************************************************************
+ * Initialize a pthread_rwlock_t for every slot (row) in the
+ * hash table. Return 0 if everything went ok, -1 if we bomb.
+ * __RWLock Impl__
+ **************************************************************/
+int cache_init_lock(void) {
+       unsigned int            x;
+       pthread_rwlock_t        *rwlock;
+
+       if (!(lock.rwlock =
+            (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t) * table_size))) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               return -1;
+       }
+
+       for (x = 0; x < table_size; x++) {
+               rwlock = lock.rwlock + x;
+
+               if (pthread_rwlock_init(rwlock, NULL) != 0) {
+                       logger(L_ERR, L_FUNC, "failed to initialize lock %d", x);
+                       return -1;
+               }
+       }
+
+       if (flags & VERBOSE) 
+               logger(L_DEBUG, L_FUNC, "%d rwlocks initialized", table_size);
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Destroy all of the rwlocks, free the buffer.
+ * __RWLock Impl__
+ **************************************************************/
+void cache_cleanup_lock(void) {
+    unsigned int x;
+    pthread_rwlock_t   *rwlock;
+
+    if(!lock.rwlock) return;
+    
+    for(x=0; x<table_size; x++) {
+       rwlock = lock.rwlock + x;
+       pthread_rwlock_destroy(rwlock);
+    }
+    
+    free(lock.rwlock);
+
+    return;
+}
+
+
+/*************************************************************
+ * Attempt to get a write lock on a slot. Return 0 if 
+ * everything went ok, return -1 if something bad happened.
+ * This function is expected to block the current thread.
+ * __RWLock Impl__
+**************************************************************/
+int cache_get_wlock(unsigned int slot) {
+
+       int             rc = 0;
+
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "attempting a write lock on slot: %d", slot);
+
+       rc = pthread_rwlock_wrlock(lock.rwlock + slot);
+
+       if (rc != 0) {  
+               logger(L_ERR, L_FUNC, "could not acquire a write lock on slot: %d\n", slot);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Attempt to get a read lock on a slot. Return 0 if 
+ * everything went ok, return -1 if something bad happened.
+ * This function is expected to block the current thread.
+ * __RWLock Impl__
+ **************************************************************/
+int cache_get_rlock(unsigned int slot) {
+
+       int             rc = 0;
+
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "attempting a read lock on slot: %d", slot);
+
+       rc = pthread_rwlock_rdlock(lock.rwlock + slot);
+
+       if (rc != 0) {  
+               logger(L_ERR, L_FUNC, "could not acquire a read lock on slot: %d\n", slot);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Releases a previously acquired lock on a slot.
+ * __RWLock Impl__
+ **************************************************************/
+int cache_un_lock(unsigned int slot) {
+
+       int             rc = 0;
+
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "attempting to release lock on slot: %d", slot);
+
+       rc = pthread_rwlock_unlock(lock.rwlock + slot);
+
+       if (rc != 0) {  
+               logger(L_ERR, L_FUNC, "could not release lock on slot: %d\n", slot);
+               return -1;
+       }
+
+       return 0;
+}
+
+
+#endif  /* CACHE_USE_PTHREAD_RWLOCK */
+/***************************************************************************************/
+/***************************************************************************************/
diff --git a/saslauthd/cache.h b/saslauthd/cache.h
new file mode 100644 (file)
index 0000000..6a5707e
--- /dev/null
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * *****************************************************************************
+ * *
+ * * cache.h
+ * *
+ * * Description:  Header file for cache.c
+ * *               
+ * *
+ * * Copyright (C) 2003 Jeremy Rumpf
+ * *
+ * * 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.
+ * *
+ * * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * * THE POSSIBILITY OF SUCH DAMAGE
+ * *
+ * * Jeremy Rumpf
+ * * jrumpf@heavyload.net
+ * *
+ * ******************************************************************************
+ ********************************************************************************/
+
+#ifndef _CACHE_H
+#define _CACHE_H
+
+
+/* constant includes */
+#include "saslauthd.h"
+
+
+/****************************************************************
+* * Plug in some autoconf magic to determine what implementation
+* * to use for the table slot (row) locking.
+****************************************************************/
+#ifdef USE_DOORS
+# define CACHE_USE_PTHREAD_RWLOCK
+#else
+# define CACHE_USE_FCNTL
+#endif
+
+
+
+/************************************************/
+#ifdef CACHE_USE_FCNTL
+       /* FCNTL Impl */
+
+struct lock_ctl {
+       char                    *flock_file;
+       int                     flock_fd;
+};
+
+#endif  /* CACHE_USE_FCNTL */
+/************************************************/
+
+
+
+/************************************************/
+#ifdef CACHE_USE_PTHREAD_RWLOCK
+       /* RWLock Impl */
+
+#include <pthread.h>
+
+struct lock_ctl {
+       pthread_rwlock_t        *rwlock;
+};
+
+#endif  /* CACHE_USE_PTHREAD_RWLOCK */
+/************************************************/
+
+
+
+/* defaults */
+#define CACHE_DEFAULT_TIMEOUT          28800
+#define CACHE_DEFAULT_TABLE_SIZE       1711
+#define CACHE_DEFAULT_FLAGS            0
+#define CACHE_MAX_BUCKETS_PER          6
+#define CACHE_MMAP_FILE                        "/cache.mmap"  /* don't forget the "/" */
+#define CACHE_FLOCK_FILE               "/cache.flock" /* don't forget the "/" */
+
+
+
+/* If debugging uncomment this for always verbose  */
+/* #define CACHE_DEFAULT_FLAGS         CACHE_VERBOSE */
+
+
+
+/* max length for cached credential values */
+#define CACHE_MAX_CREDS_LENGTH         60
+
+
+
+/* magic values (must be less than 63 chars!) */
+#define CACHE_CACHE_MAGIC              "SASLAUTHD_CACHE_MAGIC"
+
+
+
+/* return values */
+#define CACHE_OK                       0
+#define CACHE_FAIL                     1
+#define CACHE_TOO_BIG                  2       
+
+
+
+/* cache_result status values */
+#define CACHE_NO_FLUSH                 0
+#define CACHE_FLUSH                    1
+#define CACHE_FLUSH_WITH_RESCAN                2       
+
+
+
+/* declarations */
+struct bucket {
+        char                   creds[CACHE_MAX_CREDS_LENGTH];
+        unsigned int           user_offt;
+        unsigned int           realm_offt;
+        unsigned int           service_offt;
+        unsigned char          pwd_digest[16];
+        time_t                 created;
+};
+
+struct stats {
+        volatile unsigned int   hits;
+        volatile unsigned int   misses;
+        volatile unsigned int   lock_failures;
+        volatile unsigned int   attempts;
+        unsigned int            table_size;
+        unsigned int            max_buckets_per;
+        unsigned int            sizeof_bucket;
+        unsigned int            bytes;
+        unsigned int            timeout;
+};
+
+struct mm_ctl {
+       void                    *base;
+       unsigned int            bytes;
+       char                    *file;
+};
+
+struct cache_result {
+       struct bucket           bucket;
+       struct bucket           *read_bucket;
+       unsigned int            hash_offset;
+       int                     status;
+};
+
+
+/* cache.c */
+extern int cache_init(void);
+extern int cache_lookup(const char *, const char *, const char *, const char *, struct cache_result *);
+extern void cache_commit(struct cache_result *);
+extern int cache_pjwhash(char *);
+extern void cache_set_table_size(const char *);
+extern void cache_set_timeout(const char *);
+extern unsigned int cache_get_next_prime(unsigned int);
+extern void *cache_alloc_mm(unsigned int);
+extern void cache_cleanup_mm(void);
+extern void cache_cleanup_lock(void);
+extern int cache_init_lock(void);
+extern int cache_get_wlock(unsigned int);
+extern int cache_get_rlock(unsigned int);
+extern int cache_un_lock(unsigned int);
+
+#endif  /* _CACHE_H */
+
diff --git a/saslauthd/cfile.c b/saslauthd/cfile.c
new file mode 100644 (file)
index 0000000..6b72b0a
--- /dev/null
@@ -0,0 +1,212 @@
+/* Simple Config file API
+ * Dave Eckhardt
+ * Rob Siemborski
+ * Tim Martin (originally in Cyrus distribution)
+ * $Id: cfile.c,v 1.1 2005/01/19 00:11:41 shadow Exp $
+ */
+/* 
+ * Copyright (c) 2001 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.
+ */
+
+/* cfile_read() has a clumsy error reporting path
+ * so that it doesn't depend on any particular package's
+ * return code space.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "cfile.h"
+
+struct cf_keyval {
+    char *key;
+    char *value;
+};
+
+struct cfile {
+    struct cf_keyval *kvlist;
+    int n_kv;
+};
+
+#define CONFIGLISTGROWSIZE 100
+#define BIG_ENOUGH 4096
+
+cfile cfile_read(const char *filename, char *complaint, int complaint_len)
+{
+    FILE *infile;
+    int lineno = 0;
+    int alloced = 0;
+    char buf[BIG_ENOUGH];
+    char *p, *key;
+    int result;
+    struct cfile *cf;
+
+       if (complaint)
+      complaint[0] = '\0';
+
+    if (!(cf = malloc(sizeof (*cf)))) {
+      /* then strdup() will probably fail, sigh */
+      if (complaint)
+        snprintf(complaint, complaint_len, "cfile_read: no memory");
+      return 0;
+    }
+
+    cf->n_kv = 0;
+    cf->kvlist = 0;
+
+    infile = fopen(filename, "r");
+    if (!infile) {
+      if (complaint)
+        snprintf(complaint, complaint_len, "cfile_read: cannot open %s", filename);
+      cfile_free(cf);
+      return 0;
+    }
+    
+    while (fgets(buf, sizeof(buf), infile)) {
+       lineno++;
+
+       if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0';
+       for (p = buf; *p && isspace((int) *p); p++);
+       if (!*p || *p == '#') continue;
+
+       key = p;
+       while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
+           if (isupper((int) *p)) *p = tolower(*p);
+           p++;
+       }
+       if (*p != ':') {
+         if (complaint)
+           snprintf(complaint, complaint_len, "%s: line %d: no colon separator", filename, lineno);
+         cfile_free(cf);
+         return 0;
+       }
+       *p++ = '\0';
+
+       while (*p && isspace((int) *p)) p++;
+       
+       if (!*p) {
+         if (complaint)
+           snprintf(complaint, complaint_len, "%s: line %d: keyword %s: no value", filename, lineno, key);
+         cfile_free(cf);
+         return 0;
+       }
+
+       if (cf->n_kv == alloced) {
+           alloced += CONFIGLISTGROWSIZE;
+           cf->kvlist=realloc((char *)cf->kvlist, 
+                                   alloced * sizeof(struct cf_keyval));
+           if (cf->kvlist==NULL) {
+             if (complaint)
+               snprintf(complaint, complaint_len, "cfile_read: no memory");
+             cfile_free(cf);
+             return 0;
+           }
+       }
+
+       if (!(cf->kvlist[cf->n_kv].key = strdup(key)) ||
+           !(cf->kvlist[cf->n_kv].value = strdup(p))) {
+             if (complaint)
+               snprintf(complaint, complaint_len, "cfile_read: no memory");
+             cf->n_kv++; /* maybe one strdup() worked */
+             cfile_free(cf);
+             return 0;
+       }
+
+       cf->n_kv++;
+    }
+    fclose(infile);
+
+    return cf;
+}
+
+const char *cfile_getstring(cfile cf,const char *key,const char *def)
+{
+    int opt;
+
+    for (opt = 0; opt < cf->n_kv; opt++) {
+       if (*key == cf->kvlist[opt].key[0] &&
+           !strcmp(key, cf->kvlist[opt].key))
+         return cf->kvlist[opt].value;
+    }
+    return def;
+}
+
+int cfile_getint(cfile cf,const char *key,int def)
+{
+    const char *val = cfile_getstring(cf, key, (char *)0);
+
+    if (!val) return def;
+    if (!isdigit((int) *val) && (*val != '-' || !isdigit((int) val[1]))) return def;
+    return atoi(val);
+}
+
+int cfile_getswitch(cfile cf,const char *key,int def)
+{
+    const char *val = cfile_getstring(cf, key, (char *)0);
+
+    if (!val) return def;
+
+    if (*val == '0' || *val == 'n' ||
+       (*val == 'o' && val[1] == 'f') || *val == 'f') {
+       return 0;
+    }
+    else if (*val == '1' || *val == 'y' ||
+            (*val == 'o' && val[1] == 'n') || *val == 't') {
+       return 1;
+    }
+    return def;
+}
+
+void cfile_free(cfile cf)
+{
+    int opt;
+
+    if (cf->kvlist) {
+       for (opt = 0; opt < cf->n_kv; opt++) {
+           if (cf->kvlist[opt].key)
+             free(cf->kvlist[opt].key);
+           if (cf->kvlist[opt].value)
+             free(cf->kvlist[opt].value);
+       }
+       free(cf->kvlist);
+    }
+    free(cf);
+}
diff --git a/saslauthd/cfile.h b/saslauthd/cfile.h
new file mode 100644 (file)
index 0000000..29cab98
--- /dev/null
@@ -0,0 +1,55 @@
+/* Simple Config file API
+ * Dave Eckhardt
+ * Rob Siemborski
+ * Tim Martin (originally in Cyrus distribution)
+ * $Id: cfile.h,v 1.1 2005/01/19 00:11:42 shadow Exp $
+ */
+/* 
+ * Copyright (c) 2001 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.
+ */
+
+struct cfile; /* cc can type check, nobody can look inside */
+
+typedef struct cfile *cfile;
+
+cfile cfile_read(const char *filename, char *complaint, int complaint_len);
+const char *cfile_getstring(cfile cf,const char *key,const char *def);
+int cfile_getint(cfile cf,const char *key,int def);
+int cfile_getswitch(cfile cf,const char *key,int def);
+void cfile_free(cfile cf);
diff --git a/saslauthd/config/config.guess b/saslauthd/config/config.guess
new file mode 100755 (executable)
index 0000000..6012b39
--- /dev/null
@@ -0,0 +1,1298 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-07-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int dummy(){}" > $dummy.c ;
+       for c in cc gcc c89 ; do
+         ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+         if test $? = 0 ; then
+            CC_FOR_BUILD="$c"; break ;
+         fi ;
+       done ;
+       rm -f $dummy.c $dummy.o $dummy.rel ;
+       if test x"$CC_FOR_BUILD" = x ; then
+         CC_FOR_BUILD=no_compiler_found ;
+       fi
+       ;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+       # Netbsd (nbsd) targets should (where applicable) match one or
+       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+       # switched to ELF, *-*-netbsd* would select the old
+       # object file format.  This provides both forward
+       # compatibility and a consistent mechanism for selecting the
+       # object file format.
+       # Determine the machine/vendor (is the vendor relevant).
+       case "${UNAME_MACHINE}" in
+           amiga) machine=m68k-unknown ;;
+           arm32) machine=arm-unknown ;;
+           atari*) machine=m68k-atari ;;
+           sun3*) machine=m68k-sun ;;
+           mac68k) machine=m68k-apple ;;
+           macppc) machine=powerpc-apple ;;
+           hp3[0-9][05]) machine=m68k-hp ;;
+           ibmrt|romp-ibm) machine=romp-ibm ;;
+           *) machine=${UNAME_MACHINE}-unknown ;;
+       esac
+       # The Operating System including object format, if it has switched
+       # to ELF recently, or will in the future.
+       case "${UNAME_MACHINE}" in
+           i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+               eval $set_cc_for_build
+               if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+                       | grep __ELF__ >/dev/null
+               then
+                   # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+                   # Return netbsd for either.  FIX?
+                   os=netbsd
+               else
+                   os=netbsdelf
+               fi
+               ;;
+           *)
+               os=netbsd
+               ;;
+       esac
+       # The OS release
+       release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+       # contains redundant information, the shorter form:
+       # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+       echo "${machine}-${os}${release}"
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >$dummy.s
+       .data
+\$Lformat:
+       .byte 37,100,45,37,120,10,0     # "%d-%x\n"
+
+       .text
+       .globl main
+       .align 4
+       .ent main
+main:
+       .frame \$30,16,\$26,0
+       ldgp \$29,0(\$27)
+       .prologue 1
+       .long 0x47e03d80 # implver \$0
+       lda \$2,-1
+       .long 0x47e20c21 # amask \$2,\$1
+       lda \$16,\$Lformat
+       mov \$0,\$17
+       not \$1,\$18
+       jsr \$26,printf
+       ldgp \$29,0(\$26)
+       mov 0,\$16
+       jsr \$26,exit
+       .end main
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               case `./$dummy` in
+                       0-0)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       1-0)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       1-1)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       1-101)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       2-303)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       2-307)
+                               UNAME_MACHINE="alphaev67"
+                               ;;
+               esac
+       fi
+       rm -f $dummy.s $dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # Should we change UNAME_MACHINE based on the output of uname instead
+       # of the specific Alpha model?
+       echo alpha-pc-interix
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy \
+         && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+       if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+       then
+           if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+              [ ${TARGET_BINARY_INTERFACE}x = x ]
+           then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+           else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+           fi
+       else
+           echo i586-dg-dgux${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    ia64:AIX:*:*)
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >$dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               eval $set_cc_for_build
+               $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+               rm -f $dummy.c $dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:[45])
+       IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+       if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/[678][0-9][0-9])
+              case "${HPUX_REV}" in
+                11.[0-9][0-9])
+                  if [ -x /usr/bin/getconf ]; then
+                    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+                        esac ;;
+                    esac
+                  fi ;;
+              esac
+              if [ "${HP_ARCH}" = "" ]; then
+              sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+               {
+               case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+               case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+               case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+                   switch (bits)
+                       {
+                       case 64: puts ("hppa2.0w"); break;
+                       case 32: puts ("hppa2.0n"); break;
+                       default: puts ("hppa2.0"); break;
+                       } break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+                   puts ("hppa2.0"); break;
+              #endif
+               default: puts ("hppa1.0"); break;
+               }
+                  exit (0);
+              }
+EOF
+       eval $set_cc_for_build
+       (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+       if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+       rm -f $dummy.c $dummy
+       fi ;;
+       esac
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >$dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    hppa*:OpenBSD:*:*)
+       echo hppa-unknown-openbsd
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+             -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3D:*:*:*)
+       echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+       FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+       # How do we know it's Interix rather than the generic POSIX subsystem?
+       # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+       # UNAME_MACHINE based on the output of uname instead of i386?
+       echo i386-pc-interix
+       exit 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    mips:Linux:*:*)
+       case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+         big)    echo mips-unknown-linux-gnu && exit 0 ;;
+         little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+       esac
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    alpha:Linux:*:*)
+       case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+         EV5)   UNAME_MACHINE=alphaev5 ;;
+         EV56)  UNAME_MACHINE=alphaev56 ;;
+         PCA56) UNAME_MACHINE=alphapca56 ;;
+         PCA57) UNAME_MACHINE=alphapca56 ;;
+         EV6)   UNAME_MACHINE=alphaev6 ;;
+         EV67)  UNAME_MACHINE=alphaev67 ;;
+         EV68*) UNAME_MACHINE=alphaev67 ;;
+        esac
+       objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+       # Look for CPU level
+       case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+         PA7*) echo hppa1.1-unknown-linux-gnu ;;
+         PA8*) echo hppa2.0-unknown-linux-gnu ;;
+         *)    echo hppa-unknown-linux-gnu ;;
+       esac
+       exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    i*86:Linux:*:*)
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us. cd to the root directory to prevent
+       # problems with other programs or directories called `ld' in the path.
+       ld_supported_targets=`cd /; ld --help 2>&1 \
+                        | sed -ne '/supported targets:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported targets: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_targets" in
+         elf32-i386)
+               TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+               ;;
+         a.out-i386-linux)
+               echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+               exit 0 ;;               
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # Either a pre-BFD a.out linker (linux-gnuoldld) or
+               # one that does not give us useful --help.
+               echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+               exit 0 ;;
+       esac
+       # Determine whether the default compiler is a.out or elf
+       cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+       int main (int argc, char *argv[]) {
+#else
+       int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-pc-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+       eval $set_cc_for_build
+       $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+       rm -f $dummy.c $dummy
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    i*86:DYNIX/ptx:4*:*)
+       # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+       # earlier versions are messed up and put the nodename in both
+       # sysname and nodename.
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+       UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+       fi
+       exit 0 ;;
+    i*86:*:5:[78]*)
+       case `/bin/uname -X | grep "^Machine"` in
+           *486*)           UNAME_MACHINE=i486 ;;
+           *Pentium)        UNAME_MACHINE=i586 ;;
+           *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+       esac
+       echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+       exit 0 ;;
+    i*86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+                       && UNAME_MACHINE=i686
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    pc:*:*:*)
+       # Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       echo `uname -p`-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+       if test "${UNAME_MACHINE}" = "x86pc"; then
+               UNAME_MACHINE=pc
+       fi
+       echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+       exit 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[KW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *:Plan9:*:*)
+       # "uname -m" is not consistent, so use $cputype instead. 386
+       # is converted to i386 for consistency with other x86
+       # operating systems.
+       if test "$cputype" = "386"; then
+           UNAME_MACHINE=i386
+       else
+           UNAME_MACHINE="$cputype"
+       fi
+       echo ${UNAME_MACHINE}-unknown-plan9
+       exit 0 ;;
+    i*86:OS/2:*:*)
+       # If we were able to find `uname', then EMX Unix compatibility
+       # is probably installed.
+       echo ${UNAME_MACHINE}-pc-os2-emx
+       exit 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+eval $set_cc_for_build
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/saslauthd/config/config.sub b/saslauthd/config/config.sub
new file mode 100755 (executable)
index 0000000..578b302
--- /dev/null
@@ -0,0 +1,1375 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+#   Free Software Foundation, Inc.
+
+timestamp='2001-06-08'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )        # Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple | -axis)
+               os=
+               basic_machine=$1
+               ;;
+       -sim | -cisco | -oki | -wec | -winbond)
+               os=
+               basic_machine=$1
+               ;;
+       -scout)
+               ;;
+       -wrs)
+               os=-vxworks
+               basic_machine=$1
+               ;;
+       -chorusos*)
+               os=-chorusos
+               basic_machine=$1
+               ;;
+       -chorusrdb)
+               os=-chorusrdb
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=-sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -udk*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+       -mint | -mint[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
+               | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
+               | pyramid | mn10200 | mn10300 | tron | a29k \
+               | 580 | i960 | h8300 \
+               | x86 | ppcbe | mipsbe | mipsle | shbe | shle \
+               | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+               | hppa64 \
+               | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
+               | alphaev6[78] \
+               | we32k | ns16k | clipper | i370 | sh | sh[34] \
+               | powerpc | powerpcle \
+               | 1750a | dsp16xx | pdp10 | pdp11 \
+               | mips16 | mips64 | mipsel | mips64el \
+               | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+               | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+               | mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
+               | sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
+               | v850 | c4x \
+               | thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
+               | pj | pjl | h8500 | z8k)
+               basic_machine=$basic_machine-unknown
+               ;;
+       m6811 | m68hc11 | m6812 | m68hc12)
+               # Motorola 68HC11/12.
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
+       m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+               ;;
+
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i*86 | x86_64)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       # FIXME: clean up the formatting here.
+       vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
+             | arm-*  | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+             | xmp-* | ymp-* \
+             | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
+             | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
+             | hppa2.0n-* | hppa64-* \
+             | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
+             | alphaev6[78]-* \
+             | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+             | clipper-* | orion-* \
+             | sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
+             | powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
+             | mips16-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-* \
+             | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+             | mipstx39-* | mipstx39el-* | mcore-* \
+             | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
+             | [cjt]90-* \
+             | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+             | thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
+             | bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       386bsd)
+               basic_machine=i386-unknown
+               os=-bsd
+               ;;
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       a29khif)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       adobe68k)
+               basic_machine=m68010-adobe
+               os=-scout
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-unknown
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-unknown
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-unknown
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       apollo68bsd)
+               basic_machine=m68k-apollo
+               os=-bsd
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [cjt]90)
+               basic_machine=${basic_machine}-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       es1800 | OSE68k | ose68k | ose | OSE)
+               basic_machine=m68k-ericsson
+               os=-ose
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       go32)
+               basic_machine=i386-pc
+               os=-go32
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       h8300xray)
+               basic_machine=h8300-hitachi
+               os=-xray
+               ;;
+       h8500hms)
+               basic_machine=h8500-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp3k9[0-9][0-9] | hp9[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k6[0-9][0-9] | hp6[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hp9k7[0-79][0-9] | hp7[0-79][0-9])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k78[0-9] | hp78[0-9])
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+               # FIXME: really hppa2.0-hp
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][13679] | hp8[0-9][13679])
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       hppaosf)
+               basic_machine=hppa1.1-hp
+               os=-osf
+               ;;
+       hppro)
+               basic_machine=hppa1.1-hp
+               os=-proelf
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i*86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i*86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i*86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i*86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       i386mach)
+               basic_machine=i386-mach
+               os=-mach
+               ;;
+       i386-vsta | vsta)
+               basic_machine=i386-unknown
+               os=-vsta
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       mingw32)
+               basic_machine=i386-pc
+               os=-mingw32
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+               basic_machine=m68k-atari
+               os=-mint
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       mvs)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       netbsd386)
+               basic_machine=i386-unknown
+               os=-netbsd
+               ;;
+       netwinder)
+               basic_machine=armv4l-rebel
+               os=-linux
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       necv70)
+               basic_machine=v70-nec
+               os=-sysv
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       mon960)
+               basic_machine=i960-intel
+               os=-mon960
+               ;;
+       nonstopux)
+               basic_machine=mips-compaq
+               os=-nonstopux
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       OSE68000 | ose68000)
+               basic_machine=m68000-ericsson
+               os=-ose
+               ;;
+       os68k)
+               basic_machine=m68k-none
+               os=-os68k
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | k6 | nexgen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-pc
+               ;;
+       pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | 6x86-* | athlon-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=power-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       pw32)
+               basic_machine=i586-unknown
+               os=-pw32
+               ;;
+       rom68k)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sa29200)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sparclite-wrs)
+               basic_machine=sparclite-wrs
+               os=-vxworks
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       st2000)
+               basic_machine=m68k-tandem
+               ;;
+       stratus)
+               basic_machine=i860-stratus
+               os=-sysv4
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       sv1)
+               basic_machine=sv1-cray
+               os=-unicos
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       t3e)
+               basic_machine=t3e-cray
+               os=-unicos
+               ;;
+       tic54x | c54x*)
+               basic_machine=tic54x-unknown
+               os=-coff
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       v810 | necv810)
+               basic_machine=v810-nec
+               os=-none
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       w65*)
+               basic_machine=w65-wdc
+               os=-none
+               ;;
+       w89k-*)
+               basic_machine=hppa1.1-winbond
+               os=-proelf
+               ;;
+       windows32)
+               basic_machine=i386-pc
+               os=-windows32-msvcrt
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       z8k-*-coff)
+               basic_machine=z8k-unknown
+               os=-sim
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       w89k)
+               basic_machine=hppa1.1-winbond
+               ;;
+       op50n)
+               basic_machine=hppa1.1-oki
+               ;;
+       op60c)
+               basic_machine=hppa1.1-oki
+               ;;
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp10)
+               # there are many clones, so DEC is not a safe bet
+               basic_machine=pdp10-unknown
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sh3 | sh4)
+               basic_machine=sh-unknown
+               ;;
+       sparc | sparcv9 | sparcv9b)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       mac | mpw | mac-mpw)
+               basic_machine=m68k-apple
+               ;;
+       pmac | pmac-mpw)
+               basic_machine=powerpc-apple
+               ;;
+       c4x*)
+               basic_machine=c4x-none
+               os=-coff
+               ;;
+       *-unknown)
+               # Make sure to match an already-canonicalized machine name.
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -chorusos* | -chorusrdb* \
+             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+             | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+             | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+             | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -qnx*)
+               case $basic_machine in
+                   x86-* | i*86-*)
+                       ;;
+                   *)
+                       os=-nto$os
+                       ;;
+               esac
+               ;;
+       -nto*)
+               os=-nto-qnx
+               ;;
+       -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+             | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -opened*)
+               os=-openedition
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -386bsd)
+               os=-bsd
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       -nsk*)
+               os=-nsk
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -ose*)
+               os=-ose
+               ;;
+       -es1800*)
+               os=-ose
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+        -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+               os=-mint
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-rebel)
+               os=-linux
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+       pdp10-*)
+               os=-tops20
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       m68*-cisco)
+               os=-aout
+               ;;
+       mips*-cisco)
+               os=-elf
+               ;;
+       mips*-*)
+               os=-elf
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-be)
+               os=-beos
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-wec)
+               os=-proelf
+               ;;
+       *-winbond)
+               os=-proelf
+               ;;
+       *-oki)
+               os=-proelf
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f30[01]-fujitsu | f700-fujitsu)
+               os=-uxpv
+               ;;
+       *-rom68k)
+               os=-coff
+               ;;
+       *-*bug)
+               os=-coff
+               ;;
+       *-apple)
+               os=-macos
+               ;;
+       *-atari*)
+               os=-mint
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -beos*)
+                               vendor=be
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -mpeix*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs* | -opened*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+                       -hms*)
+                               vendor=hitachi
+                               ;;
+                       -mpw* | -macos*)
+                               vendor=apple
+                               ;;
+                       -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+                               vendor=atari
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/saslauthd/config/depcomp b/saslauthd/config/depcomp
new file mode 100755 (executable)
index 0000000..807b991
--- /dev/null
@@ -0,0 +1,423 @@
+#! /bin/sh
+
+# depcomp - compile a program generating dependencies as side-effects
+# Copyright 1999, 2000 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+# `libtool' can also be set to `yes' or `no'.
+
+if test -z "$depfile"; then
+   base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
+   dir=`echo "$object" | sed 's,/.*$,/,'`
+   if test "$dir" = "$object"; then
+      dir=
+   fi
+   # FIXME: should be _deps on DOS.
+   depfile="$dir.deps/$base"
+fi
+
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  This file always lives in the current directory.
+  # Also, the AIX compiler puts `$object:' at the start of each line;
+  # $object doesn't have directory information.
+  stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  outname="$stripped.o"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   else
+      tmpdepfile="$tmpdepfile2"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a space and a tab in the [].
+      sed -e 's,^.*\.[a-z]*:[  ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.  We will use -o /dev/null later,
+  # however we can't do the remplacement now because
+  # `-o $object' might simply not be used
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  "$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[      ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    -*)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the proprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+       set fnord "$@"
+       shift
+       shift
+       ;;
+    *)
+       set fnord "$@" "$arg"
+       shift
+       shift
+       ;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::   \1 \\:p' >> "$depfile"
+  echo "       " >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
diff --git a/saslauthd/config/install-sh b/saslauthd/config/install-sh
new file mode 100755 (executable)
index 0000000..36f96f3
--- /dev/null
@@ -0,0 +1,276 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+       -c) instcmd=$cpprog
+           shift
+           continue;;
+
+       -d) dir_arg=true
+           shift
+           continue;;
+
+       -m) chmodcmd="$chmodprog $2"
+           shift
+           shift
+           continue;;
+
+       -o) chowncmd="$chownprog $2"
+           shift
+           shift
+           continue;;
+
+       -g) chgrpcmd="$chgrpprog $2"
+           shift
+           shift
+           continue;;
+
+       -s) stripcmd=$stripprog
+           shift
+           continue;;
+
+       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+           shift
+           continue;;
+
+       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+           shift
+           continue;;
+
+       *)  if [ x"$src" = x ]
+           then
+               src=$1
+           else
+               # this colon is to work around a 386BSD /bin/sh bug
+               :
+               dst=$1
+           fi
+           shift
+           continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+       echo "$0: no input file specified" >&2
+       exit 1
+else
+       :
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+
+       if [ -d "$dst" ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=$mkdirprog
+       fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+       if [ -f "$src" ] || [ -d "$src" ]
+       then
+               :
+       else
+               echo "$0: $src does not exist" >&2
+               exit 1
+       fi
+
+       if [ x"$dst" = x ]
+       then
+               echo "$0: no destination specified" >&2
+               exit 1
+       else
+               :
+       fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+       if [ -d "$dst" ]
+       then
+               dst=$dst/`basename "$src"`
+       else
+               :
+       fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+       '
+IFS="${IFS-$defaultIFS}"
+
+oIFS=$IFS
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS=$oIFS
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+       pathcomp=$pathcomp$1
+       shift
+
+       if [ ! -d "$pathcomp" ] ;
+        then
+               $mkdirprog "$pathcomp"
+       else
+               :
+       fi
+
+       pathcomp=$pathcomp/
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd "$dst" &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+       if [ x"$transformarg" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               dstfile=`basename "$dst" $transformbasename |
+                       sed $transformarg`$transformbasename
+       fi
+
+# don't allow the sed command to completely eliminate the filename
+
+       if [ x"$dstfile" = x ]
+       then
+               dstfile=`basename "$dst"`
+       else
+               :
+       fi
+
+# Make a couple of temp file names in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+       rmtmp=$dstdir/#rm.$$#
+
+# Trap to clean up temp files at exit.
+
+       trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
+       trap '(exit $?); exit' 1 2 13 15
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd "$src" "$dsttmp" &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
+
+# Now remove or move aside any old file at destination location.  We try this
+# two ways since rm can't unlink itself on some systems and the destination
+# file might be busy for other reasons.  In this case, the final cleanup
+# might fail but the new file should still install successfully.
+
+{
+       if [ -f "$dstdir/$dstfile" ]
+       then
+               $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
+               $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
+               {
+                 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+                 (exit 1); exit
+               }
+       else
+               :
+       fi
+} &&
+
+# Now rename the file to the real destination.
+
+       $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+
+fi &&
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+
+{
+       (exit 0); exit
+}
diff --git a/saslauthd/config/ltconfig b/saslauthd/config/ltconfig
new file mode 100755 (executable)
index 0000000..5b61f70
--- /dev/null
@@ -0,0 +1,3150 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# Find the correct PATH separator.  Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+  UNAME=${UNAME-`uname 2>/dev/null`}
+  case X$UNAME in
+    *-DOS) PATH_SEPARATOR=';' ;;
+    *)     PATH_SEPARATOR=':' ;;
+  esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+  # find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+       echo_test_string="`eval $cmd`" &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+   test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH /usr/ucb; do
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running ltconfig again with it.
+      ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf "%s\n"'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+          test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+  case "$option" in
+  -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    eval "$prev=\$option"
+    prev=
+    continue
+  fi
+
+  case "$option" in
+  --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+    --debug                enable verbose shell tracing
+    --disable-shared       do not build shared libraries
+    --disable-static       do not build static libraries
+    --disable-fast-install do not optimize for fast installation
+    --enable-dlopen        enable dlopen support
+    --enable-win32-dll     enable building dlls on win32 hosts
+    --help                 display this help and exit
+    --no-verify            do not verify that HOST is a valid host type
+-o, --output=FILE          specify the output file [default=$default_ofile]
+    --quiet                same as \`--silent'
+    --silent               do not print informational messages
+    --srcdir=DIR           find \`config.guess' in DIR
+    --version              output version information and exit
+    --with-gcc             assume that the GNU C compiler will be used
+    --with-gnu-ld          assume that the C compiler uses the GNU linker
+    --disable-lock         disable file locking
+    --cache-file=FILE      configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+  exit 0
+  ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --disable-shared) enable_shared=no ;;
+
+  --disable-static) enable_static=no ;;
+
+  --disable-fast-install) enable_fast_install=no ;;
+
+  --enable-dlopen) enable_dlopen=yes ;;
+
+  --enable-win32-dll) enable_win32_dll=yes ;;
+
+  --quiet | --silent) silent=yes ;;
+
+  --srcdir) prev=srcdir ;;
+  --srcdir=*) srcdir="$optarg" ;;
+
+  --no-verify) verify_host=no ;;
+
+  --output | -o) prev=ofile ;;
+  --output=*) ofile="$optarg" ;;
+
+  --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+  --with-gcc) with_gcc=yes ;;
+  --with-gnu-ld) with_gnu_ld=yes ;;
+
+  --disable-lock) need_locks=no ;;
+
+  --cache-file=*) cache_file="$optarg" ;;
+
+  -*)
+    echo "$progname: unrecognized option \`$option'" 1>&2
+    echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    if test -z "$ltmain"; then
+      ltmain="$option"
+    elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+#      if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+#        echo "$progname: warning \`$option' is not a valid host type" 1>&2
+#      fi
+      host="$option"
+    else
+      echo "$progname: too many arguments" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+done
+
+if test -z "$ltmain"; then
+  echo "$progname: you must specify a LTMAIN file" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+if test ! -f "$ltmain"; then
+  echo "$progname: \`$ltmain' does not exist" 1>&2
+  echo "$help" 1>&2
+  exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+  case "$arg" in
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ltconfig_args="$ltconfig_args '$arg'" ;;
+  *) ltconfig_args="$ltconfig_args $arg" ;;
+  esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}"   = Xset; then LANG=C;   export LANG;   fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+  echo "loading cache $cache_file within ltconfig"
+  . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+  # Assume the source directory is the same one as the path to LTMAIN.
+  srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+  test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+  # Check for config.guess and config.sub.
+  ac_aux_dir=
+  for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+    if test -f $ac_dir/config.guess; then
+      ac_aux_dir=$ac_dir
+      break
+    fi
+  done
+  if test -z "$ac_aux_dir"; then
+    echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+  ac_config_guess=$ac_aux_dir/config.guess
+  ac_config_sub=$ac_aux_dir/config.sub
+
+  # Make sure we can run config.sub.
+  if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+  else
+    echo "$progname: cannot run $ac_config_sub" 1>&2
+    echo "$help" 1>&2
+    exit 1
+  fi
+
+  echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+  host_alias=$host
+  case "$host_alias" in
+  "")
+    if host_alias=`$SHELL $ac_config_guess`; then :
+    else
+      echo "$progname: cannot guess host type; you must specify one" 1>&2
+      echo "$help" 1>&2
+      exit 1
+    fi ;;
+  esac
+  host=`$SHELL $ac_config_sub $host_alias`
+  echo "$ac_t$host" 1>&6
+
+  # Make sure the host verified.
+  test -z "$host" && exit 1
+
+elif test -z "$host"; then
+  echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+  echo "$help" 1>&2
+  exit 1
+else
+  host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+  result=no
+
+  echo $ac_n "checking for ranlib... $ac_c" 1>&6
+  IFS="${IFS=  }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+  for dir in $PATH; do
+    test -z "$dir" && dir=.
+    if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+      RANLIB="ranlib"
+      result="ranlib"
+      break
+    fi
+  done
+  IFS="$save_ifs"
+
+  echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+  # If CC is not set, then try to find GCC or a usable CC.
+  if test -z "$CC"; then
+    echo $ac_n "checking for gcc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+       CC="gcc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+  fi
+
+  # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+  if test -z "$CC"; then
+    echo $ac_n "checking for cc... $ac_c" 1>&6
+    IFS="${IFS=        }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    cc_rejected=no
+    for dir in $PATH; do
+      test -z "$dir" && dir=.
+      if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+       if test "$dir/cc" = "/usr/ucb/cc"; then
+         cc_rejected=yes
+         continue
+       fi
+       CC="cc"
+       break
+      fi
+    done
+    IFS="$save_ifs"
+    if test $cc_rejected = yes; then
+      # We found a bogon in the path, so make sure we never use it.
+      set dummy $CC
+      shift
+      if test $# -gt 0; then
+       # We chose a different compiler from the bogus one.
+       # However, it has the same name, so the bogon will be chosen
+       # first if we set CC to just the name; use the full file name.
+       shift
+       set dummy "$dir/cc" "$@"
+       shift
+       CC="$@"
+      fi
+    fi
+
+    if test -n "$CC"; then
+      echo "$ac_t$CC" 1>&6
+    else
+      echo "$ac_t"no 1>&6
+    fi
+
+    if test -z "$CC"; then
+      echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+      exit 1
+    fi
+  fi
+
+  # Now see if the compiler is really GCC.
+  with_gcc=no
+  echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+  echo "$progname:581: checking whether we are using GNU C" >&5
+
+  $rm conftest.c
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+  if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+    with_gcc=yes
+  fi
+  $rm conftest.c
+  echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+  # Append any warnings to the config.log.
+  cat conftest.err 1>&5
+
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  cat conftest.err 1>&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_exeext="no"
+  $rm conftest*
+  echo 'main () { return 0; }' > conftest.c
+  echo "$progname:629: checking for executable suffix" >& 5
+  if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+
+    for ac_file in conftest.*; do
+      case $ac_file in
+      *.c | *.err | *.$objext ) ;;
+      *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+      esac
+    done
+  else
+    cat conftest.err 1>&5
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+  exeext=""
+else
+  exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+  wl='-Wl,'
+  link_static_flag='-static'
+
+  case "$host_os" in
+  beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+    # PIC is the default for these OSes.
+    ;;
+  aix*)
+    # Below there is a dirty hack to force normal static linking with -ldl
+    # The problem is because libdl dynamically linked with both libc and
+    # libC (AIX C++ library), which obviously doesn't included in libraries
+    # list by gcc. This cause undefined symbols with -static flags.
+    # This hack allows C programs to be linked with "-static -ldl", but
+    # we not sure about C++ programs.
+    link_static_flag="$link_static_flag ${wl}-lC"
+    ;;
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+  darwin* | rhapsody*)
+    # PIC is the default on this platform
+    # Common symbols not allowed in MH_DYLIB files
+    pic_flag='-fno-common'
+    ;;
+  amigaos*)
+    # FIXME: we need at least 68020 code to build shared libraries, but
+    # adding the `-m68020' flag to GCC prevents building anything better,
+    # like `-m68040'.
+    pic_flag='-m68020 -resident32 -malways-restore-a4'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec; then
+       pic_flag=-Kconform_pic
+    fi
+    ;;
+  *)
+    pic_flag='-fPIC'
+    ;;
+  esac
+else
+  # PORTME Check for PIC flags for the system compiler.
+  case "$host_os" in
+  aix3* | aix4*)
+    # All AIX code is PIC.
+    link_static_flag='-bnso -bI:/lib/syscalls.exp'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    # Is there a better link_static_flag that works with the bundled CC?
+    wl='-Wl,'
+    link_static_flag="${wl}-a ${wl}archive"
+    pic_flag='+Z'
+    ;;
+
+  irix5* | irix6*)
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    # PIC (with -KPIC) is the default.
+    ;;
+
+  cygwin* | mingw* | os2*)
+    # We can build DLLs from non-PIC.
+    ;;
+
+  osf3* | osf4* | osf5*)
+    # All OSF/1 code is PIC.
+    wl='-Wl,'
+    link_static_flag='-non_shared'
+    ;;
+
+  sco3.2v5*)
+    pic_flag='-Kpic'
+    link_static_flag='-dn'
+    special_shlib_compile_flags='-belf'
+    ;;
+
+  solaris*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  sunos4*)
+    pic_flag='-PIC'
+    link_static_flag='-Bstatic'
+    wl='-Qoption ld '
+    ;;
+
+  sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+    pic_flag='-KPIC'
+    link_static_flag='-Bstatic'
+    wl='-Wl,'
+    ;;
+
+  uts4*)
+    pic_flag='-pic'
+    link_static_flag='-Bstatic'
+    ;;
+  sysv4*MP*)
+    if test -d /usr/nec ;then
+      pic_flag='-Kconform_pic'
+      link_static_flag='-Bstatic'
+    fi
+    ;;
+  *)
+    can_build_shared=no
+    ;;
+  esac
+fi
+
+if test -n "$pic_flag"; then
+  echo "$ac_t$pic_flag" 1>&6
+
+  # Check to make sure the pic_flag actually works.
+  echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS $pic_flag -DPIC"
+  echo "$progname:781: checking if $compiler PIC flag $pic_flag works" >&5
+  if { (eval echo $progname:782: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+    # Append any warnings to the config.log.
+    cat conftest.err 1>&5
+    
+    case "$host_os" in
+    hpux9* | hpux10* | hpux11*)
+      # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+      # create non-PIC objects.  So, if there were any warnings, we assume that
+      # PIC is not supported.
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       can_build_shared=no
+       pic_flag=
+      else
+       echo "$ac_t"yes 1>&6
+       pic_flag=" $pic_flag"
+      fi
+      ;;
+    *)
+      echo "$ac_t"yes 1>&6
+      pic_flag=" $pic_flag"
+      ;;
+    esac
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    can_build_shared=no
+    pic_flag=
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory.  Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:834: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:835: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+  # The compiler can only warn and ignore the option if not recognized
+  # So say no if there are warnings
+    if test -s out/conftest.err; then
+      echo "$ac_t"no 1>&6
+      compiler_c_o=no
+    else
+      echo "$ac_t"yes 1>&6
+      compiler_c_o=yes
+    fi
+else
+  # Append any errors to the config.log.
+  cat out/conftest.err 1>&5
+  compiler_c_o=no
+  echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+  # Check to see if we can write to a .lo
+  echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -c -o conftest.lo"
+  echo "$progname:867: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:868: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_o_lo=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_o_lo=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_o_lo=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+else
+  compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$ac_t$hard_links" 1>&6
+  $rm conftest*
+  if test "$hard_links" = no; then
+    echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+  # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+  echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+  $rm conftest*
+  echo "int some_variable = 0;" > conftest.c
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+  echo "$progname:919: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+  if { (eval echo $progname:920: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+    # The compiler can only warn and ignore the option if not recognized
+    # So say no if there are warnings
+      if test -s conftest.err; then
+       echo "$ac_t"no 1>&6
+       compiler_rtti_exceptions=no
+      else
+       echo "$ac_t"yes 1>&6
+       compiler_rtti_exceptions=yes
+      fi
+  else
+    # Append any errors to the config.log.
+    cat conftest.err 1>&5
+    compiler_rtti_exceptions=no
+    echo "$ac_t"no 1>&6
+  fi
+  CFLAGS="$save_CFLAGS"
+  $rm conftest*
+
+  if test "$compiler_rtti_exceptions" = "yes"; then
+    no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+  else
+    no_builtin_flag=' -fno-builtin'
+  fi
+  
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+  echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+  if echo "$old_CC $old_CFLAGS " | egrep -e "[         ]$special_shlib_compile_flags[  ]" >/dev/null; then :
+  else
+    echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+    can_build_shared=no
+  fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:963: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:964: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  echo "$ac_t$link_static_flag" 1>&6
+else
+  echo "$ac_t"none 1>&6
+  link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+  # Check to see if we can use ln -s, or we need hard links.
+  echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+  $rm conftest.dat
+  if ln -s X conftest.dat 2>/dev/null; then
+    $rm conftest.dat
+    LN_S="ln -s"
+  else
+    LN_S=ln
+  fi
+  if test "$LN_S" = "ln -s"; then
+    echo "$ac_t"yes 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+  ac_prog=ld
+  if test "$with_gcc" = yes; then
+    # Check if gcc -print-prog-name=ld gives a path.
+    echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+    echo "$progname:996: checking for ld used by GCC" >&5
+    ac_prog=`($CC -print-prog-name=ld) 2>&5`
+    case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+    "")
+      # If it fails, then pretend we are not using GCC.
+      ac_prog=ld
+      ;;
+    *)
+      # If it is relative, then search for the first ld in PATH.
+      with_gnu_ld=unknown
+      ;;
+    esac
+  elif test "$with_gnu_ld" = yes; then
+    echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+    echo "$progname:1020: checking for GNU ld" >&5
+  else
+    echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+    echo "$progname:1023: checking for non-GNU ld" >&5
+  fi
+
+  if test -z "$LD"; then
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+       LD="$ac_dir/$ac_prog"
+       # Check to see if the program is GNU ld.  I'd rather use --version,
+       # but apparently some GNU ld's only accept -v.
+       # Break only if it was the GNU/non-GNU ld that we prefer.
+       if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+         test "$with_gnu_ld" != no && break
+       else
+         test "$with_gnu_ld" != yes && break
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+  fi
+
+  if test -n "$LD"; then
+    echo "$ac_t$LD" 1>&6
+  else
+    echo "$ac_t"no 1>&6
+  fi
+
+  if test -z "$LD"; then
+    echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+    exit 1
+  fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced.  Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+  # FIXME: the MSVC++ port hasn't been tested in a loooong time
+  # When not using gcc, we currently assume that we are using
+  # Microsoft Visual C++.
+  if test "$with_gcc" != yes; then
+    with_gnu_ld=no
+  fi
+  ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+  # If archive_cmds runs LD, not CC, wlarc should be empty
+  wlarc='${wl}'
+
+  # See if GNU ld supports shared libraries.
+  case "$host_os" in
+  aix3* | aix4*)
+    # On AIX, the GNU linker is very broken
+    ld_shlibs=no
+    cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+    ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+
+    # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+    # that the semantics of dynamic libraries on AmigaOS, at least up
+    # to version 4, is to share data among multiple programs linked
+    # with the same dynamic library.  Since this doesn't match the
+    # behavior of shared libraries on other platforms, we can use
+    # them.
+    ld_shlibs=no
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  cygwin* | mingw*)
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec='-L$libdir'
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+
+    # Extract the symbol export list from an `--export-all' def file,
+    # then regenerate the def file from the symbol export list, so that
+    # the compiled dll only exports the symbol export list.
+    # Be careful not to strip the DATA tag left by newer dlltools.
+    export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def  $objdir/$soname-ltdll.$objext $libobjs $convenience~
+      sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $objdir/$soname-def > $export_symbols'
+
+    # If DATA tags from a recent dlltool are present, honour them!
+    archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+      _lt_hint=1;
+      cat $export_symbols | while read symbol; do
+        set dummy \$symbol;
+        case \$# in
+          2) echo "    \$2 @ \$_lt_hint ; " >> $objdir/$soname-def;;
+          *) echo "     \$2 @ \$_lt_hint \$3 ; " >> $objdir/$soname-def;;
+        esac;
+       _lt_hint=`expr 1 + \$_lt_hint`;
+      done~
+      test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+      test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+      $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+      $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+      $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+      old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' 
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+      # can we support soname and/or expsyms with a.out? -oliva
+    fi
+    ;;
+
+  solaris* | sysv5*)
+    if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+      ld_shlibs=no
+      cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+    elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;      
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    wlarc=
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+      archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+    else
+      ld_shlibs=no
+    fi
+    ;;
+  esac
+
+  if test "$ld_shlibs" = yes; then
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    case $host_os in
+    cygwin* | mingw*)
+      # dlltool doesn't understand --whole-archive et. al.
+      whole_archive_flag_spec=
+      ;;
+    *)
+      # ancient GNU ld didn't support --whole-archive et. al.
+      if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+        whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+        whole_archive_flag_spec=
+      fi
+      ;;
+    esac
+  fi
+else
+  # PORTME fill in a description of your system's linker (not GNU ld)
+  case "$host_os" in
+  aix3*)
+    allow_undefined_flag=unsupported
+    always_export_symbols=yes
+    archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+    # Note: this linker hardcodes the directories in LIBPATH if there
+    # are no directories specified by -L.
+    hardcode_minus_L=yes
+    if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+      # Neither direct hardcoding nor static linking is supported with a
+      # broken collect2.
+      hardcode_direct=unsupported
+    fi
+    ;;
+
+  aix4*)
+    hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+    hardcode_libdir_separator=':'
+    if test "$with_gcc" = yes; then
+      collect2name=`${CC} -print-prog-name=collect2`
+      if test -f "$collect2name" && \
+        strings "$collect2name" | grep resolve_lib_name >/dev/null
+      then
+       # We have reworked collect2
+       hardcode_direct=yes
+      else
+       # We have old collect2
+       hardcode_direct=unsupported
+       # It fails to find uninstalled libraries when the uninstalled
+       # path is not listed in the libpath.  Setting hardcode_minus_L
+       # to unsupported forces relinking
+       hardcode_minus_L=yes
+       hardcode_libdir_flag_spec='-L$libdir'
+       hardcode_libdir_separator=
+      fi
+      shared_flag='-shared'
+    else
+      shared_flag='${wl}-bM:SRE'
+      hardcode_direct=yes
+    fi
+    allow_undefined_flag=' ${wl}-berok'
+    archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+    archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+    case "$host_os" in aix4.[01]|aix4.[01].*)
+      # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+      always_export_symbols=yes ;;
+    esac
+   ;;
+
+  amigaos*)
+    archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    # see comment about different semantics on the GNU ld section
+    ld_shlibs=no
+    ;;
+
+  cygwin* | mingw*)
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    # hardcode_libdir_flag_spec is actually meaningless, as there is
+    # no search path for DLLs.
+    hardcode_libdir_flag_spec=' '
+    allow_undefined_flag=unsupported
+    # Tell ltmain to make .lib files, not .a files.
+    libext=lib
+    # FIXME: Setting linknames here is a bad hack.
+    archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+    # The linker will automatically build a .lib file if we build a DLL.
+    old_archive_from_new_cmds='true'
+    # FIXME: Should let the user specify the lib program.
+    old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+    fix_srcfile_path='`cygpath -w $srcfile`'
+    ;;
+
+  freebsd1*)
+    ld_shlibs=no
+    ;;
+
+  # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+  # support.  Future versions do this automatically, but an explicit c++rt0.o
+  # does not break anything, and helps significantly (at the cost of a little
+  # extra space).
+  freebsd2.2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+  freebsd2*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+  freebsd*)
+    archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  darwin[15]* | rhapsody*)
+    allow_undefined_flag='-undefined error'
+    archive_cmds='$CC $(test x$module = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts -install_name $rpath/$soname $(test -n "$verstring" -a x$verstring != x0.0 && echo $verstring)'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols $lib'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  # Mac OS X v10.2 uses bash for /bin/sh instead of zsh, and the quoting syntax is incompatible
+  darwin*)
+    allow_undefined_flag='-undefined error'
+    archive_cmds='$CC $(test x$module = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs $linkopts $(test x$module != xyes && echo -install_name $rpath/$soname $tmp_verstring)'
+    # We need to add '_' to the symbols in $export_symbols first
+    #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols $lib'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    whole_archive_flag_spec='-all_load $convenience'
+    ;;
+
+  hpux9* | hpux10* | hpux11*)
+    case "$host_os" in
+    hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+    *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+    esac
+    hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator=:
+    hardcode_direct=yes
+    hardcode_minus_L=yes # Not in the search PATH, but as the default
+                        # location of the library.
+    export_dynamic_flag_spec='${wl}-E'
+    ;;
+
+  irix5* | irix6*)
+    if test "$with_gcc" = yes; then
+      archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'  # a.out
+    else
+      archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts'      # ELF
+    fi
+    hardcode_libdir_flag_spec='${wl}-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  openbsd*)
+    archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_direct=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  os2*)
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_minus_L=yes
+    allow_undefined_flag=unsupported
+    archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+    old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+    ;;
+
+  osf3*)
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+
+  osf4* | osf5*)  # As osf3* with the addition of the -msym flag
+    if test "$with_gcc" = yes; then
+      allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+      archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib'
+    else
+      allow_undefined_flag=' -expect_unresolved \*'
+      archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib'
+    fi
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator=:
+    ;;
+                                       
+  sco3.2v5*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    runpath_var=LD_RUN_PATH
+    hardcode_runpath_var=yes
+    ;;
+
+  solaris*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec='-R$libdir'
+    hardcode_shlibpath_var=no
+    case "$host_os" in
+    solaris2.[0-5] | solaris2.[0-5].*) ;;
+    *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+      whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+    esac
+    ;;
+
+  sunos4*)
+    archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_direct=yes
+    hardcode_minus_L=yes
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4)
+    if test "x$host_vendor" = xsequent; then
+      # Use $CC to link under sequent, because it throws in some extra .o 
+      # files that make .init and .fini sections work.
+      archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $linkopts'
+    else
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    fi
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    hardcode_direct=no #Motorola manual says yes, but my tests say they lie 
+    ;;  
+
+  sysv4.3*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_shlibpath_var=no
+    export_dynamic_flag_spec='-Bexport'
+    ;;
+
+  sysv5*)
+    no_undefined_flag=' -z text'
+    # $CC -shared without GNU ld will not create a library from C++
+    # object files and a static libstdc++, better avoid it by now
+    archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+    archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+    hardcode_libdir_flag_spec=
+    hardcode_shlibpath_var=no
+    runpath_var='LD_RUN_PATH'
+    ;;
+
+  uts4*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  dgux*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    hardcode_libdir_flag_spec='-L$libdir'
+    hardcode_shlibpath_var=no
+    ;;
+
+  sysv4*MP*)
+    if test -d /usr/nec; then
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+      hardcode_shlibpath_var=no
+      runpath_var=LD_RUN_PATH
+      hardcode_runpath_var=yes
+      ld_shlibs=yes
+    fi
+    ;;
+
+  sysv4.2uw2*)
+    archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+    hardcode_direct=yes
+    hardcode_minus_L=no
+    hardcode_shlibpath_var=no
+    hardcode_runpath_var=yes
+    runpath_var=LD_RUN_PATH
+    ;;
+
+  unixware7*)
+    archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+    runpath_var='LD_RUN_PATH'
+    hardcode_shlibpath_var=no
+    ;;
+
+  *)
+    ld_shlibs=no
+    ;;
+  esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+  echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+  case "$NM" in
+  [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+  *)
+    IFS="${IFS=        }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+    for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+      test -z "$ac_dir" && ac_dir=.
+      if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -B"
+         break
+       elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+         NM="$ac_dir/nm -p"
+         break
+       else
+         NM=${NM="$ac_dir/nm"} # keep the first match, but
+         continue # so that we can try to find one that supports BSD flags
+       fi
+      fi
+    done
+    IFS="$ac_save_ifs"
+    test -z "$NM" && NM=nm
+    ;;
+  esac
+  echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+  ;;
+irix*)
+  symcode='[BCDEGRST]'
+  ;;
+solaris*)
+  symcode='[BDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+  symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Write the raw and C identifiers.
+  global_symbol_pipe="sed -n -e 's/^.*[        ]\($symcode\)[  ][      ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+  $rm conftest*
+  cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  echo "$progname:1662: checking if global_symbol_pipe works" >&5
+  if { (eval echo $progname:1663: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { echo "$progname:1666: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+       if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+         cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         sed 's/^. \(.*\) \(.*\)$/  {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+         cat <<\EOF >> conftest.c
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$objext conftstm.$objext
+         save_LIBS="$LIBS"
+         save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$objext"
+         CFLAGS="$CFLAGS$no_builtin_flag"
+         if { (eval echo $progname:1718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+           pipe_works=yes
+         else
+           echo "$progname: failed program was:" >&5
+           cat conftest.c >&5
+         fi
+         LIBS="$save_LIBS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  $rm conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    global_symbol_pipe=
+  fi
+done
+if test "$pipe_works" = yes; then
+  echo "${ac_t}ok" 1>&6
+else
+  echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+  global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var"; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$hardcode_shlibpath_var" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}.so$major'
+  ;;
+
+aix4*)
+  version_type=linux
+  # AIX has no versioning support, so currently we can not hardcode correct
+  # soname into executable. Probably we can add versioning support to
+  # collect2, so additional links can be useful in future.
+  # We preserve .a as extension for shared libraries though AIX4.2
+  # and later linker supports .so
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+  shlibpath_var=LIBPATH
+  deplibs_check_method=pass_all
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}.so'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  deplibs_check_method=pass_all
+  lt_cv_dlopen="load_add_on"
+  lt_cv_dlopen_libs=
+  lt_cv_dlopen_self=yes
+  ;;
+
+bsdi4*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  export_dynamic_flag_spec=-rdynamic
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw*)
+  version_type=windows
+  need_version=no
+  need_lib_prefix=no
+  if test "$with_gcc" = yes; then
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+  else
+    library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+  fi
+  dynamic_linker='Win32 ld.exe'
+  deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  file_magic_cmd='${OBJDUMP} -f'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  lt_cv_dlopen="LoadLibrary"
+  lt_cv_dlopen_libs=
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+  
+freebsd*)
+  objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+  version_type=freebsd-$objformat
+  case "$version_type" in
+    freebsd-elf*)
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      deplibs_check_method=unknown
+      library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_os" in
+  freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  *) # from 3.2 on
+    shlibpath_overrides_runpath=no
+    ;;
+  esac
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.[012])
+    file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+    ;;
+  *) # Darwin 1.3 on
+    file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  library_names_spec='${libname}${release}${versuffix}.$(test x$module = xyes && echo so || echo dylib) ${libname}${release}${major}.$(test x$module = xyes && echo so || echo dylib) ${libname}.$(test x$module = xyes && echo so || echo dylib)'
+  soname_spec='${libname}${release}${major}.$(test x$module = xyes && echo so || echo dylib)'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  dynamic_linker="$host_os dld.sl"
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  shlibpath_var=SHLIB_PATH
+  shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+  library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+  soname_spec='${libname}${release}.sl$major'
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  case "$host_os" in
+  hpux10.20*)
+    # TODO:  Does this work for hpux-11 too?
+    deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    file_magic_cmd=/usr/bin/file
+    file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+irix5* | irix6*)
+  version_type=irix
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}.so.$major'
+  library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+  case "$host_os" in
+  irix5*)
+    libsuff= shlibsuff=
+    # this will be overridden with pass_all, but let us keep it just in case
+    deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case "$LD" in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  deplibs_check_method='pass_all'
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  deplibs_check_method=pass_all
+
+  if test -f /lib/ld.so.1; then
+    dynamic_linker='GNU ld.so'
+  else
+    # Only the GNU ld.so supports shared libraries on MkLinux.
+    case "$host_cpu" in
+    powerpc*) dynamic_linker=no ;;
+    *) dynamic_linker='Linux ld.so' ;;
+    esac
+  fi
+  ;;
+
+netbsd*)
+  version_type=sunos
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+    soname_spec='${libname}${release}.so$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+openbsd*)
+  version_type=sunos
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+    need_version=no
+  fi
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+os2*)
+  libname_spec='$name'
+  need_lib_prefix=no
+  library_names_spec='$libname.dll $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_version=no
+  soname_spec='${libname}${release}.so'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  # this will be overridden with pass_all, but let us keep it just in case
+  deplibs_check_method='file_magic COFF format alpha shared library'
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/shlib/libc.so
+  deplibs_check_method='pass_all'
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+sco3.2v5*)
+  version_type=osf
+  soname_spec='${libname}${release}.so$major'
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+  file_magic_cmd=/usr/bin/file
+  file_magic_test_file=/lib/libc.so
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case "$host_vendor" in
+    sequent)
+      file_magic_cmd='/bin/file'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+      ;;
+    ncr)
+      deplibs_check_method='pass_all'
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+      file_magic_cmd=/usr/bin/file
+      file_magic_test_file=`echo /usr/lib/libc.so*`
+      ;;
+  esac
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+  soname_spec='${libname}${release}.so$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+    soname_spec='$libname.so.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+  if test x$can_build_shared = xyes; then
+    test x$enable_win32_dll = xno && can_build_shared=no
+    echo "checking if package supports dlls... $can_build_shared" 1>&6
+  fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+  case "$deplibs_check_method" in
+  "file_magic "*)
+    file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+    if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+       egrep "$file_magic_regex" > /dev/null; then
+      :
+    else
+      cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+    fi ;;
+  esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4*)
+  test "$enable_shared" = yes && enable_static=no
+  ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+# Propagate what we've learned...
+ac_cv_can_build_shared="$can_build_shared"
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+  lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2270: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2278 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2310: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2315 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2340: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dlopen"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2357: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2365 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2397: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2402 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load"
+else
+  echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2445: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-ldld  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2453 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+    
+fi
+
+  
+fi
+
+
+fi
+
+fi
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  fi
+
+  case "$lt_cv_dlopen" in
+  dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2510: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2515 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2520: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+    if test "x$ac_cv_header_dlfcn_h" = xyes; then
+      CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+    fi
+    eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+  echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2548: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self=cross
+  else
+    cat > conftest.c <<EOF
+#line 2556 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+              if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+  if test "$lt_cv_dlopen_self" = yes; then
+    LDFLAGS="$LDFLAGS $link_static_flag"
+  echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2621: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    lt_cv_dlopen_self_static=cross
+  else
+    cat > conftest.c <<EOF
+#line 2629 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL   RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+#  define LTDL_GLOBAL  DL_GLOBAL
+# else
+#  define LTDL_GLOBAL  0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+#  define LTDL_LAZY_OR_NOW     RTLD_LAZY
+# else
+#  ifdef DL_LAZY
+#   define LTDL_LAZY_OR_NOW    DL_LAZY
+#  else
+#   ifdef RTLD_NOW
+#    define LTDL_LAZY_OR_NOW   RTLD_NOW
+#   else
+#    ifdef DL_NOW
+#     define LTDL_LAZY_OR_NOW  DL_NOW
+#    else
+#     define LTDL_LAZY_OR_NOW  0
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+    if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+    if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } 
+
+EOF
+if { (eval echo $progname:2675: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+  lt_cv_dlopen_self_static=yes
+else
+  echo "$progname: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+    ;;
+  esac
+
+  case "$lt_cv_dlopen_self" in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case "$lt_cv_dlopen_self_static" in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+  # Now quote all the things that may contain metacharacters.
+  for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+    AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+    reload_flag reload_cmds wl \
+    pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+    thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+    library_names_spec soname_spec \
+    RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+    old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+    file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+    finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+    hardcode_libdir_flag_spec hardcode_libdir_separator  \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+    case "$var" in
+    reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case "$ltecho" in
+  *'\$0 --fallback-echo"')
+    ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+  trap "$rm \"$ofile\"; exit 1" 1 2 15
+  echo "creating $ofile"
+  $rm "$ofile"
+  cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+  cfgfile="$ofile"
+  ;;
+
+*)
+  # Double-quote the variables that need it (for aesthetics).
+  for var in old_CC old_CFLAGS old_CPPFLAGS \
+    old_LD old_LDFLAGS old_LIBS \
+    old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+    eval "$var=\\\"\$var\\\""
+  done
+
+  # Just create a config file.
+  cfgfile="$ofile.cfg"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  echo "creating $cfgfile"
+  $rm "$cfgfile"
+  cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+  ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+#   $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+  echo '### END LIBTOOL CONFIG' >> "$ofile"
+  echo >> "$ofile"
+  case "$host_os" in
+  aix3*)
+    cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # Append the ltmain.sh script.
+  sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+
+  chmod +x "$ofile"
+  ;;
+
+*)
+  # Compile the libtool program.
+  echo "FIXME: would compile $ltmain"
+  ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/saslauthd/config/ltmain.sh b/saslauthd/config/ltmain.sh
new file mode 100644 (file)
index 0000000..3e72886
--- /dev/null
@@ -0,0 +1,4053 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo '' | od -x` in
+*15*) # EBCDIC based system
+  SP2NL='tr \100 \025'
+  NL2SP='tr \025 \100'
+  ;;
+*) # Assume ASCII based system
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+  echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  echo "$modename: not configured to build any kind of library" 1>&2
+  echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+  arg="$1"
+  shift
+
+  case "$arg" in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case "$prev" in
+    execute_dlfiles)
+      eval "$prev=\"\$$prev \$arg\""
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case "$arg" in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    exit 0
+    ;;
+
+  --config)
+    sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+    exit 0
+    ;;
+
+  --debug)
+    echo "$progname: enabling shell trace mode"
+    set -x
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      echo "enable shared libraries"
+    else
+      echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      echo "enable static libraries"
+    else
+      echo "disable static libraries"
+    fi
+    exit 0
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --quiet | --silent)
+    show=:
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+fi
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    case "$nonopt" in
+    *cc | *++ | gcc* | *-gcc*)
+      mode=link
+      for arg
+      do
+       case "$arg" in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit 1
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case "$mode" in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    lastarg=
+    srcfile="$nonopt"
+    suppress_output=
+
+    user_target=no
+    for arg
+    do
+      # Accept any command-line options.
+      case "$arg" in
+      -o)
+       if test "$user_target" != "no"; then
+         $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+         exit 1
+       fi
+       user_target=next
+       ;;
+
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+      esac
+
+      case "$user_target" in
+      next)
+       # The next one is the -o target name
+       user_target=yes
+       continue
+       ;;
+      yes)
+       # We got the output file
+       user_target=set
+       libobj="$arg"
+       continue
+       ;;
+      esac
+
+      # Accept the current argument as the source file.
+      lastarg="$srcfile"
+      srcfile="$arg"
+
+      # Aesthetically quote the previous argument.
+
+      # Backslashify any backslashes, double quotes, and dollar signs.
+      # These are the only characters that are still specially
+      # interpreted inside of double-quoted scrings.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly in scan
+      # sets, so we specify it separately.
+      case "$lastarg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      # Add the previous argument to base_compile.
+      if test -z "$base_compile"; then
+       base_compile="$lastarg"
+      else
+       base_compile="$base_compile $lastarg"
+      fi
+    done
+
+    case "$user_target" in
+    set)
+      ;;
+    no)
+      # Get the name of the library object.
+      libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    *)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSfmso]'
+    case "$libobj" in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case "$libobj" in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit 1
+      ;;
+    esac
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $libobj"
+    else
+      removelist="$libobj"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit 1" 1 2 15
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit 1" 1 2 15
+    else
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until ln "$0" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+      echo $srcfile > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      # All platforms use -DPIC, to notify preprocessed assembler code.
+      command="$base_compile $srcfile $pic_flag -DPIC"
+      if test "$build_old_libs" = yes; then
+       lo_libobj="$libobj"
+       dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$dir" = "X$libobj"; then
+         dir="$objdir"
+       else
+         dir="$dir/$objdir"
+       fi
+       libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+       if test -d "$dir"; then
+         $show "$rm $libobj"
+         $run $rm $libobj
+       else
+         $show "$mkdir $dir"
+         $run $mkdir $dir
+         status=$?
+         if test $status -ne 0 && test ! -d $dir; then
+           exit $status
+         fi
+       fi
+      fi
+      if test "$compiler_o_lo" = yes; then
+       output_obj="$libobj"
+       command="$command -o $output_obj"
+      elif test "$compiler_c_o" = yes; then
+       output_obj="$obj"
+       command="$command -o $output_obj"
+      fi
+
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test x"$output_obj" != x"$libobj"; then
+       $show "$mv $output_obj $libobj"
+       if $run $mv $output_obj $libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # If we have no pic_flag, then copy the object into place and finish.
+      if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+       # Rename the .lo from within objdir to obj
+       if test -f $obj; then
+         $show $rm $obj
+         $run $rm $obj
+       fi
+
+       $show "$mv $libobj $obj"
+       if $run $mv $libobj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+
+       xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$obj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+       libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+       # Now arrange that obj and lo_libobj become the same file
+       $show "(cd $xdir && $LN_S $baseobj $libobj)"
+       if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+         exit 0
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Allow error messages only from the first compilation.
+      suppress_output=' >/dev/null 2>&1'
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      command="$base_compile $srcfile"
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+       output_obj="$obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit 1
+      fi
+
+      if test "$need_locks" = warn &&
+        test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+       echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit 1
+      fi
+
+      # Just move the object if needed
+      if test x"$output_obj" != x"$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Create an invalid libtool object if no PIC, so that we do not
+      # accidentally link it into a program.
+      if test "$build_libtool_libs" != yes; then
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > \$libobj" || exit $?
+      else
+       # Move the .lo from within objdir
+       $show "$mv $libobj $lo_libobj"
+       if $run $mv $libobj $lo_libobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+    fi
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $rm "$lockfile"
+    fi
+
+    exit 0
+    ;;
+
+  # libtool link mode
+  link)
+    modename="$modename: link"
+    case "$host" in
+    *-*-cygwin* | *-*-mingw* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invokation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+
+      # This is a source program that is used to create dlls on Windows
+      # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+      # This is a source program that is used to create import libraries
+      # on Windows for dlls which lack them. Don't remove nor modify the
+      # starting and closing comments
+# /* impgen.c starts here */
+# /*   Copyright (C) 1999 Free Software Foundation, Inc.
+# 
+#  This file is part of GNU libtool.
+# 
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+# 
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+# 
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#  */
+# 
+#  #include <stdio.h>          /* for printf() */
+#  #include <unistd.h>         /* for open(), lseek(), read() */
+#  #include <fcntl.h>          /* for O_RDONLY, O_BINARY */
+#  #include <string.h>         /* for strdup() */
+# 
+#  static unsigned int
+#  pe_get16 (fd, offset)
+#       int fd;
+#       int offset;
+#  {
+#    unsigned char b[2];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 2);
+#    return b[0] + (b[1]<<8);
+#  }
+# 
+#  static unsigned int
+#  pe_get32 (fd, offset)
+#      int fd;
+#      int offset;
+#  {
+#    unsigned char b[4];
+#    lseek (fd, offset, SEEK_SET);
+#    read (fd, b, 4);
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  static unsigned int
+#  pe_as32 (ptr)
+#       void *ptr;
+#  {
+#    unsigned char *b = ptr;
+#    return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+#  }
+# 
+#  int
+#  main (argc, argv)
+#      int argc;
+#      char *argv[];
+#  {
+#      int dll;
+#      unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+#      unsigned long export_rva, export_size, nsections, secptr, expptr;
+#      unsigned long name_rvas, nexp;
+#      unsigned char *expdata, *erva;
+#      char *filename, *dll_name;
+# 
+#      filename = argv[1];
+# 
+#      dll = open(filename, O_RDONLY|O_BINARY);
+#      if (!dll)
+#      return 1;
+# 
+#      dll_name = filename;
+#    
+#      for (i=0; filename[i]; i++)
+#      if (filename[i] == '/' || filename[i] == '\\'  || filename[i] == ':')
+#          dll_name = filename + i +1;
+# 
+#      pe_header_offset = pe_get32 (dll, 0x3c);
+#      opthdr_ofs = pe_header_offset + 4 + 20;
+#      num_entries = pe_get32 (dll, opthdr_ofs + 92);
+# 
+#      if (num_entries < 1) /* no exports */
+#      return 1;
+# 
+#      export_rva = pe_get32 (dll, opthdr_ofs + 96);
+#      export_size = pe_get32 (dll, opthdr_ofs + 100);
+#      nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+#      secptr = (pe_header_offset + 4 + 20 +
+#            pe_get16 (dll, pe_header_offset + 4 + 16));
+# 
+#      expptr = 0;
+#      for (i = 0; i < nsections; i++)
+#      {
+#      char sname[8];
+#      unsigned long secptr1 = secptr + 40 * i;
+#      unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+#      unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+#      unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+#      lseek(dll, secptr1, SEEK_SET);
+#      read(dll, sname, 8);
+#      if (vaddr <= export_rva && vaddr+vsize > export_rva)
+#      {
+#          expptr = fptr + (export_rva - vaddr);
+#          if (export_rva + export_size > vaddr + vsize)
+#              export_size = vsize - (export_rva - vaddr);
+#          break;
+#      }
+#      }
+# 
+#      expdata = (unsigned char*)malloc(export_size);
+#      lseek (dll, expptr, SEEK_SET);
+#      read (dll, expdata, export_size);
+#      erva = expdata - export_rva;
+# 
+#      nexp = pe_as32 (expdata+24);
+#      name_rvas = pe_as32 (expdata+32);
+# 
+#      printf ("EXPORTS\n");
+#      for (i = 0; i<nexp; i++)
+#      {
+#      unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+#      printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+#      }
+# 
+#      return 0;
+#  }
+# /* impgen.c ends here */
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    linkopts=
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      lib_search_path=
+    fi
+    # now prepend the system-specific ones
+    eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+    
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    link_against_libtool_libs=
+    ltlibs=
+    module=no
+    objs=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case "$arg" in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       prefer_static_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test $# -gt 0; do
+      arg="$1"
+      shift
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case "$prev" in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case "$prev" in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case "$arg" in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit 1
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case "$arg" in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit 1
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi
+
+      prevarg="$arg"
+
+      case "$arg" in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: not more than one -exported-symbols argument allowed"
+         exit 1
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           absdir="$dir"
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case " $deplibs " in
+       *" $arg "*) ;;
+       *) deplibs="$deplibs $arg";;
+       esac
+       case " $lib_search_path " in
+       *" $dir "*) ;;
+       *) lib_search_path="$lib_search_path $dir";;
+       esac
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2*)
+         dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+         case ":$dllsearchpath:" in
+         ::) dllsearchpath="$dllsearchdir";;
+         *":$dllsearchdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+         esac
+         ;;
+       esac
+       ;;
+
+      -l*)
+       if test "$arg" = "-lc"; then
+         case "$host" in
+         *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+           # These systems don't actually have c library (as such)
+           continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         esac
+       elif test "$arg" = "-lm"; then
+         case "$host" in
+         *-*-cygwin* | *-*-beos*)
+           # These systems don't actually have math library (as such)
+           continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody math library is in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         esac
+       fi
+       deplibs="$deplibs $arg"
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case "$dir" in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit 1
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # If we have no pic_flag, then this is the same as -all-static.
+       if test -z "$pic_flag" && test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.o | *.obj | *.a | *.lib)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A library object.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+           prev=
+           continue
+         else
+           # If libtool objects are unsupported, then we need to preload.
+           prev=dlprefiles
+         fi
+       fi
+
+       if test "$prev" = dlprefiles; then
+         # Preload the old-style object.
+         dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+         prev=
+       fi
+       libobjs="$libobjs $arg"
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       dlname=
+       libdir=
+       library_names=
+       old_library=
+
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+         exit 1
+       fi
+
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variable installed.
+       installed=yes
+
+       # Read the .la file
+       # If there is no directory component, then add one.
+       case "$arg" in
+       */* | *\\*) . $arg ;;
+       *) . ./$arg ;;
+       esac
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+         exit 1
+       fi
+
+       # Find the relevant object directory and library name.
+       name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+       if test "X$installed" = Xyes; then
+         dir="$libdir"
+       else
+         dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$dir" = "X$arg"; then
+           dir="$objdir"
+         else
+           dir="$dir/$objdir"
+         fi
+       fi
+
+       if test -n "$dependency_libs"; then
+         # Extract -R and -L from dependency_libs
+         temp_deplibs=
+         for deplib in $dependency_libs; do
+           case "$deplib" in
+           -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+                case " $rpath $xrpath " in
+                *" $temp_xrpath "*) ;;
+                *) xrpath="$xrpath $temp_xrpath";;
+                esac;;
+           -L*) case "$compile_command $temp_deplibs " in
+                *" $deplib "*) ;;
+                *) temp_deplibs="$temp_deplibs $deplib";;
+                esac
+                temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+                case " $lib_search_path " in
+                *" $temp_dir "*) ;;
+                *) lib_search_path="$lib_search_path $temp_dir";;
+                esac
+                ;;
+           *) temp_deplibs="$temp_deplibs $deplib";;
+           esac
+         done
+         dependency_libs="$temp_deplibs"
+       fi
+
+       if test -z "$libdir"; then
+         # It is a libtool convenience library, so add in its objects.
+         convenience="$convenience $dir/$old_library"
+         old_convenience="$old_convenience $dir/$old_library"
+         deplibs="$deplibs$dependency_libs"
+         compile_command="$compile_command $dir/$old_library$dependency_libs"
+         finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+         continue
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$prev" = dlfiles; then
+         dlfiles="$dlfiles $arg"
+         if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking statically,
+           # we need to preload.
+           prev=dlprefiles
+         else
+           # We should not create a dependency on this library, but we
+           # may need any libraries it requires.
+           compile_command="$compile_command$dependency_libs"
+           finalize_command="$finalize_command$dependency_libs"
+           prev=
+           continue
+         fi
+       fi
+
+       # The library was specified with -dlpreopen.
+       if test "$prev" = dlprefiles; then
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           dlprefiles="$dlprefiles $dir/$old_library"
+         else
+           dlprefiles="$dlprefiles $dir/$linklib"
+         fi
+         prev=
+       fi
+
+       if test -n "$library_names" &&
+          { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+         link_against_libtool_libs="$link_against_libtool_libs $arg"
+         if test -n "$shlibpath_var"; then
+           # Make sure the rpath contains only unique directories.
+           case "$temp_rpath " in
+           *" $dir "*) ;;
+           *) temp_rpath="$temp_rpath $dir" ;;
+           esac
+         fi
+
+         # We need an absolute path.
+         case "$dir" in
+         [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+         *)
+           absdir=`cd "$dir" && pwd`
+           if test -z "$absdir"; then
+             $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+             $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+             absdir="$dir"
+           fi
+           ;;
+         esac
+         
+         # This is the magic to use -rpath.
+         # Skip directories that are in the system default run-time
+         # search path, unless they have been requested with -R.
+         case " $sys_lib_dlsearch_path " in
+         *" $absdir "*) ;;
+         *)
+           case "$compile_rpath " in
+           *" $absdir "*) ;;
+           *) compile_rpath="$compile_rpath $absdir" 
+           esac
+           ;;
+         esac
+
+         case " $sys_lib_dlsearch_path " in
+         *" $libdir "*) ;;
+         *)
+           case "$finalize_rpath " in
+           *" $libdir "*) ;;
+           *) finalize_rpath="$finalize_rpath $libdir"
+           esac
+           ;;
+         esac
+
+         lib_linked=yes
+         case "$hardcode_action" in
+         immediate | unsupported)
+           if test "$hardcode_direct" = no; then
+             compile_command="$compile_command $dir/$linklib"
+             deplibs="$deplibs $dir/$linklib"
+             case "$host" in
+             *-*-cygwin* | *-*-mingw* | *-*-os2*)
+               dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+               if test -n "$dllsearchpath"; then
+                 dllsearchpath="$dllsearchpath:$dllsearchdir"
+               else
+                 dllsearchpath="$dllsearchdir"
+               fi
+               ;;
+             esac
+           elif test "$hardcode_minus_L" = no; then
+             case "$host" in
+             *-*-sunos*)
+               compile_shlibpath="$compile_shlibpath$dir:"
+               ;;
+             esac
+             case "$compile_command " in
+             *" -L$dir "*) ;;
+             *) compile_command="$compile_command -L$dir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$dir -l$name"
+           elif test "$hardcode_shlibpath_var" = no; then
+             case ":$compile_shlibpath:" in
+             *":$dir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$dir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         relink)
+           if test "$hardcode_direct" = yes; then
+             compile_command="$compile_command $absdir/$linklib"
+             deplibs="$deplibs $absdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             case "$compile_command " in
+             *" -L$absdir "*) ;;
+             *) compile_command="$compile_command -L$absdir";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -L$absdir -l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case ":$compile_shlibpath:" in
+             *":$absdir:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$absdir:";;
+             esac
+             compile_command="$compile_command -l$name"
+             deplibs="$deplibs -l$name"
+           else
+             lib_linked=no
+           fi
+           ;;
+
+         *)
+           lib_linked=no
+           ;;
+         esac
+
+         if test "$lib_linked" != yes; then
+           $echo "$modename: configuration error: unsupported hardcode properties"
+           exit 1
+         fi
+
+         # Finalize command for both is simple: just hardcode it.
+         if test "$hardcode_direct" = yes; then
+           finalize_command="$finalize_command $libdir/$linklib"
+         elif test "$hardcode_minus_L" = yes; then
+           case "$finalize_command " in
+           *" -L$libdir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         elif test "$hardcode_shlibpath_var" = yes; then
+           case ":$finalize_shlibpath:" in
+           *":$libdir:"*) ;;
+           *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         else
+           # We cannot seem to hardcode it, guess we'll fake it.
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$libdir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       else
+         # Transform directly to old archives if we don't build new libraries.
+         if test -n "$pic_flag" && test -z "$old_library"; then
+           $echo "$modename: cannot find static library for \`$arg'" 1>&2
+           exit 1
+         fi
+
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_command="$compile_command $dir/$linklib"
+           finalize_command="$finalize_command $dir/$linklib"
+         else
+           case "$compile_command " in
+           *" -L$dir "*) ;;
+           *) compile_command="$compile_command -L$dir";;
+           esac
+           compile_command="$compile_command -l$name"
+           case "$finalize_command " in
+           *" -L$dir "*) ;;
+           *) finalize_command="$finalize_command -L$dir";;
+           esac
+           finalize_command="$finalize_command -l$name"
+         fi
+       fi
+
+       # Add in any libraries that this one depends upon.
+       compile_command="$compile_command$dependency_libs"
+       finalize_command="$finalize_command$dependency_libs"
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case "$arg" in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*)
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    case "$output" in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+      ;;
+
+    *.a | *.lib)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      ;;
+
+    *.la)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case "$outputname" in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      if test -n "$objs"; then
+       $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+       exit 1
+      fi
+
+      # How the heck are we supposed to write a wrapper for a shared library?
+      if test -n "$link_against_libtool_libs"; then
+        $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+        exit 1
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test $# -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         libext=al
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+       dependency_libs="$deplibs"
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       current="$2"
+       revision="$3"
+       age="$4"
+
+       # Check that each of the things are valid numbers.
+       case "$current" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$revision" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       case "$age" in
+       0 | [1-9] | [1-9][0-9]*) ;;
+       *)
+         $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+         ;;
+       esac
+
+       if test $age -gt $current; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit 1
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case "$version_type" in
+       none) ;;
+
+       irix)
+         major=`expr $current - $age + 1`
+         versuffix="$major.$revision"
+         verstring="sgi$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test $loop != 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="sgi$major.$iface:$verstring"
+         done
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test $loop != 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       windows)
+         # Like Linux, but with '-' rather than '.', since we only
+         # want one extension on Windows 95.
+         major=`expr $current - $age`
+         versuffix="-$major-$age-$revision"
+         ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         minor_current=`expr $current + 1`
+         verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         verstring="0.0"
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+       
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+
+       dependency_libs="$deplibs"
+       case "$host" in
+       *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+         # these systems don't actually have a c library (as such)!
+         ;;
+        *-*-rhapsody* | *-*-darwin1.[012])
+         # Rhapsody C library is in the System framework
+         deplibs="$deplibs -framework System"
+         ;;
+       *)
+         # Add libc to deplibs on all other systems.
+         deplibs="$deplibs -lc"
+         ;;
+       esac
+      fi
+
+      # Create the output directory, or remove our outputs if we need to.
+      if test -d $output_objdir; then
+       $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+       $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+      else
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      if test "$build_libtool_libs" = yes; then
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case "$deplibs_check_method" in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behaviour.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $CC -o conftest conftest.c $deplibs
+         if test $? -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name="`expr X$i : 'X-l\(.*\)'`"
+             # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               deplib_matches=`eval \\$echo \"$library_names_spec\"`
+               set dummy $deplib_matches
+               deplib_match=$2
+               if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                 newdeplibs="$newdeplibs $i"
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning: This library needs some functionality provided by $i."
+                 echo "*** I have the capability to make that library automatically link in when"
+                 echo "*** you link to this library.  But I can only do this if you have a"
+                 echo "*** shared version of the library, which you do not appear to have."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occured in the first compile.  Let's try to salvage the situation:
+           # Compile a seperate program for each library.
+           for i in $deplibs; do
+             name="`expr X$i : 'X-l\(.*\)'`"
+            # If $name is empty we are operating on a -L argument.
+             if test "$name" != "" ; then
+               $rm conftest
+               $CC -o conftest conftest.c $i
+               # Did it work?
+               if test $? -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   echo
+                   echo "*** Warning: This library needs some functionality provided by $i."
+                   echo "*** I have the capability to make that library automatically link in when"
+                   echo "*** you link to this library.  But I can only do this if you have a"
+                   echo "*** shared version of the library, which you do not appear to have."
+                 fi
+               else
+                 droppeddeps=yes
+                 echo
+                 echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 echo "***  make it link in!  You will probably need to install it or some"
+                 echo "*** library that it depends on before this library will be fully"
+                 echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+         for a_deplib in $deplibs; do
+           name="`expr X$a_deplib : 'X-l\(.*\)'`"
+           # If $name is empty we are operating on a -L argument.
+           if test "$name" != "" ; then
+             libname=`eval \\$echo \"$libname_spec\"`
+             for i in $lib_search_path; do
+                   potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                   for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue 
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+                       case "$potliblink" in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | sed 10q \
+                        | egrep "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                   done
+             done
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               echo
+               echo "*** Warning: This library needs some functionality provided by $a_deplib."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have."
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+              -e 's/ -[LR][^ ]*//g' -e 's/[    ]//g' |
+            grep . >/dev/null; then
+           echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           echo
+           echo "*** Warning: libtool could not satisfy all declared inter-library"
+           echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           echo "*** a static module, that should work as long as the dlopening"
+           echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             echo
+             echo "*** However, this would only work if libtool was able to extract symbol"
+             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             echo "*** not find such a program.  So, this module is probably useless."
+             echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           echo "*** The inter-library dependencies that have been dropped here will be"
+           echo "*** automatically added whenever a program is linked with this library"
+           echo "*** or is declared to -dlopen it."
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+      
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       # Get the real and link names of the library.
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+
+       lib="$output_objdir/$realname"
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Ensure that we have .o objects for linkers which dislike .lo
+       # (e.g. aix) in case we are running --disable-static
+       for obj in $libobjs; do
+         xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$obj"; then
+           xdir="."
+         else
+           xdir="$xdir"
+         fi
+         baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+         oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+         if test ! -f $xdir/$oldobj; then
+           $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+           $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+         fi
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           eval cmds=\"$export_symbols_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd" || exit $?
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "mkdir $gentop"
+           $run mkdir "$gentop"
+           status=$?
+           if test $status -ne 0 && test ! -d "$gentop"; then
+             exit $status
+           fi
+           generated="$generated $gentop"
+
+           for xlib in $convenience; do
+             # Extract the objects.
+             case "$xlib" in
+             [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+             *) xabs=`pwd`"/$xlib" ;;
+             esac
+             xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+             xdir="$gentop/$xlib"
+
+             $show "${rm}r $xdir"
+             $run ${rm}r "$xdir"
+             $show "mkdir $xdir"
+             $run mkdir "$xdir"
+             status=$?
+             if test $status -ne 0 && test ! -d "$xdir"; then
+               exit $status
+             fi
+             $show "(cd $xdir && $AR x $xabs)"
+             $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+             libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+           done
+         fi
+       fi
+
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linkopts="$linkopts $flag"
+       fi
+
+       # Do each of the archive commands.
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval cmds=\"$archive_expsym_cmds\"
+       else
+         eval cmds=\"$archive_cmds\"
+       fi
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    *.lo | *.o | *.obj)
+      if test -n "$link_against_libtool_libs"; then
+       $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+       exit 1
+      fi
+
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case "$output" in
+      *.lo)
+       if test -n "$objs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit 1
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl= 
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         $show "${rm}r $gentop"
+         $run ${rm}r "$gentop"
+         $show "mkdir $gentop"
+         $run mkdir "$gentop"
+         status=$?
+         if test $status -ne 0 && test ! -d "$gentop"; then
+           exit $status
+         fi
+         generated="$generated $gentop"
+
+         for xlib in $convenience; do
+           # Extract the objects.
+           case "$xlib" in
+           [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+           *) xabs=`pwd`"/$xlib" ;;
+           esac
+           xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+           xdir="$gentop/$xlib"
+
+           $show "${rm}r $xdir"
+           $run ${rm}r "$xdir"
+           $show "mkdir $xdir"
+           $run mkdir "$xdir"
+           status=$?
+           if test $status -ne 0 && test ! -d "$xdir"; then
+             exit $status
+           fi
+           $show "(cd $xdir && $AR x $xabs)"
+           $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+           reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+         done
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+      output="$obj"
+      eval cmds=\"$reload_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit 0
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       $show "echo timestamp > $libobj"
+       $run eval "echo timestamp > $libobj" || exit $?
+       exit 0
+      fi
+
+      if test -n "$pic_flag"; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       eval cmds=\"$reload_cmds\"
+       IFS="${IFS=     }"; save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      else
+       # Just create a symlink.
+       $show $rm $libobj
+       $run $rm $libobj
+       xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+       if test "X$xdir" = "X$libobj"; then
+         xdir="."
+       else
+         xdir="$xdir"
+       fi
+       baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+       oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+       $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+       $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit 0
+      ;;
+
+    # Anything else should be a program.
+    *)
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi 
+      fi
+    
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$compile_rpath " in
+         *" $libdir "*) ;;
+         *) compile_rpath="$compile_rpath $libdir" ;;
+         esac
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$output_objdir" = "X$output"; then
+       output_objdir="$objdir"
+      else
+       output_objdir="$output_objdir/$objdir"
+      fi
+
+      # Create the binary in the object directory, then wrap it.
+      if test ! -d $output_objdir; then
+       $show "$mkdir $output_objdir"
+       $run $mkdir $output_objdir
+       status=$?
+       if test $status -ne 0 && test ! -d $output_objdir; then
+         exit $status
+       fi
+      fi
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case "$dlsyms" in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+           
+           if test -n "$export_symbols_regex"; then
+             $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$output.exp"
+             $run $rm $export_symbols
+             $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+           else
+             $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+             $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`echo "$arg" | sed -e 's%^.*/%%'`
+           $run eval 'echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           sed -n -e 's/^: \([^ ]*\) $/  {\"\1\", (lt_ptr_t) 0},/p' \
+               -e 's/^. \([^ ]*\) \([^ ]*\)$/  {"\2", (lt_ptr_t) \&\2},/p' \
+                 < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case "$host" in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+         compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit 1
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       status=$?
+       
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case "$dir" in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+       
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+       case "$0" in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+       esac
+       $rm $output
+       trap "$rm $output; exit 1" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  link_against_libtool_libs='$link_against_libtool_libs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         echo >> $output "\
+  program=lt-'$outputname'
+  progdir=\"\$thisdir/$objdir\"
+  
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if (cd \"\$thisdir\" && eval \$relink_command); then :
+      else
+       $rm \"\$progdir/\$file\"
+       exit 1
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+       case $host in
+         # win32 systems need to use the prog path for dll
+         # lookup to work
+       *-*-cygwin*)
+         $echo >> $output "\
+      exec \$progdir/\$program \${1+\"\$@\"}
+"
+         ;;
+
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      # Export the path to the program.
+      PATH=\"\$progdir:\$PATH\"
+      export PATH
+
+      exec \$program \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit 0
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       $show "${rm}r $gentop"
+       $run ${rm}r "$gentop"
+       $show "mkdir $gentop"
+       $run mkdir "$gentop"
+       status=$?
+       if test $status -ne 0 && test ! -d "$gentop"; then
+         exit $status
+       fi
+       generated="$generated $gentop"
+         
+       # Add in members from convenience archives.
+       for xlib in $addlibs; do
+         # Extract the objects.
+         case "$xlib" in
+         [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+         *) xabs=`pwd`"/$xlib" ;;
+         esac
+         xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+         xdir="$gentop/$xlib"
+
+         $show "${rm}r $xdir"
+         $run ${rm}r "$xdir"
+         $show "mkdir $xdir"
+         $run mkdir "$xdir"
+         status=$?
+         if test $status -ne 0 && test ! -d "$xdir"; then
+           exit $status
+         fi
+         $show "(cd $xdir && $AR x $xabs)"
+         $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+         oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+       done
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       eval cmds=\"$old_archive_from_new_cmds\"
+      else
+       # Ensure that we have .o objects in place in case we decided
+       # not to build a shared library, and have fallen back to building
+       # static libs even though --disable-static was passed!
+       for oldobj in $oldobjs; do
+         if test ! -f $oldobj; then
+           xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$oldobj"; then
+             xdir="."
+           else
+             xdir="$xdir"
+           fi
+           baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+           obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+           $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+           $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+         fi
+       done
+
+       eval cmds=\"$old_archive_cmds\"
+      fi
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case "$output" in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      if test -n "$xrpath"; then
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+       done
+       dependency_libs="$temp_xrpath $dependency_libs"
+      fi
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+         fi
+         $rm $output
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+      ;;
+    esac
+    exit 0
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg="$nonopt"
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case "$arg" in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*)
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest="$arg"
+       continue
+      fi
+
+      case "$arg" in
+      -d) isdir=yes ;;
+      -f) prev="-f" ;;
+      -g) prev="-g" ;;
+      -m) prev="-m" ;;
+      -o) prev="-o" ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*) ;;
+
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest="$arg"
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case "$arg" in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*)
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test $# -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+    fi
+    case "$destdir" in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case "$file" in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case "$file" in
+      *.a | *.lib)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       library_names=
+       old_library=
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$realname $destdir/$realname"
+         $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+         if test $# -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+               $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+               $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         eval cmds=\"$postinstall_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case "$destfile" in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.o | *.obj)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit 0
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         link_against_libtool_libs=
+         relink_command=
+
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$link_against_libtool_libs"; then
+           $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+           exit 1
+         fi
+
+         finalize=yes
+         for lib in $link_against_libtool_libs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case "$lib" in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir="/tmp"
+             test -n "$TMPDIR" && tmpdir="$TMPDIR"
+             tmpdir="$tmpdir/libtool-$$"
+             if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+             else
+               $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+               continue
+             fi
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      # Do each command in the postinstall commands.
+      eval cmds=\"$old_postinstall_cmds\"
+      IFS="${IFS=      }"; save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec $SHELL $0 --finish$current_libdirs
+      exit 1
+    fi
+
+    exit 0
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         eval cmds=\"$finish_cmds\"
+         IFS="${IFS=   }"; save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit 0
+
+    echo "----------------------------------------------------------------------"
+    echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      echo "   $libdir"
+    done
+    echo
+    echo "If you ever happen to want to link against installed libraries"
+    echo "in a given directory, LIBDIR, you must either use libtool, and"
+    echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+    echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    echo
+    echo "See any operating system documentation about shared libraries for"
+    echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    echo "----------------------------------------------------------------------"
+    exit 0
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit 1
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit 1
+      fi
+
+      dir=
+      case "$file" in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit 1
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case "$file" in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit 1
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case "$file" in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case "$file" in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+        # Export the shlibpath_var.
+        eval "export $shlibpath_var"
+      fi
+
+      # Restore saved enviroment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now actually exec the command.
+      eval "exec \$cmd$args"
+
+      $echo "$modename: cannot exec \$cmd$args"
+      exit 1
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+        eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+        $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit 0
+    fi
+    ;;
+
+  # libtool uninstall mode
+  uninstall)
+    modename="$modename: uninstall"
+    rm="$nonopt"
+    files=
+
+    for arg
+    do
+      case "$arg" in
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit 1
+    fi
+
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$dir" = "X$file" && dir=.
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      rmfiles="$file"
+
+      case "$name" in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $dir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+         $show "$rm $rmfiles"
+         $run $rm $rmfiles
+
+         if test -n "$library_names"; then
+           # Do each command in the postuninstall commands.
+           eval cmds=\"$postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         if test -n "$old_library"; then
+           # Do each command in the old_postuninstall commands.
+           eval cmds=\"$old_postuninstall_cmds\"
+           IFS="${IFS=         }"; save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             $show "$cmd"
+             $run eval "$cmd"
+           done
+           IFS="$save_ifs"
+         fi
+
+         # FIXME: should reinstall the best remaining shared library.
+       fi
+       ;;
+
+      *.lo)
+       if test "$build_old_libs" = yes; then
+         oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+         rmfiles="$rmfiles $dir/$oldobj"
+       fi
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+
+      *)
+       $show "$rm $rmfiles"
+       $run $rm $rmfiles
+       ;;
+      esac
+    done
+    exit 0
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit 1
+    ;;
+  esac
+
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$generic_help" 1>&2
+  exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --version         print version information
+
+MODE must be one of the following:
+
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+  exit 0
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit 1
+  ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/saslauthd/config/missing b/saslauthd/config/missing
new file mode 100755 (executable)
index 0000000..6a37006
--- /dev/null
@@ -0,0 +1,336 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]"
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing 0.4 - GNU automake"
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+  aclocal*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+                                      sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+          sed 's/\.am$/.in/' |
+          while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1Help2man' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo "#! /bin/sh"
+       echo "# Created by GNU Automake missing as a replacement of"
+       echo "#  $ $@"
+       echo "exit 0"
+       chmod +x $file
+       exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.y)
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.c
+           fi
+           SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" y.tab.h
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f y.tab.h ]; then
+       echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+       echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+       case "$LASTARG" in
+       *.l)
+           SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+           if [ -f "$SRCFILE" ]; then
+                cp "$SRCFILE" lex.yy.c
+           fi
+         ;;
+       esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+       echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+        you modified a dependency of a manual page.  You may need the
+        \`Help2man' package in order for those modifications to take
+        effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+       file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+       touch $file
+    else
+       test -z "$file" || exec >$file
+       echo ".ab help2man is required to generate this page"
+       exit 1
+    fi
+    ;;
+
+  makeinfo)
+    if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
+       # We have makeinfo, but it failed.
+       exit 1
+    fi
+
+    echo 1>&2 "\
+WARNING: \`$1' is missing on your system.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+    if test -n "$run"; then
+      echo 1>&2 "ERROR: \`tar' requires --run"
+      exit 1
+    fi
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+       case "$firstarg" in
+       *o*)
+           firstarg=`echo "$firstarg" | sed s/o//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+       case "$firstarg" in
+       *h*)
+           firstarg=`echo "$firstarg" | sed s/h//`
+           tar "$firstarg" "$@" && exit 0
+           ;;
+       esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+         system.  You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequirements for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
diff --git a/saslauthd/config/mkinstalldirs b/saslauthd/config/mkinstalldirs
new file mode 100755 (executable)
index 0000000..d2d5f21
--- /dev/null
@@ -0,0 +1,111 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage" 1>&2
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+case $dirmode in
+  '')
+    if mkdir -p -- . 2>/dev/null; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+       errstatus=$lasterr
+      else
+       if test ! -z "$dirmode"; then
+         echo "chmod $dirmode $pathcomp"
+         lasterr=""
+         chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+         if test ! -z "$lasterr"; then
+           errstatus=$lasterr
+         fi
+       fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# End:
+# mkinstalldirs ends here
diff --git a/saslauthd/configure b/saslauthd/configure
new file mode 100755 (executable)
index 0000000..2226db0
--- /dev/null
@@ -0,0 +1,13242 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.57.
+#
+# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+# Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="mechanisms.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os SASLAUTHD_TRUE SASLAUTHD_FALSE INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP LN_S LIB_SOCKET EGREP CMU_LIB_SUBDIR LIB_DES SASL_KRB_LIB LIB_CRYPT GSSAPI_LIBS GSSAPIBASE_LIBS LIB_SIA SASL_DB_UTILS SASL_DB_MANS SASL_DB_BACKEND SASL_DB_BACKEND_STATIC SASL_DB_INC SASL_DB_LIB MAIN_COMPAT_OBJ LIB_PAM LDAP_LIBS LTLIBOBJS LIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+              localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$0" : 'X\(//\)[^/]' \| \
+         X"$0" : 'X\(//\)$' \| \
+         X"$0" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking Speeds up one-time builds
+  --enable-dependency-tracking  Do not reject slow dependency extractors
+  --enable-krb4           enable KERBEROS_V4 authentication [no]
+  --enable-gssapi=<DIR>   enable GSSAPI authentication [yes]
+  --enable-sia            enable SIA authentication no
+  --enable-auth-sasldb    enable experimental SASLdb authentication module no
+  --enable-httpform       enable HTTP form authentication [no]
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-saslauthd=DIR    enable use of the saslauth daemon using state dir DIR
+  --with-lib-subdir=DIR   Find libraries in DIR instead of lib
+  --with-openssl=PATH     use OpenSSL from PATH
+  --with-des=DIR          with DES (look in DIR) yes
+  --with-gss_impl={heimdal|mit|cybersafe|seam|auto}
+                          choose specific GSSAPI implementation [[auto]]
+  --with-dbpath=PATH      set the DB path to use /etc/sasldb2
+  --with-dblib=DBLIB      set the DB library to use berkeley
+  --with-bdb-libdir=DIR   Berkeley DB lib files are in DIR
+  --with-bdb-incdir=DIR   Berkeley DB include files are in DIR
+  --with-gdbm=PATH        use gdbm from PATH
+  --with-pam=DIR          use PAM (rooted in DIR) yes
+  --with-ipctype={unix,doors}    use ipctype unix
+  --with-ldap=DIR         use LDAP (in DIR) no
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+           test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
+Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+        ac_must_keep_next=false # Got value, back to normal.
+      else
+        case $ac_arg in
+          *=* | --config-cache | -C | -disable-* | --disable-* \
+          | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+          | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+          | -with-* | --with-* | -without-* | --without-* | --x)
+            case "$ac_configure_args0 " in
+              "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+            esac
+            ;;
+          -* ) ac_must_keep_next=true ;;
+        esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+        "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+       eval ac_val=$`echo $ac_var`
+        echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core core.* *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+               sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+        { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+        { echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+        { echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+        ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"   "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ac_aux_dir=
+for ac_dir in config $srcdir/config; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in config $srcdir/config" >&5
+echo "$as_me: error: cannot find install-sh or install.sh in config $srcdir/config" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+
+# Check whether --with-saslauthd or --without-saslauthd was given.
+if test "${with_saslauthd+set}" = set; then
+  withval="$with_saslauthd"
+  with_saslauthd=$withval
+else
+  with_saslauthd=yes
+fi;
+  if test "$with_saslauthd" = yes; then
+    with_saslauthd="/var/state/saslauthd"
+  fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SASLAUTHD
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PATH_SASLAUTHD_RUNDIR "$with_saslauthd"
+_ACEOF
+
+
+
+if test "$with_saslauthd" != no; then
+  SASLAUTHD_TRUE=
+  SASLAUTHD_FALSE='#'
+else
+  SASLAUTHD_TRUE='#'
+  SASLAUTHD_FALSE=
+fi
+
+
+am__api_version="1.7"
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+ # test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE=saslauthd
+ VERSION=2.1.23
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+
+
+
+
+
+       ACLOCAL="$ACLOCAL -I \$(top_srcdir)/cmulocal"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output" >&5
+echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+        ;;
+    conftest.$ac_ext )
+        # This is the source file.
+        ;;
+    [ab].out )
+        # We found the default executable, but exeext='' is most
+        # certainly right.
+        break;;
+    *.* )
+        ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+        # FIXME: I believe we export ac_cv_exeext for Libtool,
+        # but it would be cool to find out if it's true.  Does anybody
+        # maintain Libtool? --akim.
+        export ac_cv_exeext
+        break;;
+    * )
+        break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+          export ac_cv_exeext
+          break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX                  -qlanglvl=ansi
+# Ultrix and OSF/1     -std1
+# HP-UX 10.20 and later        -Ae
+# HP-UX older versions -Aa -D_HPUX_SOURCE
+# SVR4                 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+          ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+       @echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      : > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+       continue
+      else
+       break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored.
+      if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+                     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+       @echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+echo "$as_me:$LINENO: checking whether ln -s works" >&5
+echo $ECHO_N "checking whether ln -s works... $ECHO_C" >&6
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+  echo "$as_me:$LINENO: result: no, using $LN_S" >&5
+echo "${ECHO_T}no, using $LN_S" >&6
+fi
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+        if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+          if test $ac_prog = install &&
+            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # AIX install.  It has an incompatible calling convention.
+            :
+          elif test $ac_prog = install &&
+            grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+            # program-specific install script used by HP pwplus--don't use.
+            :
+          else
+            ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+            break 3
+          fi
+        fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+
+
+echo "$as_me:$LINENO: checking for __attribute__" >&5
+echo $ECHO_N "checking for __attribute__... $ECHO_C" >&6
+if test "${ac_cv___attribute__+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <stdlib.h>
+
+int
+main ()
+{
+
+static void foo(void) __attribute__ ((noreturn));
+
+static void
+foo(void)
+{
+  exit(1);
+}
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv___attribute__=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv___attribute__=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+if test "$ac_cv___attribute__" = "yes"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___ATTRIBUTE__ 1
+_ACEOF
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv___attribute__" >&5
+echo "${ECHO_T}$ac_cv___attribute__" >&6
+
+
+   # CMU GUESS RUNPATH SWITCH
+  echo "$as_me:$LINENO: checking for runpath switch" >&5
+echo $ECHO_N "checking for runpath switch... $ECHO_C" >&6
+if test "${andrew_runpath_switch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+    # first, try -R
+    SAVE_LDFLAGS="${LDFLAGS}"
+    LDFLAGS="-R /usr/lib"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  andrew_runpath_switch="-R"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+       LDFLAGS="-Wl,-rpath,/usr/lib"
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  andrew_runpath_switch="-Wl,-rpath,"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+andrew_runpath_switch="none"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS="${SAVE_LDFLAGS}"
+
+fi
+echo "$as_me:$LINENO: result: $andrew_runpath_switch" >&5
+echo "${ECHO_T}$andrew_runpath_switch" >&6
+
+
+       save_LIBS="$LIBS"
+       LIB_SOCKET=""
+       echo "$as_me:$LINENO: checking for connect" >&5
+echo $ECHO_N "checking for connect... $ECHO_C" >&6
+if test "${ac_cv_func_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char connect (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_connect) || defined (__stub___connect)
+choke me
+#else
+char (*f) () = connect;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != connect;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_connect=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
+echo "${ECHO_T}$ac_cv_func_connect" >&6
+if test $ac_cv_func_connect = yes; then
+  :
+else
+  echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
+echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
+if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gethostbyname ();
+int
+main ()
+{
+gethostbyname ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_nsl_gethostbyname=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_nsl_gethostbyname=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
+echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
+if test $ac_cv_lib_nsl_gethostbyname = yes; then
+  LIB_SOCKET="-lnsl $LIB_SOCKET"
+fi
+
+               echo "$as_me:$LINENO: checking for connect in -lsocket" >&5
+echo $ECHO_N "checking for connect in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_connect+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char connect ();
+int
+main ()
+{
+connect ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_connect=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_connect=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_connect" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_connect" >&6
+if test $ac_cv_lib_socket_connect = yes; then
+  LIB_SOCKET="-lsocket $LIB_SOCKET"
+fi
+
+
+fi
+
+       LIBS="$LIB_SOCKET $save_LIBS"
+       echo "$as_me:$LINENO: checking for res_search" >&5
+echo $ECHO_N "checking for res_search... $ECHO_C" >&6
+if test "${ac_cv_func_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char res_search (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_res_search) || defined (__stub___res_search)
+choke me
+#else
+char (*f) () = res_search;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != res_search;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_res_search" >&5
+echo "${ECHO_T}$ac_cv_func_res_search" >&6
+if test $ac_cv_func_res_search = yes; then
+  :
+else
+  LIBS="-lresolv $LIB_SOCKET $save_LIBS"
+               cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#ifdef HAVE_ARPA_NAMESER_COMPAT_H
+#include <arpa/nameser_compat.h>
+#endif
+#include <resolv.h>
+int
+main ()
+{
+
+const char host[12]="openafs.org";
+u_char ans[1024];
+res_search( host, C_IN, T_MX, (u_char *)&ans, sizeof(ans));
+return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  LIB_SOCKET="-lresolv $LIB_SOCKET"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+
+fi
+
+       LIBS="$LIB_SOCKET $save_LIBS"
+
+
+for ac_func in dn_expand dns_lookup
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+       LIBS="$save_LIBS"
+
+
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+                  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+# Check whether --with-lib-subdir or --without-lib-subdir was given.
+if test "${with_lib_subdir+set}" = set; then
+  withval="$with_lib_subdir"
+
+fi;
+echo "$as_me:$LINENO: checking for long" >&5
+echo $ECHO_N "checking for long... $ECHO_C" >&6
+if test "${ac_cv_type_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((long *) 0)
+  return 0;
+if (sizeof (long))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_long=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_long=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_long" >&5
+echo "${ECHO_T}$ac_cv_type_long" >&6
+
+echo "$as_me:$LINENO: checking size of long" >&5
+echo $ECHO_N "checking size of long... $ECHO_C" >&6
+if test "${ac_cv_sizeof_long+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$ac_cv_type_long" = yes; then
+  # The cast to unsigned long works around a bug in the HP C Compiler
+  # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+  # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+  # This bug is HP SR number 8606223364.
+  if test "$cross_compiling" = yes; then
+  # Depending upon the size, compute the lo and hi bounds.
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr $ac_mid + 1`
+                    if test $ac_lo -le $ac_mid; then
+                      ac_lo= ac_hi=
+                      break
+                    fi
+                    ac_mid=`expr 2 '*' $ac_mid + 1`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_lo=$ac_mid; break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_hi=`expr '(' $ac_mid ')' - 1`
+                       if test $ac_mid -le $ac_hi; then
+                         ac_lo= ac_hi=
+                         break
+                       fi
+                       ac_mid=`expr 2 '*' $ac_mid`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo= ac_hi=
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  ac_mid=`expr '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo`
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(((long) (sizeof (long))) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_hi=$ac_mid
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_lo=`expr '(' $ac_mid ')' + 1`
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in
+?*) ac_cv_sizeof_long=$ac_lo;;
+'') { { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+else
+  if test "$cross_compiling" = yes; then
+  { { echo "$as_me:$LINENO: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run test program while cross compiling
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+long longval () { return (long) (sizeof (long)); }
+unsigned long ulongval () { return (long) (sizeof (long)); }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    exit (1);
+  if (((long) (sizeof (long))) < 0)
+    {
+      long i = longval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%ld\n", i);
+    }
+  else
+    {
+      unsigned long i = ulongval ();
+      if (i != ((long) (sizeof (long))))
+       exit (1);
+      fprintf (f, "%lu\n", i);
+    }
+  exit (ferror (f) || fclose (f) != 0);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_sizeof_long=`cat conftest.val`
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+{ { echo "$as_me:$LINENO: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute sizeof (long), 77
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.val
+else
+  ac_cv_sizeof_long=0
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_sizeof_long" >&5
+echo "${ECHO_T}$ac_cv_sizeof_long" >&6
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+echo "$as_me:$LINENO: checking what directory libraries are found in" >&5
+echo $ECHO_N "checking what directory libraries are found in... $ECHO_C" >&6
+if test "${ac_cv_cmu_lib_subdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  test "X$with_lib_subdir" = "Xyes" && with_lib_subdir=
+test "X$with_lib_subdir" = "Xno" && with_lib_subdir=
+if test "X$with_lib_subdir" = "X" ; then
+  ac_cv_cmu_lib_subdir=lib
+  if test $ac_cv_sizeof_long -eq 4 ; then
+    test -d /usr/lib32 && ac_cv_cmu_lib_subdir=lib32
+  fi
+  if test $ac_cv_sizeof_long -eq 8 ; then
+    test -d /usr/lib64 && ac_cv_cmu_lib_subdir=lib64
+  fi
+else
+  ac_cv_cmu_lib_subdir=$with_lib_subdir
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cmu_lib_subdir" >&5
+echo "${ECHO_T}$ac_cv_cmu_lib_subdir" >&6
+CMU_LIB_SUBDIR=$ac_cv_cmu_lib_subdir
+
+
+
+
+
+# Check whether --with-openssl or --without-openssl was given.
+if test "${with_openssl+set}" = set; then
+  withval="$with_openssl"
+  with_openssl=$withval
+else
+  with_openssl="yes"
+fi;
+
+       save_CPPFLAGS=$CPPFLAGS
+       save_LDFLAGS=$LDFLAGS
+
+       if test -d $with_openssl; then
+         CPPFLAGS="${CPPFLAGS} -I${with_openssl}/include"
+
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L${with_openssl}/$CMU_LIB_SUBDIR ${LDFLAGS}"
+  else
+       LDFLAGS="-L${with_openssl}/$CMU_LIB_SUBDIR $andrew_runpath_switch${with_openssl}/$CMU_LIB_SUBDIR ${LDFLAGS}"
+  fi
+
+       fi
+
+case "$with_openssl" in
+       no)
+         with_openssl="no";;
+       *)
+                                 LIB_RSAREF=""
+               echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lrsaref" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lrsaref... $ECHO_C" >&6
+if test "${ac_cv_lib_rsaref_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrsaref  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_rsaref_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rsaref_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rsaref_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_rsaref_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_rsaref_RSAPublicEncrypt = yes; then
+  cmu_have_rsaref=yes;
+                       echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lRSAglue" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lRSAglue... $ECHO_C" >&6
+if test "${ac_cv_lib_RSAglue_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lRSAglue  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_RSAglue_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_RSAglue_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_RSAglue_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_RSAglue_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_RSAglue_RSAPublicEncrypt = yes; then
+  LIB_RSAREF="-lRSAglue -lrsaref"
+else
+  LIB_RSAREF="-lrsaref"
+fi
+
+else
+  cmu_have_rsaref=no
+fi
+
+
+               if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/evp.h usability" >&5
+echo $ECHO_N "checking openssl/evp.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/evp.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/evp.h presence" >&5
+echo $ECHO_N "checking openssl/evp.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/evp.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/evp.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/evp.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/evp.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/evp.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/evp.h" >&5
+echo $ECHO_N "checking for openssl/evp.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_evp_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_evp_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_evp_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_evp_h" >&6
+
+fi
+if test $ac_cv_header_openssl_evp_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for EVP_DigestInit in -lcrypto" >&5
+echo $ECHO_N "checking for EVP_DigestInit in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_EVP_DigestInit+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char EVP_DigestInit ();
+int
+main ()
+{
+EVP_DigestInit ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_EVP_DigestInit=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_EVP_DigestInit=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_EVP_DigestInit" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_EVP_DigestInit" >&6
+if test $ac_cv_lib_crypto_EVP_DigestInit = yes; then
+  with_openssl="yes"
+else
+  with_openssl="no"
+fi
+
+else
+  with_openssl=no
+fi
+
+
+               ;;
+esac
+
+       if test "$with_openssl" != "no"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_OPENSSL
+_ACEOF
+
+       else
+               CPPFLAGS=$save_CPPFLAGS
+               LDFLAGS=$save_LDFLAGS
+       fi
+
+echo "$as_me:$LINENO: checking for OpenSSL" >&5
+echo $ECHO_N "checking for OpenSSL... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_openssl" >&5
+echo "${ECHO_T}$with_openssl" >&6
+
+
+
+# Check whether --with-des or --without-des was given.
+if test "${with_des+set}" = set; then
+  withval="$with_des"
+  with_des=$withval
+else
+  with_des=yes
+fi;
+
+LIB_DES=""
+if test "$with_des" != no; then
+  if test -d $with_des; then
+    CPPFLAGS="$CPPFLAGS -I${with_des}/include"
+    LDFLAGS="$LDFLAGS -L${with_des}/lib"
+  fi
+
+  if test "$with_openssl" != no; then
+        echo "$as_me:$LINENO: checking for des_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_des_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_des_cbc_encrypt = yes; then
+
+        if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+
+        if test "$with_des" = no; then
+      echo "$as_me:$LINENO: checking for DES_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for DES_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_DES_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char DES_cbc_encrypt ();
+int
+main ()
+{
+DES_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_DES_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_DES_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_DES_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_DES_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_DES_cbc_encrypt = yes; then
+
+        if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+    fi
+  fi
+
+  if test "$with_des" = no; then
+    echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes... $ECHO_C" >&6
+if test "${ac_cv_lib_des_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes";
+                                        with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+     echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes425" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes425... $ECHO_C" >&6
+if test "${ac_cv_lib_des425_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes425  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des425_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des425_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des425_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des425_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des425_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes425";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+     echo "$as_me:$LINENO: checking for des_cbc_encrypt in -ldes524" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -ldes524... $ECHO_C" >&6
+if test "${ac_cv_lib_des524_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldes524  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_des524_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_des524_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_des524_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_des524_des_cbc_encrypt" >&6
+if test $ac_cv_lib_des524_des_cbc_encrypt = yes; then
+  LIB_DES="-ldes524";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+  fi
+
+  if test "$with_des" = no; then
+
+            LIB_RSAREF=""
+    echo "$as_me:$LINENO: checking for RSAPublicEncrypt in -lrsaref" >&5
+echo $ECHO_N "checking for RSAPublicEncrypt in -lrsaref... $ECHO_C" >&6
+if test "${ac_cv_lib_rsaref_RSAPublicEncrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrsaref  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char RSAPublicEncrypt ();
+int
+main ()
+{
+RSAPublicEncrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_rsaref_RSAPublicEncrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rsaref_RSAPublicEncrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_rsaref_RSAPublicEncrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_rsaref_RSAPublicEncrypt" >&6
+if test $ac_cv_lib_rsaref_RSAPublicEncrypt = yes; then
+  LIB_RSAREF="-lRSAglue -lrsaref"; cmu_have_rsaref=yes
+else
+  cmu_have_rsaref=no
+fi
+
+
+    echo "$as_me:$LINENO: checking for des_cbc_encrypt in -lcrypto" >&5
+echo $ECHO_N "checking for des_cbc_encrypt in -lcrypto... $ECHO_C" >&6
+if test "${ac_cv_lib_crypto_des_cbc_encrypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypto $LIB_RSAREF $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char des_cbc_encrypt ();
+int
+main ()
+{
+des_cbc_encrypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypto_des_cbc_encrypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypto_des_cbc_encrypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypto_des_cbc_encrypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypto_des_cbc_encrypt" >&6
+if test $ac_cv_lib_crypto_des_cbc_encrypt = yes; then
+
+       if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking openssl/des.h usability" >&5
+echo $ECHO_N "checking openssl/des.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <openssl/des.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking openssl/des.h presence" >&5
+echo $ECHO_N "checking openssl/des.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <openssl/des.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: openssl/des.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: openssl/des.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: openssl/des.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: openssl/des.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for openssl/des.h" >&5
+echo $ECHO_N "checking for openssl/des.h... $ECHO_C" >&6
+if test "${ac_cv_header_openssl_des_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_openssl_des_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_openssl_des_h" >&5
+echo "${ECHO_T}$ac_cv_header_openssl_des_h" >&6
+
+fi
+if test $ac_cv_header_openssl_des_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_SSL_DES
+_ACEOF
+
+                                       LIB_DES="-lcrypto";
+                                       with_des=yes
+else
+  with_des=no
+fi
+
+
+else
+  with_des=no
+fi
+
+  fi
+fi
+
+if test "$with_des" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define WITH_DES
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+  # Check whether --enable-krb4 or --disable-krb4 was given.
+if test "${enable_krb4+set}" = set; then
+  enableval="$enable_krb4"
+  krb4=$enableval
+else
+  krb4=no
+fi;
+
+  if test "$krb4" != no; then
+
+echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+
+            if test -d ${krb4}; then
+       echo "$as_me:$LINENO: checking for Kerberos includes" >&5
+echo $ECHO_N "checking for Kerberos includes... $ECHO_C" >&6
+if test "${cyrus_krbinclude+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+         for krbhloc in include/kerberosIV include/kerberos include
+         do
+           if test -f ${krb4}/${krbhloc}/krb.h ; then
+             cyrus_krbinclude=${krb4}/${krbhloc}
+             break
+           fi
+         done
+
+fi
+echo "$as_me:$LINENO: result: $cyrus_krbinclude" >&5
+echo "${ECHO_T}$cyrus_krbinclude" >&6
+
+       if test -n "${cyrus_krbinclude}"; then
+         CPPFLAGS="$CPPFLAGS -I${cyrus_krbinclude}"
+       fi
+       LDFLAGS="$LDFLAGS -L$krb4/lib"
+    fi
+
+    if test "$with_des" != no; then
+      if test "${ac_cv_header_krb_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for krb.h" >&5
+echo $ECHO_N "checking for krb.h... $ECHO_C" >&6
+if test "${ac_cv_header_krb_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5
+echo "${ECHO_T}$ac_cv_header_krb_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking krb.h usability" >&5
+echo $ECHO_N "checking krb.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <krb.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking krb.h presence" >&5
+echo $ECHO_N "checking krb.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <krb.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: krb.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: krb.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: krb.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: krb.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: krb.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: krb.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for krb.h" >&5
+echo $ECHO_N "checking for krb.h... $ECHO_C" >&6
+if test "${ac_cv_header_krb_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_krb_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_krb_h" >&5
+echo "${ECHO_T}$ac_cv_header_krb_h" >&6
+
+fi
+if test $ac_cv_header_krb_h = yes; then
+
+        echo "$as_me:$LINENO: checking for com_err in -lcom_err" >&5
+echo $ECHO_N "checking for com_err in -lcom_err... $ECHO_C" >&6
+if test "${ac_cv_lib_com_err_com_err+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcom_err  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char com_err ();
+int
+main ()
+{
+com_err ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_com_err_com_err=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_com_err_com_err=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_com_err_com_err" >&5
+echo "${ECHO_T}$ac_cv_lib_com_err_com_err" >&6
+if test $ac_cv_lib_com_err_com_err = yes; then
+
+         echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb... $ECHO_C" >&6
+if test "${ac_cv_lib_krb_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb $LIB_DES -lcom_err $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb_krb_mk_priv" >&6
+if test $ac_cv_lib_krb_krb_mk_priv = yes; then
+  COM_ERR="-lcom_err"; SASL_KRB_LIB="-lkrb"; krb4lib="yes"
+else
+  krb4lib=no
+fi
+
+else
+
+         echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb... $ECHO_C" >&6
+if test "${ac_cv_lib_krb_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb $LIB_DES $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb_krb_mk_priv" >&6
+if test $ac_cv_lib_krb_krb_mk_priv = yes; then
+  COM_ERR=""; SASL_KRB_LIB="-lkrb"; krb4lib="yes"
+else
+  krb4lib=no
+fi
+
+fi
+
+else
+  krb4="no"
+fi
+
+
+
+      if test "$krb4" != "no" -a "$krb4lib" = "no"; then
+       echo "$as_me:$LINENO: checking for krb_mk_priv in -lkrb4" >&5
+echo $ECHO_N "checking for krb_mk_priv in -lkrb4... $ECHO_C" >&6
+if test "${ac_cv_lib_krb4_krb_mk_priv+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb4 $LIB_DES $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb_mk_priv ();
+int
+main ()
+{
+krb_mk_priv ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb4_krb_mk_priv=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb4_krb_mk_priv=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb4_krb_mk_priv" >&5
+echo "${ECHO_T}$ac_cv_lib_krb4_krb_mk_priv" >&6
+if test $ac_cv_lib_krb4_krb_mk_priv = yes; then
+  COM_ERR=""; SASL_KRB_LIB="-lkrb4"; krb4=yes
+else
+  krb4=no
+fi
+
+      fi
+      if test "$krb4" = no; then
+          { echo "$as_me:$LINENO: WARNING: No Kerberos V4 found" >&5
+echo "$as_me: WARNING: No Kerberos V4 found" >&2;}
+      fi
+    else
+      { echo "$as_me:$LINENO: WARNING: No DES library found for Kerberos V4 support" >&5
+echo "$as_me: WARNING: No DES library found for Kerberos V4 support" >&2;}
+      krb4=no
+    fi
+  fi
+
+  if test "$krb4" != no; then
+    cmu_save_LIBS="$LIBS"
+    LIBS="$LIBS $SASL_KRB_LIB"
+
+for ac_func in krb_get_err_text
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    LIBS="$cmu_save_LIBS"
+  fi
+
+  echo "$as_me:$LINENO: checking KERBEROS_V4" >&5
+echo $ECHO_N "checking KERBEROS_V4... $ECHO_C" >&6
+  if test "$krb4" != no; then
+    echo "$as_me:$LINENO: result: enabled" >&5
+echo "${ECHO_T}enabled" >&6
+    SASL_MECHS="$SASL_MECHS libkerberos4.la"
+    SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/kerberos4.c"
+    SASL_STATIC_OBJS="$SASL_STATIC_OBJS kerberos4.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_KERBEROS4
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_KRB
+_ACEOF
+
+    SASL_KRB_LIB="$SASL_KRB_LIB $LIB_DES $COM_ERR"
+  else
+    echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+  fi
+
+
+echo "$as_me:$LINENO: checking for crypt" >&5
+echo $ECHO_N "checking for crypt... $ECHO_C" >&6
+if test "${ac_cv_func_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char crypt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_crypt) || defined (__stub___crypt)
+choke me
+#else
+char (*f) () = crypt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != crypt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5
+echo "${ECHO_T}$ac_cv_func_crypt" >&6
+if test $ac_cv_func_crypt = yes; then
+  cmu_have_crypt=yes
+else
+  echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6
+if test $ac_cv_lib_crypt_crypt = yes; then
+  LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes
+else
+  cmu_have_crypt=no
+fi
+
+fi
+
+
+
+
+
+# Check whether --enable-gssapi or --disable-gssapi was given.
+if test "${enable_gssapi+set}" = set; then
+  enableval="$enable_gssapi"
+  gssapi=$enableval
+else
+  gssapi=yes
+fi;
+
+# Check whether --with-gss_impl or --without-gss_impl was given.
+if test "${with_gss_impl+set}" = set; then
+  withval="$with_gss_impl"
+  gss_impl=$withval
+else
+  gss_impl=auto
+fi;
+
+if test "$gssapi" != no; then
+  platform=
+  case "${host}" in
+    *-*-linux*)
+      platform=__linux
+      ;;
+    *-*-hpux*)
+      platform=__hpux
+      ;;
+    *-*-irix*)
+      platform=__irix
+      ;;
+    *-*-solaris2*)
+# When should we use __sunos?
+      platform=__solaris
+      ;;
+    *-*-aix*)
+      platform=__aix
+      ;;
+    *)
+      { echo "$as_me:$LINENO: WARNING: The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script" >&5
+echo "$as_me: WARNING: The system type is not recognized. If you believe that CyberSafe GSSAPI works on this platform, please update the configure script" >&2;}
+      if test "$gss_impl" = "cybersafe"; then
+        { { echo "$as_me:$LINENO: error: CyberSafe was forced, cannot continue as platform is not supported" >&5
+echo "$as_me: error: CyberSafe was forced, cannot continue as platform is not supported" >&2;}
+   { (exit 1); exit 1; }; }
+      fi
+      ;;
+  esac
+
+  cmu_saved_CPPFLAGS=$CPPFLAGS
+
+  if test -d ${gssapi}; then
+    CPPFLAGS="$CPPFLAGS -I$gssapi/include"
+# We want to keep -I in our CPPFLAGS, but only if we succeed
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    LDFLAGS="$LDFLAGS -L$gssapi/lib"
+
+    if test -n "$platform"; then
+      if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+        CPPFLAGS="$CPPFLAGS -D$platform"
+        if test -d "${gssapi}/appsec-sdk/include"; then
+          CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+        fi
+      fi
+    fi
+  fi
+  if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gssapi.h" >&5
+echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gssapi.h usability" >&5
+echo $ECHO_N "checking gssapi.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gssapi.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gssapi.h presence" >&5
+echo $ECHO_N "checking gssapi.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gssapi.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gssapi.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gssapi.h" >&5
+echo $ECHO_N "checking for gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gssapi_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_h" >&6
+
+fi
+if test $ac_cv_header_gssapi_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSSAPI_H
+_ACEOF
+
+else
+  if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gssapi/gssapi.h" >&5
+echo $ECHO_N "checking for gssapi/gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_gssapi_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gssapi/gssapi.h usability" >&5
+echo $ECHO_N "checking gssapi/gssapi.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gssapi/gssapi.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gssapi/gssapi.h presence" >&5
+echo $ECHO_N "checking gssapi/gssapi.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gssapi/gssapi.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gssapi/gssapi.h" >&5
+echo $ECHO_N "checking for gssapi/gssapi.h... $ECHO_C" >&6
+if test "${ac_cv_header_gssapi_gssapi_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gssapi_gssapi_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gssapi_gssapi_h" >&5
+echo "${ECHO_T}$ac_cv_header_gssapi_gssapi_h" >&6
+
+fi
+if test $ac_cv_header_gssapi_gssapi_h = yes; then
+  :
+else
+  { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - no include files found" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - no include files found" >&2;}; gssapi=no
+fi
+
+
+fi
+
+
+
+  CPPFLAGS=$cmu_saved_CPPFLAGS
+
+fi
+
+if test "$gssapi" != no; then
+  # We need to find out which gssapi implementation we are
+  # using. Supported alternatives are: MIT Kerberos 5,
+  # Heimdal Kerberos 5 (http://www.pdc.kth.se/heimdal),
+  # CyberSafe Kerberos 5 (http://www.cybersafe.com/)
+  # and Sun SEAM (http://wwws.sun.com/software/security/kerberos/)
+  #
+  # The choice is reflected in GSSAPIBASE_LIBS
+
+
+echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+  if test -d ${gssapi}; then
+     gssapi_dir="${gssapi}/lib"
+     GSSAPIBASE_LIBS="-L$gssapi_dir"
+     GSSAPIBASE_STATIC_LIBS="-L$gssapi_dir"
+  else
+     # FIXME: This is only used for building cyrus, and then only as
+     # a real hack.  it needs to be fixed.
+     gssapi_dir="/usr/local/lib"
+  fi
+
+  # Check a full link against the Heimdal libraries.
+  # If this fails, check a full link against the MIT libraries.
+  # If this fails, check a full link against the CyberSafe libraries.
+  # If this fails, check a full link against the Solaris 8 and up libgss.
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "heimdal"; then
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgssapi" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgssapi... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi ${GSSAPIBASE_LIBS} -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gssapi_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gssapi_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_gss_unwrap" >&6
+if test $ac_cv_lib_gssapi_gss_unwrap = yes; then
+  gss_impl="heimdal"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "mit"; then
+    # check for libkrb5support first
+    echo "$as_me:$LINENO: checking for krb5int_getspecific in -lkrb5support" >&5
+echo $ECHO_N "checking for krb5int_getspecific in -lkrb5support... $ECHO_C" >&6
+if test "${ac_cv_lib_krb5support_krb5int_getspecific+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lkrb5support ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char krb5int_getspecific ();
+int
+main ()
+{
+krb5int_getspecific ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_krb5support_krb5int_getspecific=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_krb5support_krb5int_getspecific=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_krb5support_krb5int_getspecific" >&5
+echo "${ECHO_T}$ac_cv_lib_krb5support_krb5int_getspecific" >&6
+if test $ac_cv_lib_krb5support_krb5int_getspecific = yes; then
+  K5SUP=-lkrb5support K5SUPSTATIC=$gssapi_dir/libkrb5support.a
+fi
+
+
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgssapi_krb5" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgssapi_krb5... $ECHO_C" >&6
+if test "${ac_cv_lib_gssapi_krb5_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgssapi_krb5 ${GSSAPIBASE_LIBS} -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP} ${LIB_SOCKET} $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gssapi_krb5_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gssapi_krb5_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gssapi_krb5_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gssapi_krb5_gss_unwrap" >&6
+if test $ac_cv_lib_gssapi_krb5_gss_unwrap = yes; then
+  gss_impl="mit"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  # For Cybersafe one has to set a platform define in order to make compilation work
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "cybersafe"; then
+
+    cmu_saved_CPPFLAGS=$CPPFLAGS
+    cmu_saved_GSSAPIBASE_LIBS=$GSSAPIBASE_LIBS
+# FIXME - Note that the libraries are in .../lib64 for 64bit kernels
+    if test -d "${gssapi}/appsec-rt/lib"; then
+      GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -L${gssapi}/appsec-rt/lib"
+    fi
+    CPPFLAGS="$CPPFLAGS -D$platform"
+    if test -d "${gssapi}/appsec-sdk/include"; then
+      CPPFLAGS="$CPPFLAGS -I${gssapi}/appsec-sdk/include"
+    fi
+
+    gss_failed=0
+
+# Check for CyberSafe with two libraries first, than fall back to a single
+# library (older CyberSafe)
+
+    unset ac_cv_lib_gss_csf_gss_acq_user
+    echo "$as_me:$LINENO: checking for csf_gss_acq_user in -lgss" >&5
+echo $ECHO_N "checking for csf_gss_acq_user in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_csf_gss_acq_user+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss ${GSSAPIBASE_LIBS} -lgss -lcstbk5 $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char csf_gss_acq_user ();
+int
+main ()
+{
+csf_gss_acq_user ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_csf_gss_acq_user=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_csf_gss_acq_user=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_csf_gss_acq_user" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_csf_gss_acq_user" >&6
+if test $ac_cv_lib_gss_csf_gss_acq_user = yes; then
+  gss_impl="cybersafe03"
+else
+  unset ac_cv_lib_gss_csf_gss_acq_user;
+                  echo "$as_me:$LINENO: checking for csf_gss_acq_user in -lgss" >&5
+echo $ECHO_N "checking for csf_gss_acq_user in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_csf_gss_acq_user+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss $GSSAPIBASE_LIBS -lgss $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char csf_gss_acq_user ();
+int
+main ()
+{
+csf_gss_acq_user ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_csf_gss_acq_user=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_csf_gss_acq_user=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_csf_gss_acq_user" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_csf_gss_acq_user" >&6
+if test $ac_cv_lib_gss_csf_gss_acq_user = yes; then
+  gss_impl="cybersafe"
+else
+  gss_failed=1
+fi
+
+fi
+
+
+    if test "$gss_failed" = "1"; then
+# Restore variables
+      GSSAPIBASE_LIBS=$cmu_saved_GSSAPIBASE_LIBS
+      CPPFLAGS=$cmu_saved_CPPFLAGS
+
+      if test "$gss_impl" != "auto"; then
+        gss_impl="failed"
+      fi
+    fi
+  fi
+
+  if test "$gss_impl" = "auto" -o "$gss_impl" = "seam"; then
+    gss_failed=0
+    echo "$as_me:$LINENO: checking for gss_unwrap in -lgss" >&5
+echo $ECHO_N "checking for gss_unwrap in -lgss... $ECHO_C" >&6
+if test "${ac_cv_lib_gss_gss_unwrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgss -lgss $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gss_unwrap ();
+int
+main ()
+{
+gss_unwrap ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gss_gss_unwrap=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gss_gss_unwrap=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gss_gss_unwrap" >&5
+echo "${ECHO_T}$ac_cv_lib_gss_gss_unwrap" >&6
+if test $ac_cv_lib_gss_gss_unwrap = yes; then
+  gss_impl="seam"
+else
+  gss_failed=1
+fi
+
+    if test "$gss_impl" != "auto" -a "$gss_failed" = "1"; then
+      gss_impl="failed"
+    fi
+  fi
+
+  if test "$gss_impl" = "mit"; then
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err ${K5SUP}"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_LIBS $gssapi_dir/libgssapi_krb5.a $gssapi_dir/libkrb5.a $gssapi_dir/libk5crypto.a $gssapi_dir/libcom_err.a ${K5SUPSTATIC}"
+  elif test "$gss_impl" = "heimdal"; then
+    CPPFLAGS="$CPPFLAGS -DKRB5_HEIMDAL"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgssapi -lkrb5 -lasn1 -lroken ${LIB_CRYPT} ${LIB_DES} -lcom_err"
+    GSSAPIBASE_STATIC_LIBS="$GSSAPIBASE_STATIC_LIBS $gssapi_dir/libgssapi.a $gssapi_dir/libkrb5.a $gssapi_dir/libasn1.a $gssapi_dir/libroken.a $gssapi_dir/libcom_err.a ${LIB_CRYPT}"
+  elif test "$gss_impl" = "cybersafe03"; then
+# Version of CyberSafe with two libraries
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss -lcstbk5"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "cybersafe"; then
+    CPPFLAGS="$CPPFLAGS -D$platform -I${gssapi}/appsec-sdk/include"
+    GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lgss"
+    # there is no static libgss for CyberSafe
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "seam"; then
+    GSSAPIBASE_LIBS=-lgss
+    # there is no static libgss on Solaris 8 and up
+    GSSAPIBASE_STATIC_LIBS=none
+  elif test "$gss_impl" = "failed"; then
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - specified library not found" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - specified library not found" >&2;}
+  else
+    gssapi="no"
+    GSSAPIBASE_LIBS=
+    GSSAPIBASE_STATIC_LIBS=
+    { echo "$as_me:$LINENO: WARNING: Disabling GSSAPI - no library" >&5
+echo "$as_me: WARNING: Disabling GSSAPI - no library" >&2;}
+  fi
+fi
+
+#
+# Cybersafe defines both GSS_C_NT_HOSTBASED_SERVICE and GSS_C_NT_USER_NAME
+# in gssapi\rfckrb5.h
+#
+if test "$gssapi" != "no"; then
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_HOSTBASED_SERVICE
+                    hostbased_service_gss_nt_yes
+                  #endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "hostbased_service_gss_nt_yes" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: Cybersafe define not found" >&5
+echo "$as_me: WARNING: Cybersafe define not found" >&2;}
+fi
+rm -f conftest*
+
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_HOSTBASED_SERVICE" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_HOSTBASED_SERVICE
+_ACEOF
+
+fi
+rm -f conftest*
+
+  fi
+
+  if test "$gss_impl" = "cybersafe" -o "$gss_impl" = "cybersafe03"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+                  #ifdef GSS_C_NT_USER_NAME
+                   user_name_yes_gss_nt
+                  #endif
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "user_name_yes_gss_nt" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: WARNING: Cybersafe define not found" >&5
+echo "$as_me: WARNING: Cybersafe define not found" >&2;}
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_h" = "yes"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_USER_NAME" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+fi
+rm -f conftest*
+
+  elif test "$ac_cv_header_gssapi_gssapi_h"; then
+    cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gssapi/gssapi.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "GSS_C_NT_USER_NAME" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSS_C_NT_USER_NAME
+_ACEOF
+
+fi
+rm -f conftest*
+
+  fi
+fi
+
+GSSAPI_LIBS=""
+echo "$as_me:$LINENO: checking GSSAPI" >&5
+echo $ECHO_N "checking GSSAPI... $ECHO_C" >&6
+if test "$gssapi" != no; then
+  echo "$as_me:$LINENO: result: with implementation ${gss_impl}" >&5
+echo "${ECHO_T}with implementation ${gss_impl}" >&6
+  echo "$as_me:$LINENO: checking for res_search in -lresolv" >&5
+echo $ECHO_N "checking for res_search in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_res_search+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char res_search ();
+int
+main ()
+{
+res_search ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_res_search=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_res_search=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_res_search" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_res_search" >&6
+if test $ac_cv_lib_resolv_res_search = yes; then
+  GSSAPIBASE_LIBS="$GSSAPIBASE_LIBS -lresolv"
+fi
+
+  SASL_MECHS="$SASL_MECHS libgssapiv2.la"
+  SASL_STATIC_OBJS="$SASL_STATIC_OBJS gssapi.o"
+  SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/gssapi.c"
+
+  cmu_save_LIBS="$LIBS"
+  LIBS="$LIBS $GSSAPIBASE_LIBS"
+
+for ac_func in gsskrb5_register_acceptor_identity
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+  LIBS="$cmu_save_LIBS"
+else
+  echo "$as_me:$LINENO: result: disabled" >&5
+echo "${ECHO_T}disabled" >&6
+fi
+
+
+
+
+if test "$gssapi" != no; then
+       if test "$gss_impl" = "heimdal"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define KRB5_HEIMDAL
+_ACEOF
+
+       fi
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GSSAPI
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for crypt" >&5
+echo $ECHO_N "checking for crypt... $ECHO_C" >&6
+if test "${ac_cv_func_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char crypt (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_crypt) || defined (__stub___crypt)
+choke me
+#else
+char (*f) () = crypt;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != crypt;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_crypt" >&5
+echo "${ECHO_T}$ac_cv_func_crypt" >&6
+if test $ac_cv_func_crypt = yes; then
+  cmu_have_crypt=yes
+else
+  echo "$as_me:$LINENO: checking for crypt in -lcrypt" >&5
+echo $ECHO_N "checking for crypt in -lcrypt... $ECHO_C" >&6
+if test "${ac_cv_lib_crypt_crypt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char crypt ();
+int
+main ()
+{
+crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_crypt_crypt=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_crypt_crypt=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_crypt" >&5
+echo "${ECHO_T}$ac_cv_lib_crypt_crypt" >&6
+if test $ac_cv_lib_crypt_crypt = yes; then
+  LIB_CRYPT="-lcrypt"; cmu_have_crypt=yes
+else
+  cmu_have_crypt=no
+fi
+
+fi
+
+
+
+
+# Check whether --enable-sia or --disable-sia was given.
+if test "${enable_sia+set}" = set; then
+  enableval="$enable_sia"
+  sia=$enableval
+else
+  sia=no
+fi;
+LIB_SIA=""
+if test "$sia" != no; then
+  if test -f /etc/sia/matrix.conf; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SIA
+_ACEOF
+
+    LIB_SIA="-lsecurity -ldb -lm -laud"
+  else
+    { { echo "$as_me:$LINENO: error: No support for SIA found" >&5
+echo "$as_me: error: No support for SIA found" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+
+# Check whether --enable-auth-sasldb or --disable-auth-sasldb was given.
+if test "${enable_auth_sasldb+set}" = set; then
+  enableval="$enable_auth_sasldb"
+  authsasldb=$enableval
+else
+  authsasldb=no
+fi;
+if test "$authsasldb" != no; then
+  if test ! -d "../sasldb"; then
+     echo "ERROR: Cannot build sasldb module outside of the full SASL source tree."
+     exit 0;
+  fi
+
+cat >>confdefs.h <<\_ACEOF
+#define AUTH_SASLDB
+_ACEOF
+
+
+
+# Check whether --with-dbpath or --without-dbpath was given.
+if test "${with_dbpath+set}" = set; then
+  withval="$with_dbpath"
+  dbpath=$withval
+else
+  dbpath=/etc/sasldb2
+fi;
+echo "$as_me:$LINENO: checking DB path to use" >&5
+echo $ECHO_N "checking DB path to use... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $dbpath" >&5
+echo "${ECHO_T}$dbpath" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define SASL_DB_PATH "$dbpath"
+_ACEOF
+
+
+cmu_save_LIBS="$LIBS"
+
+# Check whether --with-dblib or --without-dblib was given.
+if test "${with_dblib+set}" = set; then
+  withval="$with_dblib"
+  dblib=$withval
+else
+  dblib=auto_detect
+fi;
+
+
+
+# Check whether --with-bdb-libdir or --without-bdb-libdir was given.
+if test "${with_bdb_libdir+set}" = set; then
+  withval="$with_bdb_libdir"
+  with_bdb_lib=$withval
+else
+   test "${with_bdb_lib+set}" = set || with_bdb_lib=none
+fi;
+
+# Check whether --with-bdb-incdir or --without-bdb-incdir was given.
+if test "${with_bdb_incdir+set}" = set; then
+  withval="$with_bdb_incdir"
+  with_bdb_inc=$withval
+else
+   test "${with_bdb_inc+set}" = set || with_bdb_inc=none
+fi;
+
+
+SASL_DB_LIB=""
+
+case "$dblib" in
+  berkeley)
+
+
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+                       if test "${ac_cv_header_db_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking db.h usability" >&5
+echo $ECHO_N "checking db.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <db.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking db.h presence" >&5
+echo $ECHO_N "checking db.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: db.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: db.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: db.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_db_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+
+fi
+if test $ac_cv_header_db_h = yes; then
+
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD}"
+  else
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_create(NULL, NULL, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_open(NULL, 0, 0, 0, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+
+else
+  dblib="no"
+fi
+
+
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+
+       CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+       SASL_DB_INC=$BDB_INCADD
+       SASL_DB_LIB="${BDB_LIBADD}"
+       ;;
+  gdbm)
+
+# Check whether --with-gdbm or --without-gdbm was given.
+if test "${with_gdbm+set}" = set; then
+  withval="$with_gdbm"
+  with_gdbm="${withval}"
+fi;
+
+        case "$with_gdbm" in
+           ""|yes)
+               if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gdbm.h usability" >&5
+echo $ECHO_N "checking gdbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gdbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gdbm.h presence" >&5
+echo $ECHO_N "checking gdbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gdbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gdbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gdbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gdbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+
+fi
+if test $ac_cv_header_gdbm_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for gdbm_open in -lgdbm" >&5
+echo $ECHO_N "checking for gdbm_open in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_gdbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdbm_open ();
+int
+main ()
+{
+gdbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gdbm_gdbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_gdbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gdbm_gdbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_gdbm_open" >&6
+if test $ac_cv_lib_gdbm_gdbm_open = yes; then
+  SASL_DB_LIB="-lgdbm"
+else
+  dblib="no"
+fi
+
+else
+  dblib="no"
+fi
+
+
+               ;;
+           *)
+               if test -d $with_gdbm; then
+                 CPPFLAGS="${CPPFLAGS} -I${with_gdbm}/include"
+                 LDFLAGS="${LDFLAGS} -L${with_gdbm}/lib"
+                 SASL_DB_LIB="-lgdbm"
+               else
+                 with_gdbm="no"
+               fi
+       esac
+       ;;
+  ndbm)
+                       if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking ndbm.h usability" >&5
+echo $ECHO_N "checking ndbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <ndbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking ndbm.h presence" >&5
+echo $ECHO_N "checking ndbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ndbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: ndbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: ndbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_ndbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+
+fi
+if test $ac_cv_header_ndbm_h = yes; then
+
+                       echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
+echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ndbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
+if test $ac_cv_lib_ndbm_dbm_open = yes; then
+  SASL_DB_LIB="-lndbm"
+else
+
+                               echo "$as_me:$LINENO: checking for dbm_open" >&5
+echo $ECHO_N "checking for dbm_open... $ECHO_C" >&6
+if test "${ac_cv_func_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dbm_open (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
+choke me
+#else
+char (*f) () = dbm_open;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dbm_open;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_func_dbm_open" >&6
+if test $ac_cv_func_dbm_open = yes; then
+  :
+else
+  dblib="no"
+fi
+
+fi
+
+else
+  dblib="no"
+fi
+
+
+       ;;
+  auto_detect)
+
+
+
+       cmu_save_CPPFLAGS=$CPPFLAGS
+
+       if test -d $with_bdb_inc; then
+           CPPFLAGS="$CPPFLAGS -I$with_bdb_inc"
+           BDB_INCADD="-I$with_bdb_inc"
+       else
+           BDB_INCADD=""
+       fi
+
+                       if test "${ac_cv_header_db_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking db.h usability" >&5
+echo $ECHO_N "checking db.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <db.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking db.h presence" >&5
+echo $ECHO_N "checking db.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: db.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: db.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: db.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: db.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: db.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: db.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for db.h" >&5
+echo $ECHO_N "checking for db.h... $ECHO_C" >&6
+if test "${ac_cv_header_db_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_db_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_db_h" >&5
+echo "${ECHO_T}$ac_cv_header_db_h" >&6
+
+fi
+if test $ac_cv_header_db_h = yes; then
+
+       BDB_SAVE_LDFLAGS=$LDFLAGS
+
+       if test -d $with_bdb_lib; then
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L$with_bdb_lib ${LDFLAGS} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+
+  # this is CMU ADD LIBPATH TO
+  if test "$andrew_runpath_switch" = "none" ; then
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD}"
+  else
+       BDB_LIBADD="-L$with_bdb_lib ${BDB_LIBADD} $andrew_runpath_switch$with_bdb_lib"
+  fi
+
+       else
+           BDB_LIBADD=""
+       fi
+
+       saved_LIBS=$LIBS
+        for dbname in db-4.4 db4.4 db44 db-4.3 db4.3 db43 db-4.2 db4.2 db42 db-4.1 db4.1 db41 db-4.0 db4.0 db-4 db40 db4 db-3.3 db3.3 db33 db-3.2 db3.2 db32 db-3.1 db3.1 db31 db-3 db30 db3 db
+          do
+           LIBS="$saved_LIBS -l$dbname"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_create(NULL, NULL, 0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -l$dbname"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+           if test "$dblib" = "berkeley"; then break; fi
+          done
+        if test "$dblib" = "no"; then
+           LIBS="$saved_LIBS -ldb"
+           cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <db.h>
+int
+main ()
+{
+db_open(NULL, 0, 0, 0, NULL, NULL, NULL);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  BDB_LIBADD="$BDB_LIBADD -ldb"; dblib="berkeley"; dbname=db
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+dblib="no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+        fi
+       LIBS=$saved_LIBS
+
+       LDFLAGS=$BDB_SAVE_LDFLAGS
+
+else
+  dblib="no"
+fi
+
+
+
+       CPPFLAGS=$cmu_save_CPPFLAGS
+
+       if test "$dblib" = no; then
+                 if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking ndbm.h usability" >&5
+echo $ECHO_N "checking ndbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <ndbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking ndbm.h presence" >&5
+echo $ECHO_N "checking ndbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ndbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: ndbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: ndbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: ndbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: ndbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: ndbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for ndbm.h" >&5
+echo $ECHO_N "checking for ndbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_ndbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_ndbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_ndbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_ndbm_h" >&6
+
+fi
+if test $ac_cv_header_ndbm_h = yes; then
+
+               echo "$as_me:$LINENO: checking for dbm_open in -lndbm" >&5
+echo $ECHO_N "checking for dbm_open in -lndbm... $ECHO_C" >&6
+if test "${ac_cv_lib_ndbm_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lndbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+int
+main ()
+{
+dbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ndbm_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ndbm_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ndbm_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_ndbm_dbm_open" >&6
+if test $ac_cv_lib_ndbm_dbm_open = yes; then
+  dblib="ndbm"; SASL_DB_LIB="-lndbm"
+else
+  dblib="weird"
+fi
+
+else
+  dblib="no"
+fi
+
+
+         if test "$dblib" = "weird"; then
+                       echo "$as_me:$LINENO: checking for dbm_open" >&5
+echo $ECHO_N "checking for dbm_open... $ECHO_C" >&6
+if test "${ac_cv_func_dbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dbm_open (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char dbm_open ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
+choke me
+#else
+char (*f) () = dbm_open;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dbm_open;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_dbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dbm_open" >&5
+echo "${ECHO_T}$ac_cv_func_dbm_open" >&6
+if test $ac_cv_func_dbm_open = yes; then
+  dblib="ndbm"
+else
+  dblib="no"
+fi
+
+         fi
+
+         if test "$dblib" = no; then
+                           if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking gdbm.h usability" >&5
+echo $ECHO_N "checking gdbm.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <gdbm.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking gdbm.h presence" >&5
+echo $ECHO_N "checking gdbm.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <gdbm.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: gdbm.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: gdbm.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: gdbm.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: gdbm.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: gdbm.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for gdbm.h" >&5
+echo $ECHO_N "checking for gdbm.h... $ECHO_C" >&6
+if test "${ac_cv_header_gdbm_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_gdbm_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_gdbm_h" >&5
+echo "${ECHO_T}$ac_cv_header_gdbm_h" >&6
+
+fi
+if test $ac_cv_header_gdbm_h = yes; then
+
+               echo "$as_me:$LINENO: checking for gdbm_open in -lgdbm" >&5
+echo $ECHO_N "checking for gdbm_open in -lgdbm... $ECHO_C" >&6
+if test "${ac_cv_lib_gdbm_gdbm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lgdbm  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char gdbm_open ();
+int
+main ()
+{
+gdbm_open ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_gdbm_gdbm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_gdbm_gdbm_open=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_gdbm_gdbm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_gdbm_gdbm_open" >&6
+if test $ac_cv_lib_gdbm_gdbm_open = yes; then
+  dblib="gdbm";
+                                            SASL_DB_LIB="-lgdbm"
+else
+  dblib="no"
+fi
+
+else
+  dblib="no"
+fi
+
+
+         fi
+       else
+                 CPPFLAGS="${CPPFLAGS} ${BDB_INCADD}"
+         SASL_DB_INC=$BDB_INCADD
+          SASL_DB_LIB="${BDB_LIBADD}"
+       fi
+       ;;
+  none)
+       ;;
+  no)
+       ;;
+  *)
+       { echo "$as_me:$LINENO: WARNING: Bad DB library implementation specified;" >&5
+echo "$as_me: WARNING: Bad DB library implementation specified;" >&2;}
+       { { echo "$as_me:$LINENO: error: Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"" >&5
+echo "$as_me: error: Use either \"berkeley\", \"gdbm\", \"ndbm\" or \"none\"" >&2;}
+   { (exit 1); exit 1; }; }
+       dblib=no
+       ;;
+esac
+LIBS="$cmu_save_LIBS"
+
+echo "$as_me:$LINENO: checking DB library to use" >&5
+echo $ECHO_N "checking DB library to use... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $dblib" >&5
+echo "${ECHO_T}$dblib" >&6
+
+SASL_DB_BACKEND="db_${dblib}.lo"
+SASL_DB_BACKEND_STATIC="db_${dblib}.o allockey.o"
+SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_${dblib}.c ../sasldb/allockey.c"
+SASL_DB_UTILS="saslpasswd2 sasldblistusers2"
+SASL_DB_MANS="saslpasswd2.8 sasldblistusers2.8"
+
+case "$dblib" in
+  gdbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_GDBM
+_ACEOF
+
+    ;;
+  ndbm)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_NDBM
+_ACEOF
+
+    ;;
+  berkeley)
+    SASL_MECHS="$SASL_MECHS libsasldb.la"
+
+cat >>confdefs.h <<\_ACEOF
+#define SASL_BERKELEYDB
+_ACEOF
+
+    ;;
+  *)
+    { echo "$as_me:$LINENO: WARNING: Disabling SASL authentication database support" >&5
+echo "$as_me: WARNING: Disabling SASL authentication database support" >&2;}
+            SASL_DB_BACKEND="db_none.lo"
+    SASL_DB_BACKEND_STATIC="db_none.o"
+    SASL_DB_BACKEND_STATIC_SRCS="../sasldb/db_none.c"
+    SASL_DB_UTILS=""
+    SASL_DB_MANS=""
+    SASL_DB_LIB=""
+    ;;
+esac
+
+if test "$enable_static" = yes; then
+    if test "$dblib" != "none"; then
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS ../plugins/sasldb.c $SASL_DB_BACKEND_STATIC_SRCS"
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS sasldb.o $SASL_DB_BACKEND_STATIC"
+
+cat >>confdefs.h <<\_ACEOF
+#define STATIC_SASLDB
+_ACEOF
+
+    else
+      SASL_STATIC_OBJS="$SASL_STATIC_OBJS $SASL_DB_BACKEND_STATIC"
+      SASL_STATIC_SRCS="$SASL_STATIC_SRCS $SASL_DB_BACKEND_STATIC_SRCS"
+    fi
+fi
+
+
+
+
+
+
+
+
+  SASL_DB_LIB="$SASL_DB_LIB ../sasldb/.libs/libsasldb.al"
+fi
+
+# Check whether --enable-httpform or --disable-httpform was given.
+if test "${enable_httpform+set}" = set; then
+  enableval="$enable_httpform"
+  httpform=$enableval
+else
+  httpform=no
+fi;
+if test "$httpform" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_HTTPFORM
+_ACEOF
+
+fi
+
+
+# Check whether --with-pam or --without-pam was given.
+if test "${with_pam+set}" = set; then
+  withval="$with_pam"
+  with_pam=$withval
+else
+  with_pam=yes
+fi;
+if test "$with_pam" != no; then
+  if test -d $with_pam; then
+    CPPFLAGS="$CPPFLAGS -I${with_pam}/include"
+    LDFLAGS="$LDFLAGS -L${with_pam}/lib"
+  fi
+  cmu_save_LIBS="$LIBS"
+  echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5
+echo $ECHO_N "checking for pam_start in -lpam... $ECHO_C" >&6
+if test "${ac_cv_lib_pam_pam_start+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpam $SASL_DL_LIB $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char pam_start ();
+int
+main ()
+{
+pam_start ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_pam_pam_start=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pam_pam_start=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_pam_pam_start" >&5
+echo "${ECHO_T}$ac_cv_lib_pam_pam_start" >&6
+if test $ac_cv_lib_pam_pam_start = yes; then
+
+         if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+  echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking security/pam_appl.h usability" >&5
+echo $ECHO_N "checking security/pam_appl.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <security/pam_appl.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking security/pam_appl.h presence" >&5
+echo $ECHO_N "checking security/pam_appl.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <security/pam_appl.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: security/pam_appl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: security/pam_appl.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: security/pam_appl.h: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: security/pam_appl.h: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for security/pam_appl.h" >&5
+echo $ECHO_N "checking for security/pam_appl.h... $ECHO_C" >&6
+if test "${ac_cv_header_security_pam_appl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_security_pam_appl_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_security_pam_appl_h" >&5
+echo "${ECHO_T}$ac_cv_header_security_pam_appl_h" >&6
+
+fi
+if test $ac_cv_header_security_pam_appl_h = yes; then
+  :
+else
+  with_pam=no
+fi
+
+
+else
+  with_pam=no
+fi
+
+  LIBS="$cmu_save_LIBS"
+fi
+
+
+# Check whether --with-ipctype or --without-ipctype was given.
+if test "${with_ipctype+set}" = set; then
+  withval="$with_ipctype"
+  with_ipctype=$withval
+else
+  with_ipctype="unix"
+fi;
+MAIN_COMPAT_OBJ="saslauthd-${with_ipctype}.o"
+
+if test "$with_ipctype" = "doors"; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DOORS
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define SASLAUTHD_THREADED
+_ACEOF
+
+  LIBS="$LIBS -ldoor -lpthread"
+fi
+
+echo "$as_me:$LINENO: checking for PAM support" >&5
+echo $ECHO_N "checking for PAM support... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $with_pam" >&5
+echo "${ECHO_T}$with_pam" >&6
+LIB_PAM=""
+if test "$with_pam" != no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PAM
+_ACEOF
+
+  LIB_PAM="-lpam"
+fi
+
+
+
+echo "$as_me:$LINENO: checking for inet_aton in -lresolv" >&5
+echo $ECHO_N "checking for inet_aton in -lresolv... $ECHO_C" >&6
+if test "${ac_cv_lib_resolv_inet_aton+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char inet_aton ();
+int
+main ()
+{
+inet_aton ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_resolv_inet_aton=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_resolv_inet_aton=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_inet_aton" >&5
+echo "${ECHO_T}$ac_cv_lib_resolv_inet_aton" >&6
+if test $ac_cv_lib_resolv_inet_aton = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRESOLV 1
+_ACEOF
+
+  LIBS="-lresolv $LIBS"
+
+fi
+
+
+echo "$as_me:$LINENO: checking to include LDAP support" >&5
+echo $ECHO_N "checking to include LDAP support... $ECHO_C" >&6
+
+# Check whether --with-ldap or --without-ldap was given.
+if test "${with_ldap+set}" = set; then
+  withval="$with_ldap"
+  with_ldap=$withval
+else
+  with_ldap=no
+fi;
+echo "$as_me:$LINENO: result: $with_ldap" >&5
+echo "${ECHO_T}$with_ldap" >&6
+
+if test -d $with_ldap; then
+    CPPFLAGS="$CPPFLAGS -I${with_ldap}/include"
+
+  # this is CMU ADD LIBPATH
+  if test "$andrew_runpath_switch" = "none" ; then
+       LDFLAGS="-L${with_ldap}/lib ${LDFLAGS}"
+  else
+       LDFLAGS="-L${with_ldap}/lib $andrew_runpath_switch${with_ldap}/lib ${LDFLAGS}"
+  fi
+
+fi
+
+LDAP_LIBS=""
+if test "$with_ldap" != no; then
+  echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5
+echo $ECHO_N "checking for ldap_initialize in -lldap... $ECHO_C" >&6
+if test "${ac_cv_lib_ldap_ldap_initialize+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lldap -llber $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ldap_initialize ();
+int
+main ()
+{
+ldap_initialize ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ldap_ldap_initialize=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ldap_ldap_initialize=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5
+echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6
+if test $ac_cv_lib_ldap_ldap_initialize = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LDAP
+_ACEOF
+
+                                        LDAP_LIBS="-lldap -llber"
+                                       if test "$with_openssl" != "no"; then
+                                           LDAP_LIBS="$LDAP_LIBS -lcrypto $LIB_RSAREF"
+                                       fi
+fi
+
+
+fi
+
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+                   (('a' <= (c) && (c) <= 'i') \
+                     || ('j' <= (c) && (c) <= 'r') \
+                     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+        || toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6
+if test "${ac_cv_header_sys_wait_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_sys_wait_h=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
+echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
+if test $ac_cv_header_sys_wait_h = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SYS_WAIT_H 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
+echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
+if test "${ac_cv_header_time+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_time=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_time=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
+echo "${ECHO_T}$ac_cv_header_time" >&6
+if test $ac_cv_header_time = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define TIME_WITH_SYS_TIME 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+
+
+
+for ac_header in crypt.h fcntl.h krb5.h strings.h syslog.h unistd.h sys/time.h sys/uio.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------ ##
+## Report this to bug-autoconf@gnu.org. ##
+## ------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
+echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
+if test "${ac_cv_c_const+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset x;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *ccp;
+  char **p;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  ccp = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++ccp;
+  p = (char**) ccp;
+  ccp = (char const *const *) p;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+  }
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_const=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_const=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
+echo "${ECHO_T}$ac_cv_c_const" >&6
+if test $ac_cv_c_const = no; then
+
+cat >>confdefs.h <<\_ACEOF
+#define const
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for pid_t" >&5
+echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
+if test "${ac_cv_type_pid_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((pid_t *) 0)
+  return 0;
+if (sizeof (pid_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_pid_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_pid_t=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
+echo "${ECHO_T}$ac_cv_type_pid_t" >&6
+if test $ac_cv_type_pid_t = yes; then
+  :
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+
+LTLIBOBJS=`echo "$LIBOBJS" | sed 's,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,'`
+
+
+echo "$as_me:$LINENO: checking whether $CC implements __func__" >&5
+echo $ECHO_N "checking whether $CC implements __func__... $ECHO_C" >&6
+if test "${have_func+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+printf("%s", __func__);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_func=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_func=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+
+echo "$as_me:$LINENO: result: $have_func" >&5
+echo "${ECHO_T}$have_func" >&6
+if test "$have_func" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FUNC
+_ACEOF
+
+else
+       echo "$as_me:$LINENO: checking whether $CC implements __PRETTY_FUNCTION__" >&5
+echo $ECHO_N "checking whether $CC implements __PRETTY_FUNCTION__... $ECHO_C" >&6
+       if test "${have_pretty_function+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+printf("%s", __PRETTY_FUNCTION__);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_pretty_function=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_pretty_function=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+
+       echo "$as_me:$LINENO: result: $have_pretty_function" >&5
+echo "${ECHO_T}$have_pretty_function" >&6
+       if test "$have_pretty_function" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PRETTY_FUNCTION
+_ACEOF
+
+       else
+               echo "$as_me:$LINENO: checking whether $CC implements __FUNCTION__" >&5
+echo $ECHO_N "checking whether $CC implements __FUNCTION__... $ECHO_C" >&6
+               if test "${have_function+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+printf("%s", __FUNCTION__);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  have_function=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+have_function=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+
+               echo "$as_me:$LINENO: result: $have_function" >&5
+echo "${ECHO_T}$have_function" >&6
+               if test "$have_function" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_FUNCTION
+_ACEOF
+
+               fi
+       fi
+fi
+
+echo "$as_me:$LINENO: checking return type of signal handlers" >&5
+echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
+if test "${ac_cv_type_signal+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+# undef signal
+#endif
+#ifdef __cplusplus
+extern "C" void (*signal (int, void (*)(int)))(int);
+#else
+void (*signal ()) ();
+#endif
+
+int
+main ()
+{
+int i;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_signal=void
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_signal=int
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
+echo "${ECHO_T}$ac_cv_type_signal" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define RETSIGTYPE $ac_cv_type_signal
+_ACEOF
+
+
+
+
+
+
+for ac_func in gethostname mkdir socket strdup
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in getspnam getuserpw
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+ break
+fi
+done
+
+
+
+for ac_func in strlcat strlcpy
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+char (*f) () = $ac_func;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != $ac_func;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+if test $ac_cv_func_getspnam = yes; then
+       echo "$as_me:$LINENO: checking if getpwnam_r/getspnam_r take 5 arguments" >&5
+echo $ECHO_N "checking if getpwnam_r/getspnam_r take 5 arguments... $ECHO_C" >&6
+       cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <shadow.h>
+
+int
+main ()
+{
+
+struct passwd *pw;
+struct passwd pwbuf;
+char pwdata[512];
+(void) getpwnam_r("bin", &pwbuf, pwdata, sizeof(pwdata), &pw);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define GETXXNAM_R_5ARG 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+
+GETADDRINFOOBJS=""
+sasl_cv_getaddrinfo=no
+
+echo "$as_me:$LINENO: checking for getaddrinfo" >&5
+echo $ECHO_N "checking for getaddrinfo... $ECHO_C" >&6
+if test "${ac_cv_func_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getaddrinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getaddrinfo) || defined (__stub___getaddrinfo)
+choke me
+#else
+char (*f) () = getaddrinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getaddrinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getaddrinfo" >&6
+if test $ac_cv_func_getaddrinfo = yes; then
+    ac_cv_lib_socket_getaddrinfo=no
+  ac_cv_lib_inet6_getaddrinfo=no
+
+else
+    echo "$as_me:$LINENO: checking for getaddrinfo in -lsocket" >&5
+echo $ECHO_N "checking for getaddrinfo in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+int
+main ()
+{
+getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_getaddrinfo" >&6
+if test $ac_cv_lib_socket_getaddrinfo = yes; then
+      LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_getaddrinfo=no
+
+else
+      echo "$as_me:$LINENO: checking whether your system has IPv6 directory" >&5
+echo $ECHO_N "checking whether your system has IPv6 directory... $ECHO_C" >&6
+    if test "${ipv6_cv_dir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+        for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done
+fi
+    echo "$as_me:$LINENO: result: $ipv6_cv_dir" >&5
+echo "${ECHO_T}$ipv6_cv_dir" >&6
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_getaddrinfo=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      echo "$as_me:$LINENO: checking for getaddrinfo in -linet6" >&5
+echo $ECHO_N "checking for getaddrinfo in -linet6... $ECHO_C" >&6
+if test "${ac_cv_lib_inet6_getaddrinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet6  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getaddrinfo ();
+int
+main ()
+{
+getaddrinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet6_getaddrinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet6_getaddrinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_getaddrinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_inet6_getaddrinfo" >&6
+if test $ac_cv_lib_inet6_getaddrinfo = yes; then
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi
+fi
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi
+fi
+
+fi
+ipv6_cv_getaddrinfo=no
+if test $ac_cv_func_getaddrinfo = yes -o $ac_cv_lib_socket_getaddrinfo = yes \
+     -o $ac_cv_lib_inet6_getaddrinfo = yes
+then
+  ipv6_cv_getaddrinfo=yes
+fi
+if test $ipv6_cv_getaddrinfo = no; then
+  if test getaddrinfo = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ipv6_cv_pfx}getaddrinfo" >/dev/null 2>&1; then
+  as_ac_var=`echo "ac_cv_func_${ipv6_cv_pfx}getaddrinfo" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for ${ipv6_cv_pfx}getaddrinfo" >&5
+echo $ECHO_N "checking for ${ipv6_cv_pfx}getaddrinfo... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char ${ipv6_cv_pfx}getaddrinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ${ipv6_cv_pfx}getaddrinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_${ipv6_cv_pfx}getaddrinfo) || defined (__stub___${ipv6_cv_pfx}getaddrinfo)
+choke me
+#else
+char (*f) () = ${ipv6_cv_pfx}getaddrinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != ${ipv6_cv_pfx}getaddrinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+
+fi
+rm -f conftest*
+
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}getaddrinfo = Xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+        ipv6_cv_getaddrinfo=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_getaddrinfo = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+else
+  sasl_cv_getaddrinfo=yes
+fi
+if test $sasl_cv_getaddrinfo = yes; then
+       LIBOBJS="$LIBOBJS getaddrinfo.$ac_objext"
+fi
+
+GETNAMEINFOOBJS=""
+sasl_cv_getnameinfo=no
+
+echo "$as_me:$LINENO: checking for getnameinfo" >&5
+echo $ECHO_N "checking for getnameinfo... $ECHO_C" >&6
+if test "${ac_cv_func_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char getnameinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_getnameinfo) || defined (__stub___getnameinfo)
+choke me
+#else
+char (*f) () = getnameinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != getnameinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_func_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_func_getnameinfo" >&6
+if test $ac_cv_func_getnameinfo = yes; then
+    ac_cv_lib_socket_getnameinfo=no
+  ac_cv_lib_inet6_getnameinfo=no
+
+else
+    echo "$as_me:$LINENO: checking for getnameinfo in -lsocket" >&5
+echo $ECHO_N "checking for getnameinfo in -lsocket... $ECHO_C" >&6
+if test "${ac_cv_lib_socket_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsocket  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+int
+main ()
+{
+getnameinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_socket_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_socket_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_socket_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_socket_getnameinfo" >&6
+if test $ac_cv_lib_socket_getnameinfo = yes; then
+      LIBS="$LIBS -lsocket"
+    ac_cv_lib_inet6_getnameinfo=no
+
+else
+      echo "$as_me:$LINENO: checking whether your system has IPv6 directory" >&5
+echo $ECHO_N "checking whether your system has IPv6 directory... $ECHO_C" >&6
+    if test "${ipv6_cv_dir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+        for ipv6_cv_dir in /usr/local/v6 /usr/inet6 no; do
+       if test $ipv6_cv_dir = no -o -d $ipv6_cv_dir; then
+         break
+       fi
+      done
+fi
+    echo "$as_me:$LINENO: result: $ipv6_cv_dir" >&5
+echo "${ECHO_T}$ipv6_cv_dir" >&6
+    if test $ipv6_cv_dir = no; then
+      ac_cv_lib_inet6_getnameinfo=no
+    else
+      if test x$ipv6_libinet6 = x; then
+       ipv6_libinet6=no
+       SAVELDFLAGS="$LDFLAGS"
+       LDFLAGS="$LDFLAGS -L$ipv6_cv_dir/lib"
+      fi
+      echo "$as_me:$LINENO: checking for getnameinfo in -linet6" >&5
+echo $ECHO_N "checking for getnameinfo in -linet6... $ECHO_C" >&6
+if test "${ac_cv_lib_inet6_getnameinfo+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-linet6  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char getnameinfo ();
+int
+main ()
+{
+getnameinfo ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_inet6_getnameinfo=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_inet6_getnameinfo=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_inet6_getnameinfo" >&5
+echo "${ECHO_T}$ac_cv_lib_inet6_getnameinfo" >&6
+if test $ac_cv_lib_inet6_getnameinfo = yes; then
+       if test $ipv6_libinet6 = no; then
+         ipv6_libinet6=yes
+         LIBS="$LIBS -linet6"
+       fi
+fi
+      if test $ipv6_libinet6 = no; then
+       LDFLAGS="$SAVELDFLAGS"
+      fi
+    fi
+fi
+
+fi
+ipv6_cv_getnameinfo=no
+if test $ac_cv_func_getnameinfo = yes -o $ac_cv_lib_socket_getnameinfo = yes \
+     -o $ac_cv_lib_inet6_getnameinfo = yes
+then
+  ipv6_cv_getnameinfo=yes
+fi
+if test $ipv6_cv_getnameinfo = no; then
+  if test getnameinfo = getaddrinfo; then
+    for ipv6_cv_pfx in o n; do
+      cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <netdb.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "${ipv6_cv_pfx}getnameinfo" >/dev/null 2>&1; then
+  as_ac_var=`echo "ac_cv_func_${ipv6_cv_pfx}getnameinfo" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for ${ipv6_cv_pfx}getnameinfo" >&5
+echo $ECHO_N "checking for ${ipv6_cv_pfx}getnameinfo... $ECHO_C" >&6
+if eval "test \"\${$as_ac_var+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char ${ipv6_cv_pfx}getnameinfo (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char ${ipv6_cv_pfx}getnameinfo ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_${ipv6_cv_pfx}getnameinfo) || defined (__stub___${ipv6_cv_pfx}getnameinfo)
+choke me
+#else
+char (*f) () = ${ipv6_cv_pfx}getnameinfo;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != ${ipv6_cv_pfx}getnameinfo;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_var=no"
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+
+fi
+rm -f conftest*
+
+      if eval test X\$ac_cv_func_${ipv6_cv_pfx}getnameinfo = Xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETADDRINFO
+_ACEOF
+
+        ipv6_cv_getnameinfo=yes
+        break
+      fi
+    done
+  fi
+fi
+if test $ipv6_cv_getnameinfo = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETNAMEINFO
+_ACEOF
+
+else
+  sasl_cv_getnameinfo=yes
+fi
+if test $sasl_cv_getnameinfo = yes; then
+       LIBOBJS="$LIBOBJS getnameinfo.$ac_objext"
+fi
+
+
+echo "$as_me:$LINENO: checking whether you have ss_family in struct sockaddr_storage" >&5
+echo $ECHO_N "checking whether you have ss_family in struct sockaddr_storage... $ECHO_C" >&6
+if test "${ipv6_cv_ss_family+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+struct sockaddr_storage ss; int i = ss.ss_family;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_ss_family=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_ss_family=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+if test $ipv6_cv_ss_family = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SS_FAMILY
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_ss_family" >&5
+echo "${ECHO_T}$ipv6_cv_ss_family" >&6
+
+echo "$as_me:$LINENO: checking whether you have sa_len in struct sockaddr" >&5
+echo $ECHO_N "checking whether you have sa_len in struct sockaddr... $ECHO_C" >&6
+if test "${ipv6_cv_sa_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+struct sockaddr sa; int i = sa.sa_len;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_sa_len=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_sa_len=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+fi
+if test $ipv6_cv_sa_len = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKADDR_SA_LEN
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_sa_len" >&5
+echo "${ECHO_T}$ipv6_cv_sa_len" >&6
+
+echo "$as_me:$LINENO: checking for socklen_t" >&5
+echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
+if test "${ipv6_cv_socklen_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/socket.h>
+int
+main ()
+{
+socklen_t len = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ipv6_cv_socklen_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ipv6_cv_socklen_t=no
+fi
+rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+fi
+if test $ipv6_cv_socklen_t = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_SOCKLEN_T
+_ACEOF
+
+else
+  :
+fi
+echo "$as_me:$LINENO: result: $ipv6_cv_socklen_t" >&5
+echo "${ECHO_T}$ipv6_cv_socklen_t" >&6
+
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/socket.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "sockaddr_storage" >/dev/null 2>&1; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+_ACEOF
+
+fi
+rm -f conftest*
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers saslauthd.h"
+
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+        "s/'/'\\\\''/g;
+         s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+        "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[   ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[     ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+         sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${SASLAUTHD_TRUE}" && test -z "${SASLAUTHD_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"SASLAUTHD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"SASLAUTHD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+
+# Support unset when possible.
+if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+        X"$0" : 'X\(//\)$' \| \
+        X"$0" : 'X\(/\)$' \| \
+        .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+         /^X\/\(\/\/\)$/{ s//\1/; q; }
+         /^X\/\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+        case $as_dir in
+        /*)
+          if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+            $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+            $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+            CONFIG_SHELL=$as_dir/$as_base
+            export CONFIG_SHELL
+            exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+          fi;;
+        esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='     ' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS="  $as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.57.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.57,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "saslauthd.h" ) CONFIG_HEADERS="$CONFIG_HEADERS saslauthd.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@SASLAUTHD_TRUE@,$SASLAUTHD_TRUE,;t t
+s,@SASLAUTHD_FALSE@,$SASLAUTHD_FALSE,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@CPP@,$CPP,;t t
+s,@LN_S@,$LN_S,;t t
+s,@LIB_SOCKET@,$LIB_SOCKET,;t t
+s,@EGREP@,$EGREP,;t t
+s,@CMU_LIB_SUBDIR@,$CMU_LIB_SUBDIR,;t t
+s,@LIB_DES@,$LIB_DES,;t t
+s,@SASL_KRB_LIB@,$SASL_KRB_LIB,;t t
+s,@LIB_CRYPT@,$LIB_CRYPT,;t t
+s,@GSSAPI_LIBS@,$GSSAPI_LIBS,;t t
+s,@GSSAPIBASE_LIBS@,$GSSAPIBASE_LIBS,;t t
+s,@LIB_SIA@,$LIB_SIA,;t t
+s,@SASL_DB_UTILS@,$SASL_DB_UTILS,;t t
+s,@SASL_DB_MANS@,$SASL_DB_MANS,;t t
+s,@SASL_DB_BACKEND@,$SASL_DB_BACKEND,;t t
+s,@SASL_DB_BACKEND_STATIC@,$SASL_DB_BACKEND_STATIC,;t t
+s,@SASL_DB_INC@,$SASL_DB_INC,;t t
+s,@SASL_DB_LIB@,$SASL_DB_LIB,;t t
+s,@MAIN_COMPAT_OBJ@,$MAIN_COMPAT_OBJ,;t t
+s,@LIB_PAM@,$LIB_PAM,;t t
+s,@LDAP_LIBS@,$LDAP_LIBS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+       ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+       ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+                                     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+        cat >$tmp/stdin
+        ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+        ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+         # Absolute (can't be DOS-style, as IFS=:)
+         test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         echo $f;;
+      *) # Relative
+         if test -f "$f"; then
+           # Build tree
+           echo $f
+         elif test -f "$srcdir/$f"; then
+           # Source tree
+           echo $srcdir/$f
+         else
+           # /dev/null tree
+           { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+         fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[     ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[   ]*#[    ]*define[       ][      ]*\([^  (][^    (]*\)\(([^)]*)\)[       ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[   ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[    ]*#[    ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[    ]*#[    ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[    ]*#[    ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_file" : 'X\(//\)[^/]' \| \
+         X"$ac_file" : 'X\(//\)$' \| \
+         X"$ac_file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X$ac_file : 'X\(//\)[^/]' \| \
+         X$ac_file : 'X\(//\)$' \| \
+         X$ac_file : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$ac_dest" : 'X\(//\)[^/]' \| \
+         X"$ac_dest" : 'X\(//\)$' \| \
+         X"$ac_dest" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
+# absolute.
+ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
+ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
+ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
+ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$mf" : 'X\(//\)[^/]' \| \
+         X"$mf" : 'X\(//\)$' \| \
+         X"$mf" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+  else
+    continue
+  fi
+  grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue
+  # Extract the definition of DEP_FILES from the Makefile without
+  # running `make'.
+  DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n -e '/^U = / s///p' < "$mf"`
+  test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
+  # We invoke sed twice because it is the simplest approach to
+  # changing $(DEPDIR) to its actual value in the expansion.
+  for file in `sed -n -e '
+    /^DEP_FILES = .*\\\\$/ {
+      s/^DEP_FILES = //
+      :loop
+       s/\\\\$//
+       p
+       n
+       /\\\\$/ b loop
+      p
+    }
+    /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$file" : 'X\(//\)[^/]' \| \
+         X"$file" : 'X\(//\)$' \| \
+         X"$file" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+         X"$as_dir" : 'X\(//\)[^/]' \| \
+         X"$as_dir" : 'X\(//\)$' \| \
+         X"$as_dir" : 'X\(/\)' \| \
+         .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+         /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+         /^X\(\/\/\)$/{ s//\1/; q; }
+         /^X\(\/\).*/{ s//\1/; q; }
+         s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/saslauthd/configure.in b/saslauthd/configure.in
new file mode 100644 (file)
index 0000000..2f2d1cb
--- /dev/null
@@ -0,0 +1,336 @@
+AC_INIT(mechanisms.h)
+AC_PREREQ([2.54])
+
+AC_CONFIG_AUX_DIR(config)
+AC_CANONICAL_HOST
+
+dnl Should we enable SASLAUTHd at all?
+AC_ARG_WITH(saslauthd, [  --with-saslauthd=DIR    enable use of the saslauth daemon using state dir DIR ],
+               with_saslauthd=$withval,
+               with_saslauthd=yes)
+  if test "$with_saslauthd" = yes; then
+    with_saslauthd="/var/state/saslauthd"
+  fi
+  AC_DEFINE(HAVE_SASLAUTHD,[],[Include support for saslauthd?])
+  AC_DEFINE_UNQUOTED(PATH_SASLAUTHD_RUNDIR, "$with_saslauthd",[Location of saslauthd socket])
+AM_CONDITIONAL(SASLAUTHD, test "$with_saslauthd" != no)
+
+AM_INIT_AUTOMAKE(saslauthd,2.1.23)
+CMU_INIT_AUTOMAKE
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_AWK
+AC_PROG_MAKE_SET
+AC_PROG_LN_S
+AC_PROG_INSTALL
+
+dnl Checks for build foo
+CMU_C___ATTRIBUTE__
+CMU_GUESS_RUNPATH_SWITCH
+
+dnl Checks for libraries.
+CMU_SOCKETS
+
+CMU_HAVE_OPENSSL
+AC_MSG_CHECKING(for OpenSSL)
+AC_MSG_RESULT($with_openssl)
+
+SASL_DES_CHK
+
+dnl mechanism-related checking
+SASL_KERBEROS_V4_CHK
+SASL_GSSAPI_CHK
+
+if test "$gssapi" != no; then
+       if test "$gss_impl" = "heimdal"; then
+           AC_DEFINE(KRB5_HEIMDAL,[],[Using Heimdal])
+       fi
+       AC_DEFINE(HAVE_GSSAPI,[],[Include GSSAPI/Kerberos 5 Support])
+fi
+
+SASL2_CRYPT_CHK
+
+AC_ARG_ENABLE(sia, [  --enable-sia            enable SIA authentication [no] ],
+  sia=$enableval,
+  sia=no)
+LIB_SIA=""
+if test "$sia" != no; then
+  if test -f /etc/sia/matrix.conf; then
+    AC_DEFINE(HAVE_SIA,[],[Include SIA Support])
+    LIB_SIA="-lsecurity -ldb -lm -laud"
+  else
+    AC_ERROR([No support for SIA found])
+  fi
+fi
+AC_SUBST(LIB_SIA)
+
+AC_ARG_ENABLE(auth-sasldb, [  --enable-auth-sasldb    enable experimental SASLdb authentication module [no] ],
+  authsasldb=$enableval,
+  authsasldb=no)
+if test "$authsasldb" != no; then
+  if test ! -d "../sasldb"; then
+     echo "ERROR: Cannot build sasldb module outside of the full SASL source tree."
+     exit 0;
+  fi
+  AC_DEFINE(AUTH_SASLDB,[],[Include SASLdb Support])
+  SASL_DB_PATH_CHECK()
+  SASL_DB_CHECK()
+  SASL_DB_LIB="$SASL_DB_LIB ../sasldb/.libs/libsasldb.al"
+fi
+
+AC_ARG_ENABLE(httpform, [  --enable-httpform       enable HTTP form authentication [[no]] ],
+  httpform=$enableval,
+  httpform=no)
+if test "$httpform" != no; then
+  AC_DEFINE(HAVE_HTTPFORM,[],[Include HTTP form Support])
+fi
+
+AC_ARG_WITH(pam, [  --with-pam=DIR          use PAM (rooted in DIR) [yes] ],
+       with_pam=$withval,
+       with_pam=yes)
+if test "$with_pam" != no; then
+  if test -d $with_pam; then
+    CPPFLAGS="$CPPFLAGS -I${with_pam}/include"
+    LDFLAGS="$LDFLAGS -L${with_pam}/lib"
+  fi
+  cmu_save_LIBS="$LIBS"
+  AC_CHECK_LIB(pam, pam_start, [
+         AC_CHECK_HEADER(security/pam_appl.h,,
+                         with_pam=no)],
+               with_pam=no, $SASL_DL_LIB)
+  LIBS="$cmu_save_LIBS"
+fi
+
+AC_ARG_WITH(ipctype, [  --with-ipctype={unix,doors}    use ipctype [unix] ],
+       with_ipctype=$withval,
+       with_ipctype="unix")
+MAIN_COMPAT_OBJ="saslauthd-${with_ipctype}.o"
+AC_SUBST(MAIN_COMPAT_OBJ)
+if test "$with_ipctype" = "doors"; then
+  AC_DEFINE(USE_DOORS,[],[Use the doors IPC API])
+  AC_DEFINE(SASLAUTHD_THREADED,[],[Saslauthd runs threaded?])
+  LIBS="$LIBS -ldoor -lpthread"
+fi
+
+AC_MSG_CHECKING(for PAM support)
+AC_MSG_RESULT($with_pam)
+LIB_PAM=""
+if test "$with_pam" != no; then
+  AC_DEFINE(HAVE_PAM,[],[Support for PAM?])
+  LIB_PAM="-lpam"
+fi
+AC_SUBST(LIB_PAM)
+
+AC_CHECK_LIB(resolv, inet_aton)
+
+AC_MSG_CHECKING(to include LDAP support)
+AC_ARG_WITH(ldap, [  --with-ldap=DIR         use LDAP (in DIR) [no] ],
+       with_ldap=$withval,
+       with_ldap=no)
+AC_MSG_RESULT($with_ldap)
+
+if test -d $with_ldap; then
+    CPPFLAGS="$CPPFLAGS -I${with_ldap}/include"
+    CMU_ADD_LIBPATH(${with_ldap}/lib)
+fi
+
+LDAP_LIBS=""
+if test "$with_ldap" != no; then
+  AC_CHECK_LIB(ldap, ldap_initialize, [ AC_DEFINE(HAVE_LDAP,[],[Support for LDAP?])
+                                        LDAP_LIBS="-lldap -llber"
+                                       if test "$with_openssl" != "no"; then
+                                           LDAP_LIBS="$LDAP_LIBS -lcrypto $LIB_RSAREF"
+                                       fi],,-llber)
+  
+fi
+AC_SUBST(LDAP_LIBS)
+
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
+AC_CHECK_HEADERS(crypt.h fcntl.h krb5.h strings.h syslog.h unistd.h sys/time.h sys/uio.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST  
+AC_TYPE_PID_T
+
+LTLIBOBJS=`echo "$LIB@&t@OBJS" | sed 's,\.[[^.]]* ,.lo ,g;s,\.[[^.]]*$,.lo,'`
+AC_SUBST(LTLIBOBJS)
+
+dnl Checks for which function macros exist
+AC_MSG_CHECKING(whether $CC implements __func__)
+AC_CACHE_VAL(have_func,
+[AC_TRY_LINK([#include <stdio.h>],[printf("%s", __func__);],
+have_func=yes,
+have_func=no)])
+AC_MSG_RESULT($have_func)
+if test "$have_func" = yes; then
+       AC_DEFINE(HAVE_FUNC,[],[Does the compiler understand __func__])
+else
+       AC_MSG_CHECKING(whether $CC implements __PRETTY_FUNCTION__)
+       AC_CACHE_VAL(have_pretty_function,
+       [AC_TRY_LINK([#include <stdio.h>],[printf("%s", __PRETTY_FUNCTION__);],
+       have_pretty_function=yes,
+       have_pretty_function=no)])
+       AC_MSG_RESULT($have_pretty_function)
+       if test "$have_pretty_function" = yes; then
+               AC_DEFINE(HAVE_PRETTY_FUNCTION,[],[Does compiler understand __PRETTY_FUNCTION__])
+       else
+               AC_MSG_CHECKING(whether $CC implements __FUNCTION__)
+               AC_CACHE_VAL(have_function,
+               [AC_TRY_LINK([#include <stdio.h>],[printf("%s", __FUNCTION__);],
+               have_function=yes,
+               have_function=no)])
+               AC_MSG_RESULT($have_function)
+               if test "$have_function" = yes; then
+                       AC_DEFINE(HAVE_FUNCTION,[],[Does compiler understand __FUNCTION__])
+               fi
+       fi
+fi
+
+dnl Checks for library functions.
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS(gethostname mkdir socket strdup)
+AC_CHECK_FUNCS(getspnam getuserpw, break)
+AC_CHECK_FUNCS(strlcat strlcpy)
+
+if test $ac_cv_func_getspnam = yes; then
+       AC_MSG_CHECKING(if getpwnam_r/getspnam_r take 5 arguments)
+       AC_TRY_COMPILE(
+               [
+#include <sys/types.h>
+#include <pwd.h>
+#include <shadow.h>
+               ],
+               [
+struct passwd *pw;
+struct passwd pwbuf;
+char pwdata[512];
+(void) getpwnam_r("bin", &pwbuf, pwdata, sizeof(pwdata), &pw);
+               ],
+               [AC_MSG_RESULT(yes)
+                AC_DEFINE(GETXXNAM_R_5ARG, 1,
+                       [Define if your getpwnam_r()/getspnam_r()
+                       functions take 5 arguments])],
+               [AC_MSG_RESULT(no)]
+       )
+fi
+
+dnl Check for getaddrinfo
+GETADDRINFOOBJS=""
+sasl_cv_getaddrinfo=no
+IPv6_CHECK_FUNC(getaddrinfo,
+               [AC_DEFINE(HAVE_GETADDRINFO,[],[Do we have a getaddrinfo() function?])], [sasl_cv_getaddrinfo=yes])
+if test $sasl_cv_getaddrinfo = yes; then
+       AC_LIBOBJ(getaddrinfo)
+fi
+
+dnl Check for getnameinfo
+GETNAMEINFOOBJS=""
+sasl_cv_getnameinfo=no
+IPv6_CHECK_FUNC(getnameinfo,
+               [AC_DEFINE(HAVE_GETNAMEINFO,[],[Do we have a getnameinfo() function?])], [sasl_cv_getnameinfo=yes])
+if test $sasl_cv_getnameinfo = yes; then
+       AC_LIBOBJ(getnameinfo)
+fi
+
+IPv6_CHECK_SS_FAMILY()
+IPv6_CHECK_SA_LEN()
+IPv6_CHECK_SOCKLEN_T()
+
+AC_EGREP_HEADER(sockaddr_storage, sys/socket.h,
+                AC_DEFINE(HAVE_STRUCT_SOCKADDR_STORAGE,[],[Do we have a sockaddr_storage struct?]))
+
+AH_TOP([
+#ifndef _SASLAUTHD_H
+#define _SASLAUTHD_H
+
+#include <stdio.h>
+])
+
+AH_BOTTOM([
+
+#ifndef HAVE___ATTRIBUTE__
+/* Can't use attributes... */
+#define __attribute__(foo)
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef WIN32
+# include <netdb.h>   
+# include <sys/param.h>
+#else /* WIN32 */
+# include <winsock2.h>
+#endif /* WIN32 */ 
+#include <string.h>
+
+#include <netinet/in.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#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
+
+/* Create a struct iovec if we need one */
+#if !defined(HAVE_SYS_UIO_H)
+struct iovec {
+    long iov_len;
+    char *iov_base;
+};
+#else
+#include <sys/types.h>
+#include <sys/uio.h>
+#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
+
+#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
+#define        AI_NUMERICHOST  4
+#define NI_NUMERICHOST 2
+#define NI_NAMEREQD    4
+#define NI_NUMERICSERV 8
+#endif
+
+/* handy string manipulation functions */
+#ifndef HAVE_STRLCPY
+extern size_t saslauthd_strlcpy(char *dst, const char *src, size_t len);
+#define strlcpy(x,y,z) saslauthd_strlcpy((x),(y),(z))
+#endif
+#ifndef HAVE_STRLCAT
+extern size_t saslauthd_strlcat(char *dst, const char *src, size_t len);
+#define strlcat(x,y,z) saslauthd_strlcat((x),(y),(z))
+#endif
+
+#endif
+])
+
+AC_CONFIG_HEADERS(saslauthd.h)
+
+AC_OUTPUT(Makefile)
diff --git a/saslauthd/getaddrinfo.c b/saslauthd/getaddrinfo.c
new file mode 100644 (file)
index 0000000..2ab42cb
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: getaddrinfo.c,v 1.2 2003/02/13 19:56:07 rjs3 Exp $
+ *
+ * This module is besed on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ * 
+ * In the case not using 'configure --enable-ipv6', this getaddrinfo.c
+ * will be used if you have broken getaddrinfo or no getaddrinfo.
+ */
+
+#include "saslauthd.h"
+#ifndef macintosh
+#include <sys/param.h>
+#include <arpa/inet.h>
+#endif
+#include <ctype.h>
+
+static struct addrinfo *
+malloc_ai(int port, u_long addr, int socktype, int proto)
+{
+    struct addrinfo *ai;
+
+    ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) +
+                                  sizeof(struct sockaddr_in));
+    if (ai) {
+       memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
+       ai->ai_addr = (struct sockaddr *)(ai + 1);
+       /* XXX -- ssh doesn't use sa_len */
+       ai->ai_addrlen = sizeof(struct sockaddr_in);
+#ifdef HAVE_SOCKADDR_SA_LEN
+       ai->ai_addr->sa_len = sizeof(struct sockaddr_in);
+#endif
+       ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+       ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+       ai->ai_socktype = socktype;
+       ai->ai_protocol = proto;
+       return ai;
+    } else {
+       return NULL;
+    }
+}
+
+char *
+gai_strerror(int ecode)
+{
+    switch (ecode) {
+    case EAI_NODATA:
+       return "no address associated with hostname.";
+    case EAI_MEMORY:
+       return "memory allocation failure.";
+    case EAI_FAMILY:
+       return "ai_family not supported.";
+    case EAI_SERVICE:
+       return "servname not supported for ai_socktype.";
+    default:
+       return "unknown error.";
+    }
+}
+
+void
+freeaddrinfo(struct addrinfo *ai)
+{
+    struct addrinfo *next;
+
+    if (ai->ai_canonname)
+       free(ai->ai_canonname);
+    do {
+       next = ai->ai_next;
+       free(ai);
+    } while ((ai = next) != NULL);
+}
+
+int
+getaddrinfo(const char *hostname, const char *servname,
+           const struct addrinfo *hints, struct addrinfo **res)
+{
+    struct addrinfo *cur, *prev = NULL;
+    struct hostent *hp;
+    struct in_addr in;
+    int i, port = 0, socktype, proto;
+
+    if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC)
+       return EAI_FAMILY;
+
+    socktype = (hints && hints->ai_socktype) ? hints->ai_socktype
+                                            : SOCK_STREAM;
+    if (hints && hints->ai_protocol)
+       proto = hints->ai_protocol;
+    else {
+       switch (socktype) {
+       case SOCK_DGRAM:
+           proto = IPPROTO_UDP;
+           break;
+       case SOCK_STREAM:
+           proto = IPPROTO_TCP;
+           break;
+       default:
+           proto = 0;
+           break;
+       }
+    }
+    if (servname) {
+       if (isdigit((int)*servname))
+           port = htons(atoi(servname));
+       else {
+           struct servent *se;
+           char *pe_proto;
+
+           switch (socktype) {
+           case SOCK_DGRAM:
+               pe_proto = "udp";
+               break;
+           case SOCK_STREAM:
+               pe_proto = "tcp";
+               break;
+           default:
+               pe_proto = NULL;
+               break;
+           }
+           if ((se = getservbyname(servname, pe_proto)) == NULL)
+               return EAI_SERVICE;
+           port = se->s_port;
+       }
+    }
+    if (!hostname) {
+        if (hints && hints->ai_flags & AI_PASSIVE)
+            *res = malloc_ai(port, htonl(0x00000000), socktype, proto);
+        else
+            *res = malloc_ai(port, htonl(0x7f000001), socktype, proto);
+        if (*res)
+           return 0;
+        else
+           return EAI_MEMORY;
+    }
+    if (inet_aton(hostname, &in)) {
+       *res = malloc_ai(port, in.s_addr, socktype, proto);
+       if (*res)
+           return 0;
+       else
+           return EAI_MEMORY;
+    }
+    if (hints && hints->ai_flags & AI_NUMERICHOST)
+       return EAI_NODATA;
+#ifndef macintosh
+    if ((hp = gethostbyname(hostname)) &&
+       hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+       for (i = 0; hp->h_addr_list[i]; i++) {
+           if ((cur = malloc_ai(port,
+                               ((struct in_addr *)hp->h_addr_list[i])->s_addr,
+                               socktype, proto)) == NULL) {
+               if (*res)
+                   freeaddrinfo(*res);
+               return EAI_MEMORY;
+           }
+           if (prev)
+               prev->ai_next = cur;
+           else
+               *res = cur;
+           prev = cur;
+       }
+       if (hints && hints->ai_flags & AI_CANONNAME && *res) {
+           /* NOT sasl_strdup for compatibility */
+           if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) {
+               freeaddrinfo(*res);
+               return EAI_MEMORY;
+           }
+       }
+       return 0;
+    }
+#endif
+    return EAI_NODATA;
+}
diff --git a/saslauthd/getnameinfo.c b/saslauthd/getnameinfo.c
new file mode 100644 (file)
index 0000000..970425b
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: getnameinfo.c,v 1.2 2003/02/13 19:56:07 rjs3 Exp $
+ *
+ * This module is besed on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file includes getnameinfo().
+ * These funtions are defined in rfc2133.
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For exapmle, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ * 
+ * In the case not using 'configure --enable-ipv6', this getnameinfo.c
+ * will be used if you have broken getnameinfo or no getnameinfo.
+ */
+
+#include "saslauthd.h"
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <string.h>
+
+int
+getnameinfo(const struct sockaddr *sa, socklen_t salen __attribute__((unused)),
+           char *host, size_t hostlen, char *serv, size_t servlen, int flags)
+{
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct hostent *hp;
+    char tmpserv[16];
+  
+    if (serv) {
+       sprintf(tmpserv, "%d", ntohs(sin->sin_port));
+       if (strlen(tmpserv) > servlen)
+           return EAI_MEMORY;
+       else
+           strcpy(serv, tmpserv);
+    }
+    if (host) {
+       if (flags & NI_NUMERICHOST) {
+           if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen)
+               return EAI_MEMORY;
+           else {
+               strcpy(host, inet_ntoa(sin->sin_addr));
+               return 0;
+           }
+       } else {
+           hp = gethostbyaddr((char *)&sin->sin_addr,
+                              sizeof(struct in_addr), AF_INET);
+           if (hp)
+               if (strlen(hp->h_name) >= hostlen)
+                   return EAI_MEMORY;
+               else {
+                   strcpy(host, hp->h_name);
+                   return 0;
+               }
+           else
+               return EAI_NODATA;
+       }
+    }
+    
+    return 0;
+}
diff --git a/saslauthd/globals.h b/saslauthd/globals.h
new file mode 100644 (file)
index 0000000..13967ee
--- /dev/null
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * *****************************************************************************
+ * *
+ * * globals.h
+ * *
+ * * Description:  Header file for all application wide globale variables.
+ * *
+ * * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * * 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.
+ * *
+ * * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * * THE POSSIBILITY OF SUCH DAMAGE
+ * *
+ * * HISTORY
+ * * 
+ * * This source file created using 8 space tabs.
+ * *
+ * ******************************************************************************
+ ********************************************************************************/
+
+#ifndef _GLOBALS_H
+#define _GLOBALS_H
+
+#include "mechanisms.h"
+
+
+/* saslauthd-main.c */
+extern int              g_argc;
+extern char             **g_argv;
+extern int              flags;
+extern int              num_procs;
+extern char             *mech_option;
+extern char             *run_path;
+extern authmech_t       *auth_mech;
+
+
+/* flags bits */
+#define VERBOSE                 (1 << 1)
+#define LOG_USE_SYSLOG          (1 << 2)
+#define LOG_USE_STDERR          (1 << 3)
+#define AM_MASTER               (1 << 4)
+#define USE_ACCEPT_LOCK         (1 << 5)
+#define DETACH_TTY              (1 << 6)
+#define CACHE_ENABLED           (1 << 7)
+#define USE_PROCESS_MODEL       (1 << 8)
+#define CONCAT_LOGIN_REALM      (1 << 9)
+
+
+#endif  /* _GLOBALS_H */
diff --git a/saslauthd/include/gai.h b/saslauthd/include/gai.h
new file mode 100644 (file)
index 0000000..54b93ff
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Mar  8, 2000 by Hajimu UMEMOTO <ume@mahoroba.org>
+ * $Id: gai.h,v 1.2 2003/02/13 19:56:13 rjs3 Exp $
+ *
+ * This module is besed on ssh-1.2.27-IPv6-1.5 written by
+ * KIKUCHI Takahiro <kick@kyoto.wide.ad.jp>
+ */
+/* 
+ * 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.
+ */
+/*
+ * fake library for ssh
+ *
+ * This file is included in getaddrinfo.c and getnameinfo.c.
+ * See getaddrinfo.c and getnameinfo.c.
+ */
+
+#ifndef _GAI_H_
+#define _GAI_H_
+
+#ifndef NI_MAXHOST
+#define        NI_MAXHOST      1025
+#endif
+#ifndef NI_MAXSERV
+#define        NI_MAXSERV      32
+#endif
+
+/* for old netdb.h */
+#ifndef EAI_NODATA
+#define EAI_NODATA     1
+#define EAI_MEMORY     2
+#define EAI_FAMILY     5       /* ai_family not supported */
+#define EAI_SERVICE    9       /* servname not supported for ai_socktype */
+#endif
+
+/* dummy value for old netdb.h */
+#ifndef AI_PASSIVE
+#define AI_PASSIVE     1
+#define AI_CANONNAME   2
+#define        AI_NUMERICHOST  4
+#define NI_NUMERICHOST 2
+#define NI_NAMEREQD    4
+#define NI_NUMERICSERV 8
+struct addrinfo {
+       int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME */
+       int     ai_family;      /* PF_xxx */
+       int     ai_socktype;    /* SOCK_xxx */
+       int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+       size_t  ai_addrlen;     /* length of ai_addr */
+       char    *ai_canonname;  /* canonical name for hostname */
+       struct sockaddr *ai_addr;       /* binary address */
+       struct addrinfo *ai_next;       /* next structure in linked list */
+};
+#endif
+
+int    getaddrinfo(const char *, const char *,
+                   const struct addrinfo *, struct addrinfo **);
+int    getnameinfo(const struct sockaddr *, socklen_t, char *,
+                   size_t, char *, size_t, int);
+void   freeaddrinfo(struct addrinfo *);
+char   *gai_strerror(int);
+
+#endif
diff --git a/saslauthd/ipc_doors.c b/saslauthd/ipc_doors.c
new file mode 100644 (file)
index 0000000..92f403c
--- /dev/null
@@ -0,0 +1,391 @@
+/*******************************************************************************
+ *
+ * ipc_doors.c
+ *
+ * Description:  Implements the Sun doors IPC method.
+ *
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2003 Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * HISTORY
+ *
+ * 
+ * This source file created using 8 space tabs.
+ *
+ ********************************************************************************/
+
+
+/****************************************
+ * enable/disable ifdef
+*****************************************/
+#include "saslauthd-main.h"
+
+#ifdef USE_DOORS_IPC
+/****************************************/
+
+
+
+/****************************************
+ * includes
+*****************************************/
+#include <door.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stropts.h>
+
+#include "globals.h"
+#include "utils.h"
+
+/****************************************
+ * declarations/protos
+ *****************************************/
+static void    do_request(void *, char *, size_t, door_desc_t *, uint_t);
+static void    send_no(char *);
+static void    need_thread(door_info_t*);
+static void    *server_thread(void *);
+
+/****************************************
+ * module globals
+ *****************************************/
+static char                    *door_file;  /* Path to the door file        */
+static int                     door_fd;     /* Door file descriptor         */
+static pthread_attr_t thread_attr;          /* Thread attributes            */
+static int                     num_thr;     /* Number of threads            */
+static pthread_mutex_t         num_lock;    /* Lock for update              */
+
+/****************************************
+ * flags               global from saslauthd-main.c
+ * run_path            global from saslauthd-main.c
+ * num_procs           global from saslauthd-main.c
+ * detach_tty()        function from saslauthd-main.c
+ * logger()            function from utils.c
+ *****************************************/
+
+/*************************************************************
+ * IPC init. Initialize the environment specific to the 
+ * Sun doors IPC method.
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_init() {
+       int     rc;
+       size_t  door_file_len;
+
+       /**************************************************************
+         * Doors detach immediately, otherwise the process gets confused.
+         * (they don't follow fork() properly)
+        **************************************************************/
+       detach_tty();
+
+       /**************************************************************
+        * Setup the door file and the door.
+        **************************************************************/
+       door_file_len = strlen(run_path) + sizeof(DOOR_FILE) + 1;
+       if (!(door_file = malloc(door_file_len))) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+
+       strlcpy(door_file, run_path, door_file_len);
+       strlcat(door_file, DOOR_FILE, door_file_len);
+       unlink(door_file);
+
+       if ((door_fd = open(door_file, O_CREAT|O_RDWR|O_TRUNC, 0666)) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not open door file: %s",
+                      door_file);
+               logger(L_ERR, L_FUNC, "open: %s", strerror(rc));
+               exit(1);
+       }
+
+       close(door_fd);
+
+       if ((door_fd = door_create(&do_request, NULL, 0)) < 0) {
+               logger(L_ERR, L_FUNC, "failed to create door");
+               exit(1);
+       }
+
+       door_server_create(&need_thread);
+
+       if (fattach(door_fd, door_file) < 0) {
+               logger(L_ERR, L_FUNC, "failed to attach door to file: %s",
+                      door_file);
+               exit(1);
+       }
+
+       if (chmod(door_file, 0644) < 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to chmod door file: %s",
+                      door_file);
+               logger(L_ERR, L_FUNC, "chmod: %s", strerror(rc));
+               exit(1);
+       }
+
+       logger(L_INFO, L_FUNC, "door on: %s", door_file);
+
+       /**************************************************************
+        * The doors api will handle threads for us, clear the process 
+        * model global flag.
+        **************************************************************/
+       flags &= ~USE_PROCESS_MODEL;
+
+       /* Initialize mutex */
+       pthread_mutex_init(&num_lock, NULL);
+
+       /* Initialize thread attributes */
+       pthread_attr_init(&thread_attr);
+       pthread_attr_setscope(&thread_attr, PTHREAD_SCOPE_SYSTEM);
+       pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
+
+       return;
+}
+
+
+/*************************************************************
+ * Main IPC loop. Sit idle waiting for a door request. All
+ * request get routed to do_request() via the doors api.
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_loop() {
+       while(1) {
+               pause();
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * General cleanup. Unlink our files.
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_cleanup() {
+       unlink(door_file);
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "door file removed: %s", door_file);
+}
+
+
+/*************************************************************
+ * Handle the door data, pass the request off to
+ * do_auth() back in saslauthd-main.c, then send the 
+ * result back through the door.
+ **************************************************************/
+void do_request(void *cookie, char *data, size_t datasize, door_desc_t *dp, size_t ndesc) {
+       unsigned short          count = 0;                 /* input/output data byte count           */
+       char                    *response = NULL;          /* response to send to the client         */
+       char                    response_buff[1024];       /* temporary response buffer              */
+       char                    *dataend;                  /* EOD marker for the door data           */
+       char                    login[MAX_REQ_LEN + 1];    /* account name to authenticate           */
+       char                    password[MAX_REQ_LEN + 1]; /* password for authentication            */
+       char                    service[MAX_REQ_LEN + 1];  /* service name for authentication        */
+       char                    realm[MAX_REQ_LEN + 1];    /* user realm for authentication          */
+
+
+       /**************************************************************
+        * The input data string consists of the login id, password,
+        * service name and user realm. We'll break them up and then
+        * authenticate them.
+        **************************************************************/
+       dataend = data + datasize;
+
+       /* login id */
+       memcpy(&count, data, sizeof(unsigned short));
+
+       count = ntohs(count);
+       data += sizeof(unsigned short);
+
+       if (count > MAX_REQ_LEN || data + count > dataend) {
+               logger(L_ERR, L_FUNC, "login exceeds MAX_REQ_LEN: %d",
+                      MAX_REQ_LEN);
+               send_no("");
+               return;
+       }       
+
+       memcpy(login, data, count);
+       login[count] = '\0';
+       data += count;
+
+       /* password */
+       memcpy(&count, data, sizeof(unsigned short));
+
+       count = ntohs(count);
+       data += sizeof(unsigned short);
+
+       if (count > MAX_REQ_LEN || data + count > dataend) {
+               logger(L_ERR, L_FUNC, "password exceeds MAX_REQ_LEN: %d",
+                      MAX_REQ_LEN);
+               send_no("");
+               return;
+       }       
+
+       memcpy(password, data, count);
+       password[count] = '\0';
+       data += count;
+
+       /* service */
+       memcpy(&count, data, sizeof(unsigned short));
+
+       count = ntohs(count);
+       data += sizeof(unsigned short);
+
+       if (count > MAX_REQ_LEN || data + count > dataend) {
+               logger(L_ERR, L_FUNC, "service exceeds MAX_REQ_LEN: %d",
+                      MAX_REQ_LEN);
+               send_no("");
+               return;
+       }       
+
+       memcpy(service, data, count);
+       service[count] = '\0';
+       data += count;
+
+       /* realm */
+       memcpy(&count, data, sizeof(unsigned short));
+
+       count = ntohs(count);
+       data += sizeof(unsigned short);
+
+       if (count > MAX_REQ_LEN || data + count > dataend) {
+               logger(L_ERR, L_FUNC, "realm exceeds MAX_REQ_LEN: %d",
+                      MAX_REQ_LEN);
+               send_no("");
+               return;
+       }       
+
+       memcpy(realm, data, count);
+       realm[count] = '\0';
+
+       /**************************************************************
+        * We don't allow NULL passwords or login names
+        **************************************************************/
+       if (*login == '\0') {
+               logger(L_ERR, L_FUNC, "NULL login received");
+               send_no("NULL login received");
+               return;
+       }       
+       
+       if (*password == '\0') {
+               logger(L_ERR, L_FUNC, "NULL password received");
+               send_no("NULL password received");
+               return;
+       }       
+
+       /**************************************************************
+        * Get the mechanism response from do_auth() and send it back.
+        **************************************************************/
+       response = do_auth(login, password, service, realm);
+
+       memset(password, 0, strlen(password));
+
+       if (response == NULL) {
+           send_no("NULL response from mechanism");
+           return;
+       }       
+
+       strncpy(response_buff, response, 1023);
+       response_buff[1023] = '\0';
+       free(response);
+
+       if (flags & VERBOSE)
+           logger(L_DEBUG, L_FUNC, "response: %s", response_buff);
+
+       if(door_return(response_buff, strlen(response_buff), NULL, 0) < 0)
+           logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno));
+
+       return;
+}
+
+/*************************************************************
+ * The available server  thread  pool  is  depleted.
+ * Create a new thread with suitable attributes.
+ * Client door_call() will block until server thread is available.
+ **************************************************************/
+void need_thread(door_info_t *di) {
+    pthread_t newt;
+    int more;
+    
+    if (num_procs > 0) {
+       pthread_mutex_lock(&num_lock);
+       more = (num_thr < num_procs);
+       if (more) num_thr++;
+       pthread_mutex_unlock(&num_lock);
+       if (!more) return;
+    }
+
+    pthread_create(&newt, &thread_attr, &server_thread, NULL);
+}
+/*************************************************************
+ * Start a new server thread.
+ * Make it available for door invocations.
+ **************************************************************/
+void *server_thread(void *arg) {
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+    door_return(NULL, 0, NULL, 0);
+}
+
+/*************************************************************
+ * In case something went out to lunch while parsing the
+ * request data, we may want to attempt to send back a
+ * "NO" response through the door. The mesg is optional.
+ **************************************************************/
+void send_no(char *mesg) {
+       char            buff[1024];
+
+       buff[0] = 'N';
+       buff[1] = 'O';
+       buff[2] = ' ';
+
+       /* buff, except for the trailing NUL and 'NO ' */
+       strncpy(buff + 3, mesg, sizeof(buff) - 1 - 3);
+       buff[1023] = '\0';
+
+       if (flags & VERBOSE)
+           logger(L_DEBUG, L_FUNC, "response: %s", buff);
+
+       if(door_return(buff, strlen(buff), NULL, 0) < 0)
+           logger(L_ERR, L_FUNC, "door_return: %s", strerror(errno));
+
+       return; 
+}
+
+#endif /* USE_DOORS_IPC */
diff --git a/saslauthd/ipc_unix.c b/saslauthd/ipc_unix.c
new file mode 100644 (file)
index 0000000..f82a245
--- /dev/null
@@ -0,0 +1,570 @@
+/*******************************************************************************
+ *
+ * ipc_unix.c
+ *
+ * Description:  Implements the AF_UNIX IPC method.
+ *
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2003 Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * HISTORY
+ *
+ * 
+ * This source file created using 8 space tabs.
+ *
+ ********************************************************************************/
+
+/****************************************
+ * enable/disable ifdef
+*****************************************/
+#include "saslauthd-main.h"
+
+#ifdef USE_UNIX_IPC
+/****************************************/
+
+/****************************************
+ * includes
+*****************************************/
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <string.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#include "globals.h"
+#include "utils.h"
+
+/****************************************
+ * declarations/protos
+ *****************************************/
+static void    do_request(int);
+static void    send_no(int, char *);
+static int     rel_accept_lock();
+static int     get_accept_lock();
+
+/****************************************
+ * module globals
+ *****************************************/
+static int                     sock_fd;     /* descriptor for the socket          */
+static int                     accept_fd;   /* descriptor for the accept lock     */
+static struct sockaddr_un      server;      /* domain socket control, server side */
+static struct sockaddr_un      client;      /* domain socket control, client side */
+static SALEN_TYPE              len;         /* length for the client sockaddr_un  */
+static char                    *sock_file;  /* path to the AF_UNIX socket         */
+static char                    *accept_file;/* path to the accept() lock file     */
+
+/****************************************
+ * flags               global from saslauthd-main.c
+ * run_path            global from saslauthd-main.c
+ * num_procs           global from saslauthd-main.c
+ * detach_tty()        function from saslauthd-main.c
+ * rx_rec()            function from utils.c
+ * tx_rec()            function from utils.c
+ * logger()            function from utils.c
+ *****************************************/
+
+
+/*************************************************************
+ * IPC init. Initialize the environment specific to the 
+ * AF_UNIX IPC method.
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_init() {
+       int     rc;
+       size_t  sock_file_len;
+       
+        /*********************************************************
+        * When we're not preforking, using an accept lock is a
+        * waste of resources. Otherwise, setup the accept lock
+        * file.
+        **********************************************************/
+       if (num_procs == 0) 
+               flags &= ~USE_ACCEPT_LOCK;
+       
+       if (flags & USE_ACCEPT_LOCK) {
+               size_t accept_file_len;
+
+               accept_file_len = strlen(run_path) + sizeof(ACCEPT_LOCK_FILE) + 1;
+               if ((accept_file = malloc(accept_file_len)) == NULL) {
+                       logger(L_ERR, L_FUNC, "could not allocate memory");
+                       exit(1);
+               }
+
+               strlcpy(accept_file, run_path, accept_file_len);
+               strlcat(accept_file, ACCEPT_LOCK_FILE, accept_file_len);
+
+               if ((accept_fd = open(accept_file, O_RDWR|O_CREAT|O_TRUNC, S_IWUSR|S_IRUSR)) == -1) {
+                       rc = errno;
+                       logger(L_ERR, L_FUNC, "could not open accept lock file: %s", accept_file);
+                       logger(L_ERR, L_FUNC, "open: %s", strerror(rc));
+                       exit(1);
+               }
+
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "using accept lock file: %s", accept_file);
+       }
+
+       /**************************************************************
+        * We're at the point where we can't really do anything else
+        * until we attempt to detach or daemonize.
+        **************************************************************/
+       detach_tty();
+
+       /**************************************************************
+        * Setup the UNIX domain socket
+        **************************************************************/
+       sock_file_len = strlen(run_path) + sizeof(SOCKET_FILE) + 1;
+       if ((sock_file = malloc(sock_file_len)) == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+
+       strlcpy(sock_file, run_path, sock_file_len);
+       strlcat(sock_file, SOCKET_FILE, sock_file_len);
+
+       unlink(sock_file);
+       memset(&server, 0, sizeof(server));
+       strlcpy(server.sun_path, sock_file, sizeof(server.sun_path));   
+       server.sun_family = AF_UNIX;
+       
+       if ((sock_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not create socket");
+               logger(L_ERR, L_FUNC, "socket: %s", strerror(rc));
+               exit(1);
+       }
+
+       umask(0);
+
+       if (bind(sock_fd, (struct sockaddr *)&server, sizeof(server)) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not bind to socket: %s", sock_file);
+               logger(L_ERR, L_FUNC, "bind: %s", strerror(rc));
+               exit(1);
+       }
+
+       if (chmod(sock_file, S_IRWXU|S_IRWXG|S_IRWXO) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not chmod socket: %s", sock_file);
+               logger(L_ERR, L_FUNC, "chmod: %s", strerror(rc));
+               exit(1);
+       }
+
+       fchmod(sock_fd, S_IRWXU|S_IRWXG|S_IRWXO);
+
+       umask(077);
+
+       if (listen(sock_fd, SOCKET_BACKLOG) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not listen on socket: %s", sock_file);
+               logger(L_ERR, L_FUNC, "listen: %s", strerror(rc));
+               exit(1);
+       }
+
+
+       logger(L_INFO, L_FUNC, "listening on socket: %s", sock_file);
+
+       /**************************************************************
+        * Ok boys... Let's procreate... If necessary of course...
+        * Num_procs == 0 means we're running one shot per process. In
+        * that case, we'll handle forking on a per connection basis.
+        **************************************************************/
+       if (num_procs != 0)
+               flags |= USE_PROCESS_MODEL;
+
+       return;
+}
+
+/*************************************************************
+ * Main IPC loop. Handle all the socket accept stuff, fork if 
+ * needed, then pass things off to do_request().
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_loop() {
+
+       int             rc;
+       int             conn_fd;
+
+
+       while(1) {
+
+               len = sizeof(client);
+
+               /**************************************************************
+                * First, if needed, get the accept lock. If it fails, take a
+                * nap and go to the top of the loop. (or should we just die?)
+                *************************************************************/
+               if (get_accept_lock() != 0) {
+                       sleep(5);
+                       continue;
+               }
+
+               conn_fd = accept(sock_fd, (struct sockaddr *)&client, &len);
+               rc = errno;
+
+               rel_accept_lock();
+
+               if (conn_fd == -1) {
+                       if (rc != EINTR) {
+                               logger(L_ERR, L_FUNC, "socket accept failure");
+                               logger(L_ERR, L_FUNC, "accept: %s", strerror(rc));
+                               sleep(5);
+                       }
+                       continue;
+               }
+
+               /**************************************************************
+                * If we're running one shot, drop off a kid to handle the
+                * connection.
+                *************************************************************/
+               if (num_procs == 0) {
+                   if(flags & DETACH_TTY) {
+                       if (have_baby() > 0) {  /* parent */
+                           close(conn_fd);
+                           continue;
+                       }
+                       
+                       close(sock_fd);         /* child  */
+                   }
+                   
+                   do_request(conn_fd);
+                   close(conn_fd);
+
+                   if(flags & DETACH_TTY) {
+                       exit(0);        
+                   } else {
+                       continue;
+                   }
+                   
+               }
+
+               /**************************************************************
+                * Normal prefork mode.
+                *************************************************************/
+               do_request(conn_fd);
+               close(conn_fd);
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * General cleanup. Unlock, close, and unlink our files.
+ *
+ * __Required Function__
+ **************************************************************/
+void ipc_cleanup() {
+
+       struct flock    lock_st;
+
+       if (flags & USE_ACCEPT_LOCK) {
+
+               lock_st.l_type = F_UNLCK;
+               lock_st.l_start = 0;
+               lock_st.l_whence = SEEK_SET;
+               lock_st.l_len = 1;
+
+               fcntl(accept_fd, F_SETLK, &lock_st);
+
+               close(accept_fd);
+               unlink(accept_file);
+
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "accept lock file removed: %s", accept_file);
+       }
+
+       close(sock_fd);
+       unlink(sock_file);
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "socket removed: %s", sock_file);
+}
+
+
+/*************************************************************
+ * Handle the comms on the socket, pass the request off to
+ * do_auth() back in saslauthd-main.c, then transmit the
+ * result back out on the socket.
+ **************************************************************/
+void do_request(int conn_fd) {
+
+       unsigned short          count;                     /* input/output data byte count           */
+       unsigned short          ncount;                    /* input/output data byte count, network  */ 
+       char                    *response;                 /* response to send to the client         */
+       char                    login[MAX_REQ_LEN + 1];    /* account name to authenticate           */
+       char                    password[MAX_REQ_LEN + 1]; /* password for authentication            */
+       char                    service[MAX_REQ_LEN + 1];  /* service name for authentication        */
+       char                    realm[MAX_REQ_LEN + 1];    /* user realm for authentication          */
+
+
+       /**************************************************************
+        * The input data stream consists of the login id, password,
+        * service name and user realm as counted length strings.
+        * We read in each string, then dispatch the data.
+        **************************************************************/
+
+       /* login id */
+       if (rx_rec(conn_fd, (void *)&count, (size_t)sizeof(count)) != (ssize_t)sizeof(count)) 
+               return;
+
+       count = ntohs(count);
+
+       if (count > MAX_REQ_LEN) {
+               logger(L_ERR, L_FUNC, "login exceeded MAX_REQ_LEN: %d", MAX_REQ_LEN);
+               send_no(conn_fd, "");
+               return;
+       }       
+
+       if (rx_rec(conn_fd, (void *)login, (size_t)count) != (ssize_t)count) 
+               return;
+       
+       login[count] = '\0';
+
+       /* password */
+       if (rx_rec(conn_fd, (void *)&count, (size_t)sizeof(count)) != (ssize_t)sizeof(count)) 
+               return;
+
+       count = ntohs(count);
+
+       if (count > MAX_REQ_LEN) {
+               logger(L_ERR, L_FUNC, "password exceeded MAX_REQ_LEN: %d", MAX_REQ_LEN);
+               send_no(conn_fd, "");
+               return;
+       }       
+
+       if (rx_rec(conn_fd, (void *)password, (size_t)count) != (ssize_t)count) 
+               return;
+               
+       password[count] = '\0';
+
+       /* service */
+       if (rx_rec(conn_fd, (void *)&count, (size_t)sizeof(count)) != (ssize_t)sizeof(count)) 
+               return;
+
+       count = ntohs(count);
+
+       if (count > MAX_REQ_LEN) {
+               logger(L_ERR, L_FUNC, "service exceeded MAX_REQ_LEN: %d", MAX_REQ_LEN);
+               send_no(conn_fd, "");
+               return;
+       }       
+
+       if (rx_rec(conn_fd, (void *)service, (size_t)count) != (ssize_t)count) 
+               return;
+
+       service[count] = '\0';
+
+       /* realm */
+       if (rx_rec(conn_fd, (void *)&count, (size_t)sizeof(count)) != (ssize_t)sizeof(count)) 
+               return;
+
+       count = ntohs(count);
+
+       if (count > MAX_REQ_LEN) {
+               logger(L_ERR, L_FUNC, "realm exceeded MAX_REQ_LEN: %d", MAX_REQ_LEN);
+               send_no(conn_fd, "");
+               return;
+       }       
+
+       if (rx_rec(conn_fd, (void *)realm, (size_t)count) != (ssize_t)count) 
+               return;
+
+       realm[count] = '\0';
+
+       /**************************************************************
+        * We don't allow NULL passwords or login names
+        **************************************************************/
+       if (*login == '\0') {
+               logger(L_ERR, L_FUNC, "NULL login received");
+               send_no(conn_fd, "NULL login received");
+               return;
+       }       
+       
+       if (*password == '\0') {
+               logger(L_ERR, L_FUNC, "NULL password received");
+               send_no(conn_fd, "NULL password received");
+               return;
+       }       
+
+       /**************************************************************
+        * Get the mechanism response from do_auth() and send it back.
+        **************************************************************/
+       response = do_auth(login, password, service, realm);
+
+       memset(password, 0, strlen(password));
+
+       if (response == NULL) {
+               send_no(conn_fd, "NULL response from mechanism");
+               return;
+       }       
+
+       count = strlen(response);
+       ncount = htons(count);
+
+       if (tx_rec(conn_fd, (void *)&ncount, (size_t)sizeof(ncount)) != (ssize_t)sizeof(ncount)) {
+               free(response);
+               return;
+       }
+
+       if (tx_rec(conn_fd, (void *)response, (size_t)count) != (ssize_t)sizeof(count)) {
+               free(response);
+               return;
+       }
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "response: %s", response);
+
+       free(response);
+
+       return;
+}
+
+
+/*************************************************************
+ * In case something went out to lunch while reading in the
+ * request data, we may want to attempt to send out a default 
+ * "NO" response on the socket. The mesg is optional.
+ **************************************************************/
+void send_no(int conn_fd, char *mesg) {
+       char            buff[1024];
+       unsigned short  count; 
+       unsigned short  ncount; 
+
+       buff[0] = 'N';
+       buff[1] = 'O';
+       buff[2] = ' ';
+
+       /* buff, except for the trailing NUL and 'NO ' */
+       strncpy(buff + 3, mesg, sizeof(buff) - 1 - 3);
+       buff[1023] = '\0';
+
+       count = strlen(buff);
+       ncount = htons(count);
+
+       if (tx_rec(conn_fd, (void *)&ncount, (size_t)sizeof(ncount)) != (ssize_t)sizeof(ncount))
+               return;
+
+       if (tx_rec(conn_fd, (void *)buff, (size_t)count) != (ssize_t)sizeof(count))
+               return;
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "response: %s", buff);
+       
+       return; 
+}
+
+
+/*************************************************************
+ * Attempt to get a write lock on the accept lock file.
+ * Return 0 if everything went ok, return -1 if something bad
+ * happened. This function is expected to block.
+ **************************************************************/
+int get_accept_lock() {
+
+       struct flock    lock_st;
+       int             rc;
+
+
+       if (!(flags & USE_ACCEPT_LOCK))
+               return 0;
+
+       lock_st.l_type = F_WRLCK;
+       lock_st.l_start = 0;
+       lock_st.l_whence = SEEK_SET;
+       lock_st.l_len = 1;
+
+       errno = 0;
+
+       do {
+               rc = fcntl(accept_fd, F_SETLKW, &lock_st);
+       } while (rc != 0 && errno == EINTR);
+
+       if (rc != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not acquire accept lock");
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               return -1;
+       }
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "acquired accept lock");
+
+       return 0;
+}
+
+
+/*************************************************************
+ * Attempt to release the write lock on the accept lock file.
+ * Return 0 if everything went ok, return -1 if something bad
+ * happened.
+ **************************************************************/
+int rel_accept_lock() {
+
+       struct flock    lock_st;
+       int             rc;
+
+
+       if (!(flags & USE_ACCEPT_LOCK))
+               return 0;
+
+       lock_st.l_type = F_UNLCK;
+       lock_st.l_start = 0;
+       lock_st.l_whence = SEEK_SET;
+       lock_st.l_len = 1;
+
+       errno = 0;
+
+       do {
+               rc = fcntl(accept_fd, F_SETLKW, &lock_st);
+       } while (rc != 0 && errno == EINTR);
+
+       if (rc != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not release accept lock");
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               return -1;
+       }
+
+       if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "released accept lock");
+
+       return 0;
+}
+
+
+
+#endif /* USE_UNIX_IPC */
diff --git a/saslauthd/krbtf.c b/saslauthd/krbtf.c
new file mode 100644 (file)
index 0000000..9084c1c
--- /dev/null
@@ -0,0 +1,225 @@
+/* MODULE: krbtf */
+/* 
+ * Copyright (c) 2001 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.
+ */
+
+/*
+ * Dec  4, 2002 by Dave Eckhardt <davide+receptionist@cs.cmu.edu>
+ * $Id: krbtf.c,v 1.2 2005/02/14 05:18:36 shadow Exp $
+ * This is inspired by code which was identical in both
+ * auth_krb4.c and auth_krb5.c.  This code is shared
+ * between the two implementations, contains protection
+ * against a race condition, and, when possible, uses
+ * Heimdal krb5's memory-only credential caches to avoid
+ * needless disk i/o.
+ */
+
+#ifdef __GNUC__
+#ident "$Id: krbtf.c,v 1.2 2005/02/14 05:18:36 shadow Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#ifdef SASLAUTHD_THREADED /* is this really used??? */
+#include <pthread.h>
+#endif /* SASLAUTHD_THREADED */
+
+#include "mechanisms.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <syslog.h>
+
+#ifdef AUTH_KRB4
+#include <auth_krb4.h>
+#define WANT_KRBTF
+#endif /* WANT_KRBTF */
+
+#ifdef AUTH_KRB5
+#include <auth_krb5.h>
+#define WANT_KRBTF
+#endif /* WANT_KRBTF */
+
+#ifdef WANT_KRBTF
+
+/* PRIVATE DEPENDENCIES */
+/* globals */
+
+/* privates */
+static char tf_dir[] = PATH_SASLAUTHD_RUNDIR "/.tf";
+static char *tfn_cookie = 0;
+static int tfn_cookie_len = 0;
+static char pidstring[80];
+int pidstring_len = 0;
+/* END PRIVATE DEPENDENCIES */
+
+#endif /* WANT_KRBTF */
+\f
+/* FUNCTION: krbtf_init */
+
+/* SYNOPSIS
+ * Initialize the Kerberos IV/V ticket-file/credential-cache common code
+ *
+ * When possible, use Heimdal krb5's memory-only credential caches--
+ * this saves a whole bunch of useless disk i/o's to create and destroy
+ * a file which we don't want anybody to see anyway.
+ *
+ * If not, this function will create a private directory for ticket
+ * files and cache getpid() for later use.  Therefore, we must be
+ * called AFTER main() does whatever fork()ing it wants.
+ *
+ * END SYNOPSIS */
+
+int                                    /* R: -1 on failure, else 0 */
+krbtf_init (
+  /* PARAMETERS */
+  void                                 /* no parameters */
+  /* END PARAMETERS */
+  )
+{
+#ifdef WANT_KRBTF
+    /* VARIABLES */
+    int rc;                            /* return code holder */
+    struct stat sb;                    /* stat() work area */
+    /* END VARIABLES */
+    authmech_t *authmech;
+
+#ifdef AUTH_KRB5
+    for (authmech = mechanisms; authmech->name != NULL; authmech++ ) {
+           if (authmech->initialize != auth_krb5_init) continue;
+           /* This execution is using krb5 */
+           /* Both MIT krb5 and Heimdal support MEMORY: ccaches */
+           tfn_cookie = "MEMORY:0";
+           tfn_cookie_len = strlen(tfn_cookie);
+           return 0;
+    }
+#endif /* AUTH_KRB5 */
+
+    if (((rc = mkdir(tf_dir, 0700)) == 0) || (errno == EEXIST)) {
+       if ((rc = lstat(tf_dir, &sb)) == 0) {
+           if (sb.st_mode & S_IFLNK) {
+               syslog(LOG_ERR, "krbtf_init: %s is a symbolic link", tf_dir);
+               return -1;
+           }
+       }
+    }
+
+    if (rc != 0) {
+       syslog(LOG_ERR, "krbtf_init %s: %m", tf_dir);
+       return -1;
+    }
+
+    /* cache getpid() for use in filenames */
+    if ((pidstring_len = snprintf(pidstring, sizeof (pidstring), "%d", getpid())) >= sizeof (pidstring)) {
+           syslog(LOG_ERR, "krbtf_init pidstring too long(!?)");
+           return -1;
+    }
+
+    return 0;
+#else /* WANT_KRBTF */
+       syslog(LOG_ERR, "krbtf_init: not compiled!");
+       return -1;
+#endif /* WANT_KRBTF */
+}
+
+/* END FUNCTION: krbtf_init */
+\f
+/* FUNCTION: krbtf_name */
+
+/* SYNOPSIS
+ * Spit a ticket-file/credentical-cache name into caller's array.
+ *
+ * If we can, emit the magic cookie for a memory-only krb5 ccname
+ * END SYNOPSIS */
+
+int                                    /* R: -1 on failure, else 0 */
+krbtf_name (
+  /* PARAMETERS */
+  char *tfname,                                /* O: where caller wants name */
+  int len                              /* I: available length */
+  /* END PARAMETERS */
+  )
+{
+#ifdef WANT_KRBTF
+    if (tfn_cookie_len) {
+       if (tfn_cookie_len + 1 > len) {
+           syslog(LOG_ERR, "krbtf_name: cookie name (%s) too long", tfn_cookie);
+           return -1;
+       }
+       strcpy(tfname, tfn_cookie);
+    } else {
+       int dir_len = sizeof (tf_dir) - 1; /* don't count the null */
+       int want_len = dir_len + 1 + pidstring_len + 1;
+
+       if (want_len > len) {
+           syslog(LOG_ERR, "krbtf_name: need room for %d bytes, got %d", want_len, len);
+           return -1;
+       }
+
+       strcpy(tfname, tf_dir);
+       tfname += dir_len; len -= dir_len;
+
+       *tfname++ = '/'; len--;
+
+       strcpy(tfname, pidstring);
+
+#ifdef SASLAUTHD_THREADED /* is this really used??? */
+       tfname += pidstring_len;
+       len -= pidstring_len;
+
+       if (snprintf(tfname, len, "_%d", pthread_self() >= len)) {
+           syslog(LOG_ERR, "krbtf_name: no room for thread id");
+           return -1;
+       }
+#endif /* SASLAUTHD_THREADED */
+    }
+
+    return 0;
+#else /* WANT_KRBTF */
+       syslog(LOG_ERR, "krbtf_name: not compiled!");
+       return -1;
+#endif /* WANT_KRBTF */
+}
+/* END FUNCTION: krbtf_name */
+
+/* END MODULE: krbtf */
diff --git a/saslauthd/krbtf.h b/saslauthd/krbtf.h
new file mode 100644 (file)
index 0000000..03ef05d
--- /dev/null
@@ -0,0 +1,42 @@
+/* 
+ * Copyright (c) 2001 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.
+ */
+
+int krbtf_init (void);
+int krbtf_name (char *, int);
diff --git a/saslauthd/lak.c b/saslauthd/lak.c
new file mode 100644 (file)
index 0000000..803d51f
--- /dev/null
@@ -0,0 +1,1787 @@
+/* COPYRIGHT
+ * Copyright (c) 2002-2003 Igor Brezac
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IGOR BREZAC OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifndef AUTH_LDAP
+       #include "mechanisms.h"
+       #include "utils.h"
+#endif
+
+#ifdef AUTH_LDAP
+
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#ifdef HAVE_OPENSSL
+#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+#define OPENSSL_DISABLE_OLD_DES_SUPPORT
+#endif
+#include <openssl/evp.h>
+#include <openssl/des.h>
+#endif
+
+#include <ldap.h>
+#include <lber.h>
+#include <sasl.h>
+#include "lak.h"
+
+typedef struct lak_auth_method {
+       int method;
+       int (*check) (LAK *lak, const char *user, const char *service, const char *realm, const char *password) ;
+} LAK_AUTH_METHOD;
+
+typedef struct lak_hash_rock {
+       const char *mda;
+       int salted;
+} LAK_HASH_ROCK;
+
+typedef struct lak_password_scheme {
+       char *hash;
+       int (*check) (const char *cred, const char *passwd, void *rock);
+       void *rock;
+} LAK_PASSWORD_SCHEME;
+
+static int lak_config_read(LAK_CONF *, const char *);
+static int lak_config_int(const char *);
+static int lak_config_switch(const char *);
+static void lak_config_free(LAK_CONF *);
+static int lak_config(const char *, LAK_CONF **);
+static int lak_escape(const char *, const unsigned int, char **);
+static int lak_tokenize_domains(const char *, int, char **);
+static int lak_expand_tokens(const char *, const char *, const char *, const char *, const char *, char **);
+static int lak_connect(LAK *);
+static int lak_bind(LAK *, LAK_USER *);
+static void lak_unbind(LAK *);
+static int lak_auth_custom(LAK *, const char *, const char *, const char *, const char *);
+static int lak_auth_bind(LAK *, const char *, const char *, const char *, const char *);
+static int lak_auth_fastbind(LAK *, const char *, const char *, const char *, const char *);
+static int lak_group_member(LAK *, const char *, const char *, const char *, const char *);
+static char *lak_result_get(const LAK_RESULT *, const char *);
+static int lak_result_add(const char *, const char *, LAK_RESULT **);
+static int lak_check_password(const char *, const char *, void *);
+static int lak_check_crypt(const char *, const char *, void *);
+#ifdef HAVE_OPENSSL
+static int lak_base64_decode(const char *, char **, int *);
+static int lak_check_hashed(const char *, const char *, void *);
+#endif
+static int lak_sasl_interact(LDAP *, unsigned, void *, void *);
+static int lak_user(const char *, const char *, const char *, const char *, const char *, const char *, LAK_USER **);
+static int lak_user_copy(LAK_USER **, const LAK_USER *);
+static int lak_user_cmp(const LAK_USER *, const LAK_USER *);
+static void lak_user_free(LAK_USER *);
+
+static LAK_AUTH_METHOD authenticator[] = {
+       { LAK_AUTH_METHOD_BIND, lak_auth_bind },
+       { LAK_AUTH_METHOD_CUSTOM, lak_auth_custom },
+       { LAK_AUTH_METHOD_FASTBIND, lak_auth_fastbind },
+       { -1, NULL }
+};
+
+static LAK_HASH_ROCK hash_rock[] = {
+       { "md5", 0 },
+       { "md5", 1 },
+       { "sha1", 0 },
+       { "sha1", 1 }
+};
+
+static LAK_PASSWORD_SCHEME password_scheme[] = {
+       { "{CRYPT}", lak_check_crypt, NULL },
+       { "{UNIX}", lak_check_crypt, NULL },
+#ifdef HAVE_OPENSSL
+       { "{MD5}", lak_check_hashed, &hash_rock[0] },
+       { "{SMD5}", lak_check_hashed, &hash_rock[1] },
+       { "{SHA}", lak_check_hashed, &hash_rock[2] },
+       { "{SSHA}", lak_check_hashed, &hash_rock[3] },
+#endif
+       { NULL, NULL, NULL }
+};
+
+static const char *dn_attr = "dn";
+
+#define ISSET(x)  ((x != NULL) && (*(x) != '\0'))
+#define EMPTY(x)  ((x == NULL) || (*(x) == '\0'))
+
+static int lak_config_read(
+       LAK_CONF *conf,
+       const char *configfile)
+{
+       FILE *infile;
+       int lineno = 0;
+       char buf[4096];
+       char *p, *key;
+
+       infile = fopen(configfile, "r");
+       if (!infile) {
+           syslog(LOG_ERR|LOG_AUTH,
+                  "Could not open saslauthd config file: %s (%m)",
+                  configfile);
+           return LAK_FAIL;
+       }
+    
+       while (fgets(buf, sizeof(buf), infile)) {
+               lineno++;
+
+               if (buf[strlen(buf)-1] == '\n') 
+                       buf[strlen(buf)-1] = '\0';
+               for (p = buf; *p && isspace((int) *p); p++);
+                       if (!*p || *p == '#') 
+                               continue;
+
+               key = p;
+               while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) {
+                       if (isupper((int) *p)) 
+                               *p = tolower(*p);
+                       p++;
+               }
+               if (*p != ':')
+                       return LAK_FAIL;
+               
+               *p++ = '\0';
+
+               while (*p && isspace((int) *p)) 
+                       p++;
+
+               if (!*p)
+                       return LAK_FAIL;
+
+               if (!strcasecmp(key, "ldap_servers"))
+                       strlcpy(conf->servers, p, LAK_URL_LEN);
+
+               else if (!strcasecmp(key, "ldap_bind_dn"))
+                       strlcpy(conf->bind_dn, p, LAK_DN_LEN);
+
+               else if (!strcasecmp(key, "ldap_bind_pw") ||
+                        !strcasecmp(key, "ldap_password"))
+                       strlcpy(conf->password, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_version"))
+                       conf->version = lak_config_int(p);
+
+               else if (!strcasecmp(key, "ldap_search_base"))
+                       strlcpy(conf->search_base, p, LAK_DN_LEN);
+
+               else if (!strcasecmp(key, "ldap_filter"))
+                       strlcpy(conf->filter, p, LAK_DN_LEN);
+               
+               else if (!strcasecmp(key, "ldap_password_attr"))
+                       strlcpy(conf->password_attr, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_group_dn"))
+                       strlcpy(conf->group_dn, p, LAK_DN_LEN);
+               
+               else if (!strcasecmp(key, "ldap_group_attr"))
+                       strlcpy(conf->group_attr, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_group_filter"))
+                       strlcpy(conf->group_filter, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_group_search_base"))
+                       strlcpy(conf->group_search_base, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_group_scope")) {
+                       if (!strcasecmp(p, "one")) {
+                               conf->group_scope = LDAP_SCOPE_ONELEVEL;
+                       } else if (!strcasecmp(p, "base")) {
+                               conf->group_scope = LDAP_SCOPE_BASE;
+                       }
+               } else if (!strcasecmp(key, "ldap_group_match_method")) {
+                       if (!strcasecmp(p, "filter")) {
+                               conf->group_match_method = LAK_GROUP_MATCH_METHOD_FILTER;
+                       } else if (!strcasecmp(p, "attr")) {
+                               conf->group_match_method = LAK_GROUP_MATCH_METHOD_ATTR;
+                       }
+               } else if (!strcasecmp(key, "ldap_default_realm") ||
+                        !strcasecmp(key, "ldap_default_domain"))
+                       strlcpy(conf->default_realm, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_auth_method")) {
+                       if (!strcasecmp(p, "custom")) {
+                               conf->auth_method = LAK_AUTH_METHOD_CUSTOM;
+                       } else if (!strcasecmp(p, "fastbind")) {
+                               conf->auth_method = LAK_AUTH_METHOD_FASTBIND;
+                       }
+               } else if (!strcasecmp(key, "ldap_timeout")) {
+                       conf->timeout.tv_sec = lak_config_int(p);
+                       conf->timeout.tv_usec = 0;
+               } else if (!strcasecmp(key, "ldap_size_limit"))
+                       conf->size_limit = lak_config_int(p);
+
+               else if (!strcasecmp(key, "ldap_time_limit"))
+                       conf->time_limit = lak_config_int(p);
+
+               else if (!strcasecmp(key, "ldap_deref")) {
+                       if (!strcasecmp(p, "search")) {
+                               conf->deref = LDAP_DEREF_SEARCHING;
+                       } else if (!strcasecmp(p, "find")) {
+                               conf->deref = LDAP_DEREF_FINDING;
+                       } else if (!strcasecmp(p, "always")) {
+                               conf->deref = LDAP_DEREF_ALWAYS;
+                       } else if (!strcasecmp(p, "never")) {
+                               conf->deref = LDAP_DEREF_NEVER;
+                       }
+               } else if (!strcasecmp(key, "ldap_referrals")) {
+                       conf->referrals = lak_config_switch(p);
+
+               } else if (!strcasecmp(key, "ldap_restart")) {
+                       conf->restart = lak_config_switch(p);
+
+               } else if (!strcasecmp(key, "ldap_scope")) {
+                       if (!strcasecmp(p, "one")) {
+                               conf->scope = LDAP_SCOPE_ONELEVEL;
+                       } else if (!strcasecmp(p, "base")) {
+                               conf->scope = LDAP_SCOPE_BASE;
+                       }
+               } else if (!strcasecmp(key, "ldap_use_sasl")) {
+                       conf->use_sasl = lak_config_switch(p);
+
+               } else if (!strcasecmp(key, "ldap_id") ||
+                   !strcasecmp(key, "ldap_sasl_authc_id"))
+                       strlcpy(conf->id, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_authz_id") ||
+                 !strcasecmp(key, "ldap_sasl_authz_id"))
+                       strlcpy(conf->authz_id, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_realm") ||
+                 !strcasecmp(key, "ldap_sasl_realm"))
+                       strlcpy(conf->realm, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_mech") ||
+                 !strcasecmp(key, "ldap_sasl_mech"))
+                       strlcpy(conf->mech, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_sasl_secprops"))
+                       strlcpy(conf->sasl_secprops, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_start_tls"))
+                       conf->start_tls = lak_config_switch(p);
+
+               else if (!strcasecmp(key, "ldap_tls_check_peer"))
+                       conf->tls_check_peer = lak_config_switch(p);
+
+               else if (!strcasecmp(key, "ldap_tls_cacert_file"))
+                       strlcpy(conf->tls_cacert_file, p, LAK_PATH_LEN);
+
+               else if (!strcasecmp(key, "ldap_tls_cacert_dir"))
+                       strlcpy(conf->tls_cacert_dir, p, LAK_PATH_LEN);
+
+               else if (!strcasecmp(key, "ldap_tls_ciphers"))
+                       strlcpy(conf->tls_ciphers, p, LAK_BUF_LEN);
+
+               else if (!strcasecmp(key, "ldap_tls_cert"))
+                       strlcpy(conf->tls_cert, p, LAK_PATH_LEN);
+
+               else if (!strcasecmp(key, "ldap_tls_key"))
+                       strlcpy(conf->tls_key, p, LAK_PATH_LEN);
+
+               else if (!strcasecmp(key, "ldap_debug"))
+                       conf->debug = lak_config_int(p);
+       }
+
+       if (conf->version != LDAP_VERSION3 && 
+           (conf->use_sasl ||
+            conf->start_tls))
+           conf->version = LDAP_VERSION3;
+
+    if (conf->use_sasl &&
+        conf->auth_method == LAK_AUTH_METHOD_BIND)
+        conf->auth_method = LAK_AUTH_METHOD_FASTBIND;
+
+    if ( ISSET(conf->group_filter) &&
+         ISSET(conf->search_base) &&
+         EMPTY(conf->group_search_base) )
+        strlcpy(conf->group_search_base, conf->search_base, LAK_DN_LEN);
+        
+       fclose(infile);
+
+       return LAK_OK;
+}
+
+static int lak_config_int(
+       const char *val)
+{
+    if (!val) return 0;
+
+    if (!isdigit((int) *val) && (*val != '-' || !isdigit((int) val[1]))) return 0;
+
+    return atoi(val);
+}
+
+static int lak_config_switch(
+       const char *val)
+{
+    if (!val) return 0;
+    
+    if (*val == '0' || *val == 'n' ||
+       (*val == 'o' && val[1] == 'f') || *val == 'f') {
+       return 0;
+    } else if (*val == '1' || *val == 'y' ||
+            (*val == 'o' && val[1] == 'n') || *val == 't') {
+       return 1;
+    }
+    return 0;
+}
+
+static int lak_config(
+       const char *configfile, 
+       LAK_CONF **ret)
+{
+       LAK_CONF *conf;
+       int rc = 0;
+
+       conf = malloc( sizeof(LAK_CONF) );
+       if (conf == NULL) {
+               return LAK_NOMEM;
+       }
+
+       memset(conf, 0, sizeof(LAK_CONF));
+
+       strlcpy(conf->servers, "ldap://localhost/", LAK_BUF_LEN);
+       conf->version = LDAP_VERSION3;
+       strlcpy(conf->filter, "(uid=%u)", LAK_DN_LEN);
+       strlcpy(conf->password_attr, "userPassword", LAK_BUF_LEN);
+       conf->scope = LDAP_SCOPE_SUBTREE;
+       strlcpy(conf->group_attr, "uniqueMember", LAK_BUF_LEN);
+       conf->group_scope = LDAP_SCOPE_SUBTREE;
+    conf->group_match_method = LAK_GROUP_MATCH_METHOD_ATTR;
+       conf->auth_method = LAK_AUTH_METHOD_BIND;
+       conf->timeout.tv_sec = 5;
+       conf->timeout.tv_usec = 0;
+       conf->size_limit = 1;
+       conf->time_limit = 5;
+       conf->deref = LDAP_DEREF_NEVER;
+       conf->restart = 1;
+       conf->start_tls = 0;
+       conf->use_sasl = 0;
+
+       strlcpy(conf->path, configfile, LAK_PATH_LEN);
+
+       rc = lak_config_read(conf, conf->path);
+       if (rc != LAK_OK) {
+               lak_config_free(conf);
+               return rc;
+       }
+
+       *ret = conf;
+       return LAK_OK;
+}
+
+static void lak_config_free(
+       LAK_CONF *conf) 
+{
+       if (conf == NULL) {
+               return;
+       }
+
+       memset(conf, 0, sizeof(LAK_CONF));
+
+       free (conf);
+
+       return;
+}
+
+/*
+ * Note: calling function must free memory.
+ */
+static int lak_escape(
+       const char *s, 
+       const unsigned int n, 
+       char **result) 
+{
+       char *buf;
+       char *end, *ptr, *temp;
+
+       if (n > strlen(s))  // Sanity check, just in case
+               return LAK_FAIL;
+
+       buf = malloc(n * 5 + 1);
+       if (buf == NULL) {
+               return LAK_NOMEM;
+       }
+
+       buf[0] = '\0';
+       ptr = (char *)s;
+       end = ptr + n;
+
+       while (((temp = strpbrk(ptr, "*()\\\0"))!=NULL) && (temp<end)) {
+
+               if (temp>ptr)
+                       strncat(buf, ptr, temp-ptr);
+
+               switch (*temp) {
+                       case '*':
+                               strcat(buf, "\\2a");
+                               break;
+                       case '(':
+                               strcat(buf, "\\28");
+                               break;
+                       case ')':
+                               strcat(buf, "\\29");
+                               break;
+                       case '\\':
+                               strcat(buf, "\\5c");
+                               break;
+                       case '\0':
+                               strcat(buf, "\\00");
+                               break;
+               }
+               ptr=temp+1;
+       }
+       if (ptr<end)
+               strncat(buf, ptr, end-ptr);
+
+       *result = buf;
+
+       return LAK_OK;
+}
+
+static int lak_tokenize_domains(
+       const char *d, 
+       int n, 
+       char **result)
+{
+       char *s, *s1;
+       char *lasts;
+       int nt, i, rc;
+
+       *result = NULL;
+
+       if (d == NULL || n < 1 || n > 9)
+               return LAK_FAIL;
+
+       s = strdup(d);
+       if (s == NULL)
+               return LAK_NOMEM;
+
+       for( nt=0, s1=s; *s1; s1++ )
+               if( *s1 == '.' ) nt++;
+       nt++;
+
+       if (n > nt) {
+               free(s);
+               return LAK_FAIL;
+       }
+
+       i = nt - n;
+       s1 = (char *)strtok_r(s, ".", &lasts);
+       while(s1) {
+               if (i == 0) {
+                       rc = lak_escape(s1, strlen(s1), result);
+                       free(s);
+                       return rc;
+               }
+               s1 = (char *)strtok_r(NULL, ".", &lasts);
+               i--;
+       }
+
+       free(s);
+       return LAK_FAIL;
+}
+
+#define LAK_MAX(a,b) (a>b?a:b)
+
+/*
+ * lak_expand_tokens
+ * Parts with the strings provided.
+ *   %%   = %
+ *   %u   = user
+ *   %U   = user part of %u
+ *   %d   = domain part of %u if available, othwise same as %r
+ *   %1-9 = domain if not available realm, token
+ *          (%1 = tld, %2 = domain when %r = domain.tld)
+ *   %s   = service
+ *   %r   = realm
+ *   %R   = prepend '@' to realm
+ *   %D   = user DN
+ * Note: calling function must free memory.
+ */
+static int lak_expand_tokens(
+       const char *pattern,
+       const char *username, 
+       const char *service,
+       const char *realm,
+       const char *dn,
+       char **result) 
+{
+       char *buf; 
+       char *end, *ptr, *temp;
+       char *ebuf, *user;
+       char *domain;
+       int rc;
+
+       /* to permit multiple occurences of username and/or realm in filter */
+       /* and avoid memory overflow in filter build [eg: (|(uid=%u)(userid=%u)) ] */
+       int percents, service_len, realm_len, dn_len, user_len, maxparamlength;
+       
+       if (pattern == NULL) {
+               syslog(LOG_ERR|LOG_AUTH, "filter pattern not setup");
+               return LAK_FAIL;
+       }
+
+       /* find the longest param of username and realm, 
+          do not worry about domain because it is always shorter 
+          then username                                           */
+       user_len=ISSET(username) ? strlen(username) : 0;
+       service_len=ISSET(service) ? strlen(service) : 0;
+       realm_len=ISSET(realm) ? strlen(realm) : 0;
+       dn_len=ISSET(dn) ? strlen(dn) : 0;
+
+       maxparamlength = LAK_MAX(user_len, service_len);
+       maxparamlength = LAK_MAX(maxparamlength, realm_len + 1);  /* +1 for %R when '@' is prepended */
+       maxparamlength = LAK_MAX(maxparamlength, dn_len);
+
+       /* find the number of occurences of percent sign in filter */
+       for( percents=0, buf=(char *)pattern; *buf; buf++ ) {
+               if( *buf == '%' ) percents++;
+       }
+
+       /* percents * 3 * maxparamlength because we need to account for
+         * an entirely-escaped worst-case-length parameter */
+       buf=malloc(strlen(pattern) + (percents * 3 * maxparamlength) + 1);
+       if(buf == NULL)
+               return LAK_NOMEM;
+       buf[0] = '\0';
+       
+       ptr = (char *)pattern;
+       end = ptr + strlen(ptr);
+
+       while ((temp=strchr(ptr,'%'))!=NULL ) {
+
+               if ((temp-ptr) > 0)
+                       strncat(buf, ptr, temp-ptr);
+
+               if ((temp+1) >= end) {
+                       syslog(LOG_DEBUG|LOG_AUTH, "Incomplete lookup substitution format");
+                       break;
+               }
+
+               switch (*(temp+1)) {
+                       case '%':
+                               strncat(buf,temp+1,1);
+                               break;
+                       case 'u':
+                               if (ISSET(username)) {
+                                       rc=lak_escape(username, strlen(username), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "Username not available.");
+                               break;
+                       case 'U':
+                               if (ISSET(username)) {
+                                       user = strchr(username, '@');
+                                       rc=lak_escape(username, (user ? user - username : strlen(username)), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "Username not available.");
+                               break;
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                       case '8':
+                       case '9':
+                               if (ISSET(username) && 
+                                   ((domain = strchr(username, '@')) && domain[1]!='\0')) {
+                                       rc=lak_tokenize_domains(domain+1, (int) *(temp+1)-48, &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else if (ISSET(realm)) {
+                                       rc=lak_tokenize_domains(realm, (int) *(temp+1)-48, &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "Domain/Realm not available.");
+                               break;
+                       case 'd':
+                               if (ISSET(username) && 
+                                   ((domain = strchr(username, '@')) && domain[1]!='\0')) {
+                                       rc=lak_escape(domain+1, strlen(domain+1), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                                       break;
+                               } 
+                       case 'R':
+                       case 'r':
+                               if (ISSET(realm)) {
+                                       rc = lak_escape(realm, strlen(realm), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               if (*(temp+1) == 'R')
+                                                       strcat(buf,"@");
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "Domain/Realm not available.");
+                               break;
+                       case 's':
+                               if (ISSET(service)) {
+                                       rc = lak_escape(service, strlen(service), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "Service not available.");
+                               break;
+                       case 'D':
+                               if (ISSET(dn)) {
+                                       rc = lak_escape(dn, strlen(dn), &ebuf);
+                                       if (rc == LAK_OK) {
+                                               strcat(buf,ebuf);
+                                               free(ebuf);
+                                       }
+                               } else
+                                       syslog(LOG_DEBUG|LOG_AUTH, "User DN not available.");
+                               break;
+                       default:
+                               break;
+               }
+               ptr=temp+2;
+       }
+       if (temp<end)
+               strcat(buf, ptr);
+
+       *result = buf;
+
+       return LAK_OK;
+}
+
+int lak_init(
+       const char *configfile, 
+       LAK **ret) 
+{
+       LAK *lak;
+       int rc;
+
+       lak = *ret;
+
+       if (lak != NULL) {
+               return LAK_OK;
+       }
+
+       lak = (LAK *)malloc(sizeof(LAK));
+       if (lak == NULL)
+               return LAK_NOMEM;
+
+       lak->status=LAK_NOT_BOUND;
+       lak->ld=NULL;
+       lak->conf=NULL;
+       lak->user=NULL;
+
+       rc = lak_config(configfile, &lak->conf);
+       if (rc != LAK_OK) {
+               free(lak);
+               return rc;
+       }
+
+#ifdef HAVE_OPENSSL
+       OpenSSL_add_all_digests();
+#endif
+
+       *ret=lak;
+       return LAK_OK;
+}
+
+void lak_close(
+       LAK *lak) 
+{
+
+       if (lak == NULL)
+               return;
+
+       lak_config_free(lak->conf);
+
+       lak_unbind(lak);
+
+       free(lak);
+
+#ifdef HAVE_OPENSSL
+       EVP_cleanup();
+#endif
+
+       return;
+}
+
+static int lak_connect(
+       LAK *lak)
+{
+       int rc = 0;
+       char *p = NULL;
+
+       if (ISSET(lak->conf->tls_cacert_file)) {
+               rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTFILE, lak->conf->tls_cacert_file);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CACERTFILE (%s).", ldap_err2string (rc));
+               }
+       }
+
+       if (ISSET(lak->conf->tls_cacert_dir)) {
+               rc = ldap_set_option (NULL, LDAP_OPT_X_TLS_CACERTDIR, lak->conf->tls_cacert_dir);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CACERTDIR (%s).", ldap_err2string (rc));
+               }
+       }
+
+       if (lak->conf->tls_check_peer != 0) {
+               rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &lak->conf->tls_check_peer);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_REQUIRE_CERT (%s).", ldap_err2string (rc));
+               }
+       }
+
+       if (ISSET(lak->conf->tls_ciphers)) {
+               /* set cipher suite, certificate and private key: */
+               rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE, lak->conf->tls_ciphers);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CIPHER_SUITE (%s).", ldap_err2string (rc));
+               }
+       }
+
+       if (ISSET(lak->conf->tls_cert)) {
+               rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE, lak->conf->tls_cert);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_CERTFILE (%s).", ldap_err2string (rc));
+               }
+       }
+
+       if (ISSET(lak->conf->tls_key)) {
+               rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE, lak->conf->tls_key);
+               if (rc != LDAP_SUCCESS) {
+                       syslog (LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_X_TLS_KEYFILE (%s).", ldap_err2string (rc));
+               }
+       }
+
+       rc = ldap_initialize(&lak->ld, lak->conf->servers);
+       if (rc != LDAP_SUCCESS) {
+               syslog(LOG_ERR|LOG_AUTH, "ldap_initialize failed (%s)", lak->conf->servers);
+               return LAK_CONNECT_FAIL;
+       }
+
+       if (lak->conf->debug) {
+               rc = ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(lak->conf->debug));
+               if (rc != LDAP_OPT_SUCCESS)
+                       syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_DEBUG_LEVEL %x.", lak->conf->debug);
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_PROTOCOL_VERSION, &(lak->conf->version));
+       if (rc != LDAP_OPT_SUCCESS) {
+
+               if (lak->conf->use_sasl ||
+                   lak->conf->start_tls) {
+                       syslog(LOG_ERR|LOG_AUTH, "Failed to set LDAP_OPT_PROTOCOL_VERSION %d, required for ldap_start_tls and ldap_use_sasl.", lak->conf->version);
+                       lak_unbind(lak);
+                       return LAK_CONNECT_FAIL;
+               } else
+                       syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_PROTOCOL_VERSION %d.", lak->conf->version);
+
+               lak->conf->version = LDAP_VERSION2;
+
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_NETWORK_TIMEOUT, &(lak->conf->timeout));
+       if (rc != LDAP_OPT_SUCCESS) {
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_NETWORK_TIMEOUT %d.%d.", lak->conf->timeout.tv_sec, lak->conf->timeout.tv_usec);
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_TIMELIMIT, &(lak->conf->time_limit));
+       if (rc != LDAP_OPT_SUCCESS) {
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_TIMELIMIT %d.", lak->conf->time_limit);
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_DEREF, &(lak->conf->deref));
+       if (rc != LDAP_OPT_SUCCESS) {
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_DEREF %d.", lak->conf->deref);
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_REFERRALS, lak->conf->referrals ? LDAP_OPT_ON : LDAP_OPT_OFF);
+       if (rc != LDAP_OPT_SUCCESS) {
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_REFERRALS.");
+       }
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_SIZELIMIT, &(lak->conf->size_limit));
+       if (rc != LDAP_OPT_SUCCESS)
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_SIZELIMIT %d.", lak->conf->size_limit);
+
+       rc = ldap_set_option(lak->ld, LDAP_OPT_RESTART, lak->conf->restart ? LDAP_OPT_ON : LDAP_OPT_OFF);
+       if (rc != LDAP_OPT_SUCCESS) {
+               syslog(LOG_WARNING|LOG_AUTH, "Unable to set LDAP_OPT_RESTART.");
+       }
+
+       if (lak->conf->start_tls) {
+
+               rc = ldap_start_tls_s(lak->ld, NULL, NULL);
+               if (rc != LDAP_SUCCESS) {
+                       syslog(LOG_ERR|LOG_AUTH, "start tls failed (%s).", ldap_err2string(rc));
+                       lak_unbind(lak);
+                       return LAK_CONNECT_FAIL;
+               }
+       }
+       
+       if (lak->conf->use_sasl) {
+
+               if (EMPTY(lak->conf->mech)) {
+                       ldap_get_option(lak->ld, LDAP_OPT_X_SASL_MECH, &p);
+                       if (p)
+                               strlcpy(lak->conf->mech, p, LAK_BUF_LEN);
+               }
+
+               if (EMPTY(lak->conf->realm)) {
+                       ldap_get_option(lak->ld, LDAP_OPT_X_SASL_REALM, &p);
+                       if (p)
+                               strlcpy(lak->conf->realm, p, LAK_BUF_LEN);
+               }
+
+               if (ISSET(lak->conf->sasl_secprops)) {
+                       rc = ldap_set_option(lak->ld, LDAP_OPT_X_SASL_SECPROPS, (void *) lak->conf->sasl_secprops);
+                       if( rc != LDAP_OPT_SUCCESS ) {
+                               syslog(LOG_ERR|LOG_AUTH, "Unable to set LDAP_OPT_X_SASL_SECPROPS.");
+                               lak_unbind(lak);
+                               return LAK_CONNECT_FAIL;
+                       }
+               }
+       }
+
+
+       return LAK_OK;
+}
+
+static int lak_user(
+       const char *bind_dn, 
+       const char *id, 
+       const char *authz_id, 
+       const char *mech, 
+       const char *realm, 
+       const char *password, 
+       LAK_USER **ret)
+{
+       LAK_USER *lu = NULL;
+       
+       *ret = NULL;
+
+       lu = (LAK_USER *)malloc(sizeof(LAK_USER));
+       if (lu == NULL)
+               return LAK_NOMEM;
+
+       memset(lu, 0, sizeof(LAK_USER));
+
+       if (ISSET(bind_dn))
+               strlcpy(lu->bind_dn, bind_dn, LAK_DN_LEN);
+
+       if (ISSET(id))
+               strlcpy(lu->id, id, LAK_BUF_LEN);
+
+       if (ISSET(authz_id))
+               strlcpy(lu->authz_id, authz_id, LAK_BUF_LEN);
+
+       if (ISSET(mech))
+               strlcpy(lu->mech, mech, LAK_BUF_LEN);
+
+       if (ISSET(realm))
+               strlcpy(lu->realm, realm, LAK_BUF_LEN);
+
+       if (ISSET(password))
+               strlcpy(lu->password, password, LAK_BUF_LEN);
+       
+       *ret = lu;
+       return LAK_OK;
+}
+
+static int lak_user_cmp(
+       const LAK_USER *lu1,
+       const LAK_USER *lu2)
+{
+
+       if (lu1 == NULL ||
+           lu2 == NULL)
+               return LAK_FAIL;
+       
+       if (memcmp(lu1, lu2, sizeof(LAK_USER)) == 0)
+               return LAK_OK;
+
+       return LAK_FAIL;
+}
+
+static int lak_user_copy(
+       LAK_USER **lu1,
+       const LAK_USER *lu2)
+{
+       LAK_USER *lu;
+
+       lu = *lu1;
+
+       if (lu2 == NULL)
+               return LAK_FAIL;
+
+       if (lu == NULL) {
+               lu = (LAK_USER *)malloc(sizeof(LAK_USER));
+               if (lu == NULL)
+                       return LAK_NOMEM;
+               
+               *lu1 = lu;
+       }
+
+       memcpy((void *)lu, (void *)lu2, sizeof(LAK_USER));
+
+       return LAK_OK;
+}
+
+static void lak_user_free(
+       LAK_USER *user)
+{
+       if (user == NULL) {
+               return;
+       }
+
+       memset(user, 0, sizeof(LAK_USER));
+
+       free(user);
+
+       return;
+}
+
+static int lak_sasl_interact(
+       LDAP *ld, 
+       unsigned flags __attribute__((unused)), 
+       void *def, 
+       void *inter)
+{
+       sasl_interact_t *in = inter;
+       const char *p;
+       LAK_USER *lu = def;
+
+       for (;in->id != SASL_CB_LIST_END;in++) {
+               p = NULL;
+               switch(in->id) {
+                       case SASL_CB_AUTHNAME:
+                               if (ISSET(lu->id))
+                                       p = lu->id;
+                               if (!p)
+                                       ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHCID, &p);
+                               break;
+                       case SASL_CB_USER:
+                               if (ISSET(lu->authz_id))
+                                       p = lu->authz_id;
+                               if (!p)
+                                       ldap_get_option( ld, LDAP_OPT_X_SASL_AUTHZID, &p);
+                               break;
+                       case SASL_CB_GETREALM:
+                               if (ISSET(lu->realm))
+                                       p = lu->realm;
+                               break;          
+                       case SASL_CB_PASS:
+                               if (ISSET(lu->password))
+                                       p = lu->password;
+                               break;
+               }
+
+               in->result = ISSET(p) ? p : "";
+               in->len = strlen(in->result);
+       }
+
+       return LDAP_SUCCESS;
+}
+
+static int lak_bind(
+       LAK *lak, 
+       LAK_USER *user)
+{
+       int rc;
+
+       if (user == NULL)  // Sanity Check
+               return LAK_FAIL;
+
+       if ((lak->status == LAK_BOUND) &&
+           (lak_user_cmp(lak->user, user) == LAK_OK))
+               return LAK_OK;
+
+       lak_user_free(lak->user);
+       lak->user = NULL;
+
+       if (
+#if LDAP_VENDOR_VERSION < 20204
+        lak->conf->use_sasl ||
+#endif
+           lak->conf->version == LDAP_VERSION2) 
+               lak->status = LAK_NOT_BOUND;
+
+       if (lak->status == LAK_NOT_BOUND) {
+               lak_unbind(lak);
+               rc = lak_connect(lak);
+               if (rc != LAK_OK)
+                       return rc;
+       }
+
+       if (lak->conf->use_sasl)
+               rc = ldap_sasl_interactive_bind_s(
+                       lak->ld, 
+                       user->bind_dn,
+                       user->mech, 
+                       NULL, 
+                       NULL, 
+                       LDAP_SASL_QUIET, 
+                       lak_sasl_interact, 
+                       user);
+       else
+               rc = ldap_simple_bind_s(lak->ld, user->bind_dn, user->password);
+
+       switch (rc) {
+               case LDAP_SUCCESS:
+                       break;
+        case LDAP_INVALID_CREDENTIALS:
+        case LDAP_INSUFFICIENT_ACCESS:
+        case LDAP_INVALID_DN_SYNTAX:
+        case LDAP_OTHER: 
+                       lak->status = LAK_NOT_BOUND;
+            return LAK_BIND_FAIL;
+               case LDAP_TIMEOUT:
+               case LDAP_SERVER_DOWN:
+               default:
+                       syslog(LOG_DEBUG|LOG_AUTH,
+                                  (lak->conf->use_sasl ? "ldap_sasl_interactive_bind() failed %d (%s)." : "ldap_simple_bind() failed %d (%s)."), rc, ldap_err2string(rc));
+                       lak->status = LAK_NOT_BOUND;
+                       return LAK_RETRY;
+       }
+
+       rc = lak_user_copy(&(lak->user), user);
+       if (rc != LAK_OK)
+               return rc;
+
+       lak->status = LAK_BOUND;
+
+       return LAK_OK;
+}
+
+static void lak_unbind(
+       LAK *lak)
+{
+       if (!lak)
+               return;
+
+       lak_user_free(lak->user);
+
+       if (lak->ld)
+               ldap_unbind(lak->ld);
+
+       lak->ld = NULL;
+       lak->user = NULL;
+       lak->status = LAK_NOT_BOUND;
+
+       return;
+}
+
+/* 
+ * lak_retrieve - retrieve user@realm values specified by 'attrs'
+ */
+int lak_retrieve(
+       LAK *lak, 
+       const char *user, 
+       const char *service, 
+       const char *realm, 
+       const char **attrs, 
+       LAK_RESULT **ret)
+{
+       int rc = 0, i;
+       char *filter = NULL;
+       char *search_base = NULL;
+       LDAPMessage *res = NULL;
+       LDAPMessage *entry = NULL;
+       BerElement *ber = NULL;
+       char *attr = NULL, **vals = NULL, *dn = NULL;
+       LAK_USER *lu = NULL;
+    
+       *ret = NULL;
+
+       if (lak == NULL) {
+               syslog(LOG_ERR|LOG_AUTH, "lak_init did not run.");
+               return LAK_FAIL;
+       }
+
+       if (EMPTY(user))
+               return LAK_FAIL;
+
+       if (EMPTY(realm))
+               realm = lak->conf->default_realm;
+
+       rc = lak_user(  
+               lak->conf->bind_dn,
+               lak->conf->id,
+               lak->conf->authz_id,
+               lak->conf->mech,
+               lak->conf->realm,
+               lak->conf->password,
+               &lu);
+       if (rc != LAK_OK)
+               return rc;
+
+       rc = lak_bind(lak, lu);
+       if (rc != LAK_OK)
+               goto done;
+
+       rc = lak_expand_tokens(lak->conf->filter, user, service, realm, NULL, &filter);
+       if (rc != LAK_OK)
+        goto done;
+
+       rc = lak_expand_tokens(lak->conf->search_base, user, service, realm, NULL, &search_base);
+       if (rc != LAK_OK)
+        goto done;
+
+       rc = ldap_search_st(lak->ld, search_base, lak->conf->scope, filter, (char **) attrs, 0, &(lak->conf->timeout), &res);
+       switch (rc) {
+               case LDAP_SUCCESS:
+               case LDAP_NO_SUCH_OBJECT:
+                       break;
+               case LDAP_TIMELIMIT_EXCEEDED:
+               case LDAP_BUSY:
+               case LDAP_UNAVAILABLE:
+               case LDAP_INSUFFICIENT_ACCESS:
+                       /*  We do not need to re-connect to the LDAP server 
+                           under these conditions */
+                       syslog(LOG_ERR|LOG_AUTH, "user ldap_search_st() failed: %s", ldap_err2string(rc));
+            rc = LAK_USER_NOT_FOUND;
+                       goto done;
+               case LDAP_TIMEOUT:
+               case LDAP_SERVER_DOWN:
+               default:
+                       syslog(LOG_ERR|LOG_AUTH, "user ldap_search_st() failed: %s", ldap_err2string(rc));
+            rc = LAK_RETRY;
+                       lak->status = LAK_NOT_BOUND;
+                       goto done;
+       }
+
+    i = ldap_count_entries(lak->ld, res);
+    if (i != 1) {
+        if (i == 0)
+                       syslog(LOG_DEBUG|LOG_AUTH, "Entry not found (%s).", filter);
+        else
+            syslog(LOG_DEBUG|LOG_AUTH, "Duplicate entries found (%s).", filter);
+        rc = LAK_USER_NOT_FOUND;
+        goto done;
+    }
+       
+    rc = LAK_FAIL;
+
+       if ((entry = ldap_first_entry(lak->ld, res)) != NULL)  {
+        for (i=0; attrs[i] != NULL; i++) {
+            
+            if (!strcmp(attrs[i], dn_attr)) {
+                dn = ldap_get_dn(lak->ld, entry);
+                if (dn == NULL)
+                    goto done;
+
+                rc = lak_result_add(dn_attr, dn, ret);
+                if (rc != LAK_OK) {
+                    lak_result_free(*ret);
+                    *ret = NULL;
+                    goto done;
+                }
+            }
+        }
+
+        for (attr = ldap_first_attribute(lak->ld, entry, &ber); attr != NULL; 
+            attr = ldap_next_attribute(lak->ld, entry, ber)) {
+
+            vals = ldap_get_values(lak->ld, entry, attr);
+            if (vals == NULL)
+                continue;
+
+            for (i = 0; vals[i] != NULL; i++) {
+                rc = lak_result_add(attr, vals[i], ret);
+                if (rc != LAK_OK) {
+                    lak_result_free(*ret);
+                    *ret = NULL;
+                    goto done;
+                }
+            }
+
+            ldap_value_free(vals);
+            vals = NULL;
+            ldap_memfree(attr);
+            attr = NULL;
+        }
+    }
+
+done:;
+       if (res)
+               ldap_msgfree(res);
+       if (dn)
+               ldap_memfree(dn);
+       if (vals)
+               ldap_value_free(vals);
+       if (attr)
+               ldap_memfree(attr);
+       if (ber != NULL)
+               ber_free(ber, 0);
+       if (filter)
+               free(filter);
+       if (search_base)
+               free(search_base);
+       if (lu)
+               lak_user_free(lu);
+
+       return rc;
+}
+
+static int lak_group_member(
+       LAK *lak, 
+       const char *user, 
+       const char *service, 
+       const char *realm, 
+       const char *dn)
+{
+       char *group_dn = NULL, *user_dn = NULL;
+    char *group_filter = NULL;
+    char *group_search_base = NULL;
+       struct berval *dn_bv = NULL;
+       int rc;
+    LAK_RESULT *lres = NULL;
+    const char *attrs[] = { dn_attr, NULL };
+    const char *group_attrs[] = {"1.1", NULL};
+
+       LDAPMessage *res = NULL;
+
+    user_dn = (char *)dn;
+
+    if (EMPTY(user_dn)) {
+        if (lak->conf->use_sasl) {
+
+#if LDAP_VENDOR_VERSION >= 20122
+            if (ldap_whoami_s(lak->ld, &dn_bv, NULL, NULL) != LDAP_SUCCESS || !dn_bv) {
+                syslog(LOG_ERR|LOG_AUTH, "ldap_whoami_s() failed.");
+                rc =  LAK_NOT_GROUP_MEMBER;
+                goto done;
+            }
+
+            user_dn = dn_bv->bv_val;
+#else
+            syslog(LOG_ERR|LOG_AUTH, "Your OpenLDAP API does not supported ldap_whoami().");
+            rc =  LAK_NOT_GROUP_MEMBER;
+            goto done;
+#endif
+
+        } else {
+            
+            rc = lak_retrieve(lak, user, service, realm, attrs, &lres);
+            if (rc != LAK_OK)
+                goto done;
+
+            user_dn = lres->value;
+        }
+    }
+
+    if (lak->conf->group_match_method == LAK_GROUP_MATCH_METHOD_ATTR) {
+
+            rc = lak_expand_tokens(lak->conf->group_dn, user, service, realm, NULL, &group_dn);
+            if (rc != LAK_OK)
+                goto done;
+
+            rc = ((ldap_compare_s(lak->ld, group_dn, lak->conf->group_attr, user_dn)) == LDAP_COMPARE_TRUE ? 
+                     LAK_OK : LAK_NOT_GROUP_MEMBER);
+
+    } else if (lak->conf->group_match_method == LAK_GROUP_MATCH_METHOD_FILTER) {
+
+        rc = lak_expand_tokens(lak->conf->group_filter, user, service, realm, user_dn, &group_filter);
+        if (rc != LAK_OK)
+            goto done;
+
+        rc = lak_expand_tokens(lak->conf->group_search_base, user, service, realm, user_dn, &group_search_base);
+        if (rc != LAK_OK)
+            goto done;
+
+        rc = ldap_search_st(lak->ld, group_search_base, lak->conf->group_scope, group_filter, (char **) group_attrs, 0, &(lak->conf->timeout), &res);
+        switch (rc) {
+            case LDAP_SUCCESS:
+            case LDAP_NO_SUCH_OBJECT:
+                break;
+            case LDAP_TIMELIMIT_EXCEEDED:
+            case LDAP_BUSY:
+            case LDAP_UNAVAILABLE:
+            case LDAP_INSUFFICIENT_ACCESS:
+                syslog(LOG_ERR|LOG_AUTH, "group ldap_search_st() failed: %s", ldap_err2string(rc));
+                rc = LAK_NOT_GROUP_MEMBER;
+                goto done;
+            case LDAP_TIMEOUT:
+            case LDAP_SERVER_DOWN:
+            default:
+                syslog(LOG_ERR|LOG_AUTH, "group ldap_search_st() failed: %s", ldap_err2string(rc));
+                rc = LAK_RETRY;
+                lak->status = LAK_NOT_BOUND;
+                goto done;
+        }
+
+        rc = ( (ldap_count_entries(lak->ld, res) >= 1) ? LAK_OK : LAK_NOT_GROUP_MEMBER );
+
+    } else {
+
+            syslog(LOG_WARNING|LOG_AUTH, "Unknown ldap_group_match_method value.");
+            rc = LAK_FAIL;
+
+    }
+
+done:;
+       if (res)
+               ldap_msgfree(res);
+    if (group_dn)
+        free(group_dn);
+    if (group_filter)
+        free(group_filter);
+    if (group_search_base)
+        free(group_search_base);
+    if (lres)
+        lak_result_free(lres);
+    if (dn_bv)
+        ber_bvfree(dn_bv);
+
+       return rc;
+}
+
+static int lak_auth_custom(
+       LAK *lak,
+       const char *user,
+       const char *service,
+       const char *realm,
+       const char *password) 
+{
+       LAK_RESULT *lres;
+       int rc;
+       const char *attrs[] = { lak->conf->password_attr, NULL};
+
+       rc = lak_retrieve(lak, user, service, realm, attrs, &lres);
+       if (rc != LAK_OK)
+               return rc;
+
+    rc = lak_check_password(lres->value, password, NULL);
+
+       if ( rc == LAK_OK &&
+           (ISSET(lak->conf->group_dn) ||
+         ISSET(lak->conf->group_filter)) )
+        rc = lak_group_member(lak, user, service, realm, NULL);
+       
+       lak_result_free(lres);
+
+       return(rc);
+}
+
+static int lak_auth_bind(
+       LAK *lak,
+       const char *user,
+       const char *service,
+       const char *realm,
+       const char *password) 
+{
+    LAK_USER *lu = NULL;
+       LAK_RESULT *dn = NULL;
+       int rc;
+       const char *attrs[] = {dn_attr, NULL};
+
+       rc = lak_retrieve(lak, user, service, realm, attrs, &dn);
+       if (rc != LAK_OK)
+               goto done;
+
+       rc = lak_user(  
+               dn->value,
+               NULL,
+               NULL,
+               NULL,
+               NULL,
+               password,
+               &lu);
+       if (rc != LAK_OK)
+               goto done;
+
+       rc = lak_bind(lak, lu);
+
+       if ( rc == LAK_OK &&
+           (ISSET(lak->conf->group_dn) ||
+         ISSET(lak->conf->group_filter)) )
+               rc = lak_group_member(lak, user, service, realm, dn->value);
+
+done:;
+       if (lu)
+               lak_user_free(lu);
+       if (dn)
+               lak_result_free(dn);
+
+       return rc;
+}
+
+static int lak_auth_fastbind(
+       LAK *lak,
+       const char *user,
+       const char *service,
+       const char *realm,
+       const char *password) 
+{
+       int rc;
+       LAK_USER *lu = NULL;
+       char *dn = NULL;
+       char id[LAK_BUF_LEN];
+
+       *id = '\0';
+
+       if (lak->conf->use_sasl) {
+               strlcpy(id, user, LAK_BUF_LEN);
+               if (!strchr(id, '@') &&
+                   (ISSET(realm))) {
+                       strlcat(id, "@", LAK_BUF_LEN);
+                       strlcat(id, realm, LAK_BUF_LEN);
+               }
+       } else {
+               rc = lak_expand_tokens(lak->conf->filter, user, service, realm, NULL, &dn);
+               if (rc != LAK_OK || 
+            EMPTY(dn))
+                       goto done;
+       }
+                       
+       rc = lak_user(  
+               dn,
+               id,
+               NULL,
+               lak->conf->mech,
+               lak->conf->realm,
+               password,
+               &lu);
+       if (rc != LAK_OK)
+               goto done;
+
+       rc = lak_bind(lak, lu);
+
+       if ( rc == LAK_OK &&
+           (ISSET(lak->conf->group_dn) ||
+         ISSET(lak->conf->group_filter)) )
+            rc = lak_group_member(lak, user, service, realm, dn);
+
+done:;
+       if (lu)
+               lak_user_free(lu);
+       if (dn != NULL)
+               free(dn);
+
+       return rc;
+}
+
+int lak_authenticate(
+       LAK *lak,
+       const char *user,
+       const char *service,
+       const char *realm,
+       const char *password) 
+{
+       int i;
+       int rc;
+    int retry = 2;
+
+       if (lak == NULL) {
+               syslog(LOG_ERR|LOG_AUTH, "lak_init did not run.");
+               return LAK_FAIL;
+       }
+
+       if (EMPTY(user))
+               return LAK_FAIL;
+
+       if (EMPTY(realm))
+               realm = lak->conf->default_realm;
+
+       for (i = 0; authenticator[i].method != -1; i++) {
+               if (authenticator[i].method == lak->conf->auth_method) {
+                       if (authenticator[i].check) {
+                for (;retry > 0; retry--) {
+                    rc = (authenticator[i].check)(lak, user, service, realm, password);
+                    switch(rc) {
+                        case LAK_OK:
+                            return LAK_OK;
+                        case LAK_RETRY:
+                            if (retry > 1) {
+                                syslog(LOG_INFO|LOG_AUTH, "Retrying authentication");
+                                break;
+                            }
+                        default:
+                            syslog(
+                                LOG_DEBUG|LOG_AUTH, 
+                                "Authentication failed for %s%s%s: %s (%d)", 
+                                user, 
+                                (ISSET(realm) ? "/" : ""), 
+                                (ISSET(realm) ? realm : ""), 
+                                lak_error(rc), 
+                                rc);
+                            return LAK_FAIL;
+                    }
+                }
+            }
+                       break;
+               }
+       }
+
+    /* Should not get here */
+    syslog(LOG_DEBUG|LOG_AUTH, "Authentication method not setup properly (%d)", lak->conf->auth_method);
+
+       return LAK_FAIL;
+}
+
+char *lak_error(
+    const int errno)
+{
+
+    switch (errno) {
+        case LAK_OK:
+            return "Success";
+        case LAK_FAIL:
+            return "Generic error";
+        case LAK_NOMEM:
+            return "Out of memory";
+        case LAK_RETRY:
+            return "Retry condition (ldap server connection reset or broken)";
+        case LAK_NOT_GROUP_MEMBER:
+            return "Group member check failed";
+        case LAK_INVALID_PASSWORD:
+            return "Invalid password";
+        case LAK_USER_NOT_FOUND:
+            return "User not found";
+        case LAK_BIND_FAIL:
+            return "Bind to ldap server failed (invalid user/password or insufficient access)";
+        case LAK_CONNECT_FAIL:
+            return "Cannot connect to ldap server (configuration error)";
+        default:
+            return "Unknow error";
+    }
+}
+
+static char *lak_result_get(
+    const LAK_RESULT *lres, 
+    const char *attr) 
+{
+    LAK_RESULT *ptr;
+
+
+    for (ptr = (LAK_RESULT *)lres; ptr != NULL; ptr = ptr->next)
+        if (!strcasecmp(ptr->attribute, attr))
+            return ptr->value;
+
+    return NULL;
+}
+
+static int lak_result_add(
+       const char *attr,
+       const char *val,
+       LAK_RESULT **ret)  
+{
+       LAK_RESULT *lres;
+       
+       lres = (LAK_RESULT *) malloc(sizeof(LAK_RESULT));
+       if (lres == NULL) {
+               return LAK_NOMEM;
+       }
+
+       lres->next = NULL;
+
+       lres->attribute = strdup(attr);
+       if (lres->attribute == NULL) {
+               lak_result_free(lres);
+               return LAK_NOMEM;
+       }
+
+       lres->value = strdup(val);
+       if (lres->value == NULL) {
+               lak_result_free(lres);
+               return LAK_NOMEM;
+       }
+       lres->len = strlen(lres->value);
+
+       lres->next = *ret;
+
+       *ret = lres;
+       return LAK_OK;
+}
+
+void lak_result_free(
+       LAK_RESULT *res) 
+{
+       LAK_RESULT *lres, *ptr = res;
+
+       if (ptr == NULL)
+               return;
+
+       for (lres = ptr; lres != NULL; lres = ptr) {
+
+               ptr = lres->next;
+
+               if (lres->attribute != NULL) {
+                       memset(lres->attribute, 0, strlen(lres->attribute));
+                       free(lres->attribute);  
+               }
+
+               if (lres->value != NULL) {
+                       memset(lres->value, 0, strlen(lres->value));
+                       free(lres->value);      
+               }
+
+               lres->next = NULL;
+
+               free(lres);
+       }
+
+       return;
+}
+
+static int lak_check_password(
+       const char *hash, 
+       const char *passwd,
+       void *rock __attribute__((unused))) 
+{
+       int i, hlen;
+
+       if (EMPTY(hash))
+               return LAK_INVALID_PASSWORD;
+
+       if (EMPTY(passwd))
+               return LAK_INVALID_PASSWORD;
+
+       for (i = 0; password_scheme[i].hash != NULL; i++) {
+
+               hlen = strlen(password_scheme[i].hash);
+               if (!strncasecmp(password_scheme[i].hash, hash, hlen)) {
+                       if (password_scheme[i].check) {
+                               return (password_scheme[i].check)(hash+hlen, passwd,
+                                                               password_scheme[i].rock);
+                       }
+                       return LAK_FAIL;
+               }
+       }
+
+       return strcmp(hash, passwd) ? LAK_INVALID_PASSWORD : LAK_OK;
+}
+
+#ifdef HAVE_OPENSSL
+
+static int lak_base64_decode(
+       const char *src,
+       char **ret,
+       int *rlen) 
+{
+
+       int rc, i, tlen = 0;
+       char *text;
+       EVP_ENCODE_CTX EVP_ctx;
+
+       text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1);
+       if (text == NULL)
+               return LAK_NOMEM;
+
+       EVP_DecodeInit(&EVP_ctx);
+       rc = EVP_DecodeUpdate(&EVP_ctx, text, &i, (char *)src, strlen(src));
+       if (rc < 0) {
+               free(text);
+               return LAK_FAIL;
+       }
+       tlen += i;
+       EVP_DecodeFinal(&EVP_ctx, text, &i); 
+
+       *ret = text;
+       if (rlen != NULL)
+               *rlen = tlen;
+
+       return LAK_OK;
+}
+
+static int lak_check_hashed(
+       const char *hash,
+       const char *passwd,
+       void *rock)
+{
+       int rc, clen;
+       LAK_HASH_ROCK *hrock = (LAK_HASH_ROCK *) rock;
+       EVP_MD_CTX mdctx;
+       const EVP_MD *md;
+       unsigned char digest[EVP_MAX_MD_SIZE];
+       char *cred;
+
+       md = EVP_get_digestbyname(hrock->mda);
+       if (!md)
+               return LAK_FAIL;
+
+       rc = lak_base64_decode(hash, &cred, &clen);
+       if (rc != LAK_OK)
+               return rc;
+
+       EVP_DigestInit(&mdctx, md);
+       EVP_DigestUpdate(&mdctx, passwd, strlen(passwd));
+       if (hrock->salted) {
+               EVP_DigestUpdate(&mdctx, &cred[EVP_MD_size(md)],
+                                clen - EVP_MD_size(md));
+       }
+       EVP_DigestFinal(&mdctx, digest, NULL);
+
+       rc = memcmp((char *)cred, (char *)digest, EVP_MD_size(md));
+       free(cred);
+       return rc ? LAK_INVALID_PASSWORD : LAK_OK;
+}
+
+#endif /* HAVE_OPENSSL */
+
+static int lak_check_crypt(
+       const char *hash,
+       const char *passwd,
+       void *rock __attribute__((unused))) 
+{
+       char *cred;
+
+       if (strlen(hash) < 2 )
+               return LAK_INVALID_PASSWORD;
+
+       cred = crypt(passwd, hash);
+       if (EMPTY(cred))
+               return LAK_INVALID_PASSWORD;
+
+       return strcmp(hash, cred) ? LAK_INVALID_PASSWORD : LAK_OK;
+}
+
+#endif /* AUTH_LDAP */
diff --git a/saslauthd/lak.h b/saslauthd/lak.h
new file mode 100644 (file)
index 0000000..a16d898
--- /dev/null
@@ -0,0 +1,141 @@
+/* COPYRIGHT
+ * Copyright (c) 2002-2003 Igor Brezac
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IGOR BREZAC OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifndef _LAK_H
+#define _LAK_H
+
+#include <ldap.h>
+#include <lber.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
+
+#define LAK_OK 0
+#define LAK_FAIL -1
+#define LAK_NOMEM -2
+#define LAK_RETRY -3
+#define LAK_NOT_GROUP_MEMBER -4
+#define LAK_INVALID_PASSWORD -5
+#define LAK_USER_NOT_FOUND -6
+#define LAK_BIND_FAIL -7
+#define LAK_CONNECT_FAIL -8
+
+#define LAK_NOT_BOUND 1
+#define LAK_BOUND 2
+
+#define LAK_AUTH_METHOD_BIND 0
+#define LAK_AUTH_METHOD_CUSTOM 1
+#define LAK_AUTH_METHOD_FASTBIND 2
+
+#define LAK_GROUP_MATCH_METHOD_ATTR 0
+#define LAK_GROUP_MATCH_METHOD_FILTER 1
+
+#define LAK_BUF_LEN 128
+#define LAK_DN_LEN 512
+#define LAK_PATH_LEN 1024
+#define LAK_URL_LEN LAK_PATH_LEN
+
+typedef struct lak_conf {
+    char   path[LAK_PATH_LEN];
+    char   servers[LAK_URL_LEN];
+    char   bind_dn[LAK_DN_LEN];
+    char   password[LAK_BUF_LEN];
+    int    version;
+    struct timeval timeout;
+    int    size_limit;
+    int    time_limit;
+    int    deref;
+    int    referrals;
+    int    restart;
+    int    scope;
+    char   default_realm[LAK_BUF_LEN];
+    char   search_base[LAK_DN_LEN];
+    char   filter[LAK_DN_LEN];
+    char   password_attr[LAK_BUF_LEN];
+    char   group_dn[LAK_DN_LEN];
+    char   group_attr[LAK_BUF_LEN];
+    char   group_filter[LAK_DN_LEN];
+    char   group_search_base[LAK_DN_LEN];
+    int    group_scope;
+    int    group_match_method;
+    char   auth_method;
+    int    use_sasl;
+    char   id[LAK_BUF_LEN];
+    char   authz_id[LAK_BUF_LEN];
+    char   mech[LAK_BUF_LEN];
+    char   realm[LAK_BUF_LEN];
+    char   sasl_secprops[LAK_BUF_LEN];
+    int    start_tls;
+    int    tls_check_peer;
+    char   tls_cacert_file[LAK_PATH_LEN];
+    char   tls_cacert_dir[LAK_PATH_LEN];
+    char   tls_ciphers[LAK_BUF_LEN];
+    char   tls_cert[LAK_PATH_LEN];
+    char   tls_key[LAK_PATH_LEN];
+    int    debug;
+} LAK_CONF;
+
+typedef struct lak_user {
+    char bind_dn[LAK_DN_LEN];
+    char id[LAK_BUF_LEN];
+    char authz_id[LAK_BUF_LEN];
+    char mech[LAK_BUF_LEN];
+    char realm[LAK_BUF_LEN];
+    char password[LAK_BUF_LEN];
+} LAK_USER;
+
+
+typedef struct lak {
+    LDAP     *ld;
+    char      status;
+    LAK_USER *user;
+    LAK_CONF *conf;
+} LAK;
+
+typedef struct lak_result {
+    char              *attribute;
+    char              *value;
+    size_t             len;
+    struct lak_result *next;
+} LAK_RESULT;
+
+int lak_init(const char *, LAK **);
+void lak_close(LAK *);
+int lak_authenticate(LAK *, const char *, const char *, const char *, const char *);
+int lak_retrieve(LAK *, const char *, const char *, const char *, const char **, LAK_RESULT **);
+void lak_result_free(LAK_RESULT *);
+char *lak_error(const int errno);
+
+#endif  /* _LAK_H */
diff --git a/saslauthd/md5.c b/saslauthd/md5.c
new file mode 100644 (file)
index 0000000..d38425d
--- /dev/null
@@ -0,0 +1,526 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Function names changed to avoid namespace collisions: Rob Siemborski */
+
+/* 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.
+*/
+
+#include <config.h>
+#include "md5global.h"
+#include "md5.h"
+#include "hmac-md5.h"
+
+#ifndef WIN32
+# include <arpa/inet.h>
+#endif
+
+/* Constants for MD5Transform routine.
+*/
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+       ((unsigned char *, UINT4 *, unsigned int)); 
+static void Decode PROTO_LIST
+       ((UINT4 *, unsigned char *, unsigned int)); 
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+       0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
+};
+
+/* F, G, H and I are basic MD5 functions.
+
+        */
+#ifdef I
+/* This might be defined via NANA */
+#undef I
+#endif
+
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+
+        */
+
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+*/
+
+#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+#define GG(a, b, c, d, x, s, ac) {        (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);         } 
+#define HH(a, b, c, d, x, s, ac) {        (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+#define II(a, b, c, d, x, s, ac) {        (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac);        (a) = ROTATE_LEFT ((a), (s));        (a) += (b);        } 
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+*/
+
+void _saslauthd_MD5Init (context)
+MD5_CTX *context; /* context */
+{
+       context->count[0] = context->count[1] = 0; 
+
+       /* Load magic initialization constants. */
+       context->state[0] = 0x67452301; 
+       context->state[1] = 0xefcdab89; 
+       context->state[2] = 0x98badcfe; 
+       context->state[3] = 0x10325476; 
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+       operation, processing another message block, and updating the context. 
+*/
+
+void _saslauthd_MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+       unsigned int i, index, partLen; 
+
+         /* Compute number of bytes mod 64 */
+         index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+         /* Update number of bits */
+         if ((context->count[0] += ((UINT4)inputLen << 3))
+          < ((UINT4)inputLen << 3))
+        context->count[1]++;
+         context->count[1] += ((UINT4)inputLen >> 29);
+
+       partLen = 64 - index; 
+
+         /* Transform as many times as possible.
+
+*/
+       if (inputLen >= partLen) { 
+       MD5_memcpy 
+       ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform
+       (context->state, context->buffer); 
+
+       for (i = partLen; i + 63 < inputLen; i += 64) 
+       MD5Transform (context->state, &input[i]); 
+
+       index = 0; 
+       } 
+       else 
+       i = 0; 
+
+         /* Buffer remaining input */
+         MD5_memcpy
+        ((POINTER)&context->buffer[index], (POINTER)&input[i],
+         inputLen-i);
+
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+       the message digest and zeroizing the context. 
+*/
+
+void _saslauthd_MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+       unsigned char bits[8]; 
+       unsigned int index, padLen; 
+
+         /* Save number of bits */
+         Encode (bits, context->count, 8);
+
+         /* Pad out to 56 mod 64. */
+        index = (unsigned int)((context->count[0] >> 3) & 0x3f); 
+        padLen = (index < 56) ? (56 - index) : (120 - index); 
+        _saslauthd_MD5Update (context, PADDING, padLen); 
+
+         /* Append length (before padding) */
+         _saslauthd_MD5Update (context, bits, 8);
+
+         /* Store state in digest */
+         Encode (digest, context->state, 16);
+
+         /* Zeroize sensitive information. */
+       MD5_memset ((POINTER)context, 0, sizeof (*context)); 
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+       UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; 
+
+       Decode (x, block, 64); 
+
+         /* Round 1 */
+         FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+         FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+         FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+         FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+         FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+         FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+         FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+         FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+         FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+         FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+         FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+         FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+         FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+         FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+         FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+         FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+        /* Round 2 */
+         GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+         GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+         GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+         GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+         GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+         GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
+         GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+         GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+         GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+         GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+         GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+        GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ 
+        GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ 
+        GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ 
+        GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ 
+        GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ 
+
+         /* Round 3 */
+         HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+         HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+         HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+         HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+         HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+         HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+         HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+         HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+         HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+         HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+         HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+         HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
+         HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+         HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+         HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+         HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+         /* Round 4 */
+         II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+         II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+         II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+         II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+         II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+         II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+         II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+         II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+         II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+         II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+         II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+         II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+         II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+         II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+         II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+         II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+       state[0] += a; 
+       state[1] += b; 
+       state[2] += c; 
+       state[3] += d; 
+
+         /* Zeroize sensitive information.
+        */
+       MD5_memset ((POINTER)x, 0, sizeof (x)); 
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+       a multiple of 4. 
+
+        */
+
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+       unsigned int i, j; 
+
+       for (i = 0, j = 0; j < len; i++, j += 4) { 
+       output[j] = (unsigned char)(input[i] & 0xff); 
+       output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); 
+       output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); 
+       output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); 
+       } 
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+       a multiple of 4. 
+
+        */
+
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+       unsigned int i, j; 
+
+       for (i = 0, j = 0; j < len; i++, j += 4) 
+       output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16)
+       | (((UINT4)input[j+3]) << 24); 
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+
+        */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+       unsigned int i; 
+
+       for (i = 0; i < len; i++) 
+             output[i] = input[i]; 
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+*/
+
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+       unsigned int i; 
+
+       for (i = 0; i < len; i++) 
+       ((char *)output)[i] = (char)value; 
+}
+
+void _saslauthd_hmac_md5_init(HMAC_MD5_CTX *hmac,
+                        const unsigned char *key,
+                        int key_len)
+{
+  unsigned char k_ipad[65];    /* inner padding -
+                               * key XORd with ipad
+                               */
+  unsigned char k_opad[65];    /* outer padding -
+                               * key XORd with opad
+                               */
+  unsigned char tk[16];
+  int i;
+  /* if key is longer than 64 bytes reset it to key=MD5(key) */
+  if (key_len > 64) {
+    
+    MD5_CTX      tctx;
+
+    _saslauthd_MD5Init(&tctx); 
+    _saslauthd_MD5Update(&tctx, key, key_len); 
+    _saslauthd_MD5Final(tk, &tctx); 
+
+    key = tk; 
+    key_len = 16; 
+  } 
+
+  /*
+   * the HMAC_MD5 transform looks like:
+   *
+   * MD5(K XOR opad, MD5(K XOR ipad, text))
+   *
+   * where K is an n byte key
+   * ipad is the byte 0x36 repeated 64 times
+   * opad is the byte 0x5c repeated 64 times
+   * and text is the data being protected
+   */
+
+  /* start out by storing key in pads */
+  MD5_memset(k_ipad, '\0', sizeof k_ipad);
+  MD5_memset(k_opad, '\0', sizeof k_opad);
+  MD5_memcpy( k_ipad, key, key_len);
+  MD5_memcpy( k_opad, key, key_len);
+
+  /* XOR key with ipad and opad values */
+  for (i=0; i<64; i++) {
+    k_ipad[i] ^= 0x36;
+    k_opad[i] ^= 0x5c;
+  }
+
+  _saslauthd_MD5Init(&hmac->ictx);                   /* init inner context */
+  _saslauthd_MD5Update(&hmac->ictx, k_ipad, 64);     /* apply inner pad */
+
+  _saslauthd_MD5Init(&hmac->octx);                   /* init outer context */
+  _saslauthd_MD5Update(&hmac->octx, k_opad, 64);     /* apply outer pad */
+
+  /* scrub the pads and key context (if used) */
+  MD5_memset(&k_ipad, 0, sizeof(k_ipad));
+  MD5_memset(&k_opad, 0, sizeof(k_opad));
+  MD5_memset(&tk, 0, sizeof(tk));
+
+  /* and we're done. */
+}
+
+/* The precalc and import routines here rely on the fact that we pad
+ * the key out to 64 bytes and use that to initialize the md5
+ * contexts, and that updating an md5 context with 64 bytes of data
+ * leaves nothing left over; all of the interesting state is contained
+ * in the state field, and none of it is left over in the count and
+ * buffer fields.  So all we have to do is save the state field; we
+ * can zero the others when we reload it.  Which is why the decision
+ * was made to pad the key out to 64 bytes in the first place. */
+void _saslauthd_hmac_md5_precalc(HMAC_MD5_STATE *state,
+                                const unsigned char *key,
+                                int key_len)
+{
+  HMAC_MD5_CTX hmac;
+  unsigned lupe;
+
+  _saslauthd_hmac_md5_init(&hmac, key, key_len);
+  for (lupe = 0; lupe < 4; lupe++) {
+    state->istate[lupe] = htonl(hmac.ictx.state[lupe]);
+    state->ostate[lupe] = htonl(hmac.octx.state[lupe]);
+  }
+  MD5_memset(&hmac, 0, sizeof(hmac));
+}
+
+
+void _saslauthd_hmac_md5_import(HMAC_MD5_CTX *hmac,
+                               HMAC_MD5_STATE *state)
+{
+  unsigned lupe;
+  MD5_memset(hmac, 0, sizeof(HMAC_MD5_CTX));
+  for (lupe = 0; lupe < 4; lupe++) {
+    hmac->ictx.state[lupe] = ntohl(state->istate[lupe]);
+    hmac->octx.state[lupe] = ntohl(state->ostate[lupe]);
+  }
+  /* Init the counts to account for our having applied
+   * 64 bytes of key; this works out to 0x200 (64 << 3; see
+   * MD5Update above...) */
+  hmac->ictx.count[0] = hmac->octx.count[0] = 0x200;
+}
+
+void _saslauthd_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE],
+                              HMAC_MD5_CTX *hmac)
+{
+  _saslauthd_MD5Final(digest, &hmac->ictx);  /* Finalize inner md5 */
+  _saslauthd_MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */
+  _saslauthd_MD5Final(digest, &hmac->octx); /* Finalize outer md5 */
+}
+
+
+void _saslauthd_hmac_md5(text, text_len, key, key_len, digest)
+const unsigned char* text; /* pointer to data stream */
+int text_len; /* length of data stream */
+const unsigned char* key; /* pointer to authentication key */
+int key_len; /* length of authentication key */
+unsigned char *digest; /* caller digest to be filled in */
+{
+  MD5_CTX context; 
+
+  unsigned char k_ipad[65];    /* inner padding -
+                               * key XORd with ipad
+                               */
+  unsigned char k_opad[65];    /* outer padding -
+                               * key XORd with opad
+                               */
+  unsigned char tk[16];
+  int i;
+  /* if key is longer than 64 bytes reset it to key=MD5(key) */
+  if (key_len > 64) {
+    
+    MD5_CTX      tctx;
+
+    _saslauthd_MD5Init(&tctx); 
+    _saslauthd_MD5Update(&tctx, key, key_len); 
+    _saslauthd_MD5Final(tk, &tctx); 
+
+    key = tk; 
+    key_len = 16; 
+  } 
+
+  /*
+   * the HMAC_MD5 transform looks like:
+   *
+   * MD5(K XOR opad, MD5(K XOR ipad, text))
+   *
+   * where K is an n byte key
+   * ipad is the byte 0x36 repeated 64 times
+   * opad is the byte 0x5c repeated 64 times
+   * and text is the data being protected
+   */
+
+  /* start out by storing key in pads */
+  MD5_memset(k_ipad, '\0', sizeof k_ipad);
+  MD5_memset(k_opad, '\0', sizeof k_opad);
+  MD5_memcpy( k_ipad, key, key_len);
+  MD5_memcpy( k_opad, key, key_len);
+
+  /* XOR key with ipad and opad values */
+  for (i=0; i<64; i++) {
+    k_ipad[i] ^= 0x36;
+    k_opad[i] ^= 0x5c;
+  }
+  /*
+   * perform inner MD5
+   */
+
+  _saslauthd_MD5Init(&context);                   /* init context for 1st
+                                              * pass */
+  _saslauthd_MD5Update(&context, k_ipad, 64);      /* start with inner pad */
+  _saslauthd_MD5Update(&context, text, text_len); /* then text of datagram */
+  _saslauthd_MD5Final(digest, &context);          /* finish up 1st pass */
+
+  /*
+   * perform outer MD5
+   */
+  _saslauthd_MD5Init(&context);                   /* init context for 2nd
+                                       * pass */
+  _saslauthd_MD5Update(&context, k_opad, 64);     /* start with outer pad */
+  _saslauthd_MD5Update(&context, digest, 16);     /* then results of 1st
+                                       * hash */
+  _saslauthd_MD5Final(digest, &context);          /* finish up 2nd pass */
+}
diff --git a/saslauthd/md5global.h b/saslauthd/md5global.h
new file mode 100644 (file)
index 0000000..fbd7455
--- /dev/null
@@ -0,0 +1,38 @@
+/* GLOBAL.H - RSAREF types and constants
+ */
+#ifndef MD5GLOBAL_H
+#define MD5GLOBAL_H
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+  function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+  been defined with C compiler flags.
+ */
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+typedef signed char 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/saslauthd/mechanisms.c b/saslauthd/mechanisms.c
new file mode 100644 (file)
index 0000000..ab977cf
--- /dev/null
@@ -0,0 +1,98 @@
+/* COPYRIGHT
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+/* SYNOPSIS
+ * mechanisms[] contains the NULL terminated list of supported
+ * authentication drivers.
+ * END SYNOPSIS */
+
+#ifdef __GNUC__
+#ident "$Id: mechanisms.c,v 1.8 2006/03/13 20:17:09 mel Exp $"
+#endif
+
+/* PUBLIC DEPENDENCIES */
+#include "mechanisms.h"
+
+#ifdef AUTH_DCE
+# include "auth_dce.h"
+#endif /* AUTH_DCE */
+#ifdef AUTH_SHADOW
+# include "auth_shadow.h"
+#endif /* AUTH_SHADOW */
+#ifdef AUTH_SIA
+# include "auth_sia.h"
+#endif /* AUTH_SIA */
+#include "auth_krb4.h"
+#include "auth_krb5.h"
+#include "auth_getpwent.h"
+#include "auth_sasldb.h"
+#include "auth_rimap.h"
+#ifdef AUTH_PAM
+# include "auth_pam.h"
+#endif
+#ifdef AUTH_LDAP
+#include "auth_ldap.h"
+#endif
+#ifdef AUTH_HTTPFORM
+#include "auth_httpform.h"
+#endif
+/* END PUBLIC DEPENDENCIES */
+
+authmech_t mechanisms[] =
+{
+#ifdef AUTH_SASLDB
+    {  "sasldb",       0,                      auth_sasldb },
+#endif /* AUTH_SASLDB */
+#ifdef AUTH_DCE
+    {  "dce",          0,                      auth_dce },
+#endif /* AUTH_DCE */
+    {  "getpwent",     0,                      auth_getpwent },
+#ifdef AUTH_KRB4
+    {  "kerberos4",    auth_krb4_init,         auth_krb4 },
+#endif /* AUTH_KRB4 */
+#ifdef AUTH_KRB5
+    {  "kerberos5",    auth_krb5_init,         auth_krb5 },
+#endif /* AUTH_KRB5 */
+#ifdef AUTH_PAM
+    {  "pam",          0,                      auth_pam },
+#endif /* AUTH_PAM */
+    {  "rimap",        auth_rimap_init,        auth_rimap },
+#ifdef AUTH_SHADOW
+    {  "shadow",       0,                      auth_shadow },
+#endif /* AUTH_SHADOW */
+#ifdef AUTH_SIA
+    {   "sia",         0,                      auth_sia },
+#endif /* AUTH_SIA */
+#ifdef AUTH_LDAP
+    {   "ldap",                auth_ldap_init,         auth_ldap },
+#endif /* AUTH_LDAP */
+#ifdef AUTH_HTTPFORM
+    {   "httpform",     auth_httpform_init,     auth_httpform },
+#endif /* AUTH_LDAP */
+    {  0,              0,                      0 }
+};
+
diff --git a/saslauthd/mechanisms.h b/saslauthd/mechanisms.h
new file mode 100644 (file)
index 0000000..e2323bf
--- /dev/null
@@ -0,0 +1,102 @@
+/* COPYRIGHT
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * END COPYRIGHT */
+
+#ifdef __GNUC__
+#ident "$Id: mechanisms.h,v 1.10 2006/03/13 20:17:09 mel Exp $"
+#endif
+
+#ifndef _MECHANISMS_H
+#define _MECHANISMS_H
+
+#include "saslauthd.h"
+
+/* PUBLIC DEPENDENCIES */
+/* Authentication mechanism dispatch table definition */
+typedef struct {
+    char *name;                                /* name of the mechanism */
+    int (*initialize)(void);           /* initialization function */
+    char *(*authenticate)(const char *, const char *,
+                         const char *, const char *); /* authentication
+                                                         function */
+} authmech_t;
+
+extern authmech_t mechanisms[];                /* array of supported auth mechs */
+extern authmech_t *authmech;           /* auth mech daemon is using */
+/* END PUBLIC DEPENDENCIES */
+
+/*
+ * Figure out which optional drivers we support.
+ */
+#ifndef AUTH_KRB5
+# if defined(HAVE_KRB5_H) && defined(HAVE_GSSAPI)
+#  define AUTH_KRB5
+# endif
+#endif
+
+#ifndef AUTH_KRB4
+# if defined(HAVE_KRB)
+#  define AUTH_KRB4
+# endif
+#endif
+
+#ifndef AUTH_DCE
+# if defined(HAVE_USERSEC_H) && defined(HAVE_AUTHENTICATE)
+#  define AUTH_DCE
+# endif
+#endif
+
+#ifndef AUTH_SHADOW
+# if defined(HAVE_GETSPNAM) || defined(HAVE_GETUSERPW)
+#  define AUTH_SHADOW
+# endif
+#endif
+
+#ifndef AUTH_SIA
+# if defined(HAVE_SIA_VALIDATE_USER)
+#  define AUTH_SIA
+# endif
+#endif
+
+#ifndef AUTH_PAM
+# ifdef HAVE_PAM
+#  define AUTH_PAM
+# endif
+#endif
+
+#ifndef AUTH_LDAP
+# ifdef HAVE_LDAP
+#  define AUTH_LDAP
+# endif
+#endif
+
+#ifndef AUTH_HTTPFORM
+# ifdef HAVE_HTTPFORM
+#  define AUTH_HTTPFORM
+# endif
+#endif
+
+#endif  /* _MECHANISMS_H */
diff --git a/saslauthd/saslauthd-main.c b/saslauthd/saslauthd-main.c
new file mode 100644 (file)
index 0000000..2c7b58e
--- /dev/null
@@ -0,0 +1,996 @@
+/*****************************************************************************
+ *
+ * saslauthd-main.c
+ *
+ * Description:  Main program source.
+ *
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2003 Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * HISTORY
+ *
+ * saslauthd is a re-implementation of the pwcheck utility included
+ * with the CMU Cyrus IMAP server circa 1997. This implementation
+ * was written by Lyndon Nerenberg of Messaging Direct Inc. (which
+ * at that time was the Esys Corporation) and was included in the
+ * company's IMAP message store product (Simeon Message Service) as
+ * the smsauthd utility.
+ *
+ * This implementation was contributed to CMU by Messaging Direct Ltd.
+ * in September 2000.
+ *
+ * September 2001 (Ken Murchison of Oceana Matrix Ltd.):
+ * - Modified the protocol to use counted length strings instead of
+ *   nul delimited strings.
+ * - Augmented the protocol to accept the service name and user realm.
+ * 
+ * Feb 2003: Partial rewrite and cleanup  by Jeremy Rumpf jrumpf@heavyload.net
+ * - Merge the doors and unix IPC methods under a common framework.
+ *
+ *   OVERVIEW
+ *
+ * saslauthd provides an interface between the SASL library and various
+ * external authentication mechanisms. The primary goal is to isolate
+ * code that requires superuser privileges (for example, access to
+ * the shadow password file) into a single easily audited module. It
+ * can also act as an authentication proxy between plaintext-equivelent
+ * authentication schemes (i.e. CRAM-MD5) and more secure authentication
+ * services such as Kerberos, although such usage is STRONGLY discouraged
+ * because it exposes the strong credentials via the insecure plaintext
+ * mechanisms.
+ *
+ * The program listens for connections on a UNIX domain socket. Access to
+ * the service is controlled by the UNIX filesystem permissions on the
+ * socket.
+ *
+ * The service speaks a very simple protocol. The client connects and
+ * sends the authentication identifier, the plaintext password, the
+ * service name and user realm as counted length strings (a 16-bit
+ * unsigned integer in network byte order followed by the string
+ * itself). The server returns a single response as a counted length
+ * string. The response begins with "OK" or "NO", and is followed by
+ * an optional text string (separated from the OK/NO by a single space
+ * character), and a NUL. The server then closes the connection.
+ *
+ * An "OK" response indicates the authentication credentials are valid.
+ * A "NO" response indicates the authentication failed.
+ *
+ * The optional text string may be used to indicate an exceptional
+ * condition in the authentication environment that should be communicated
+ * to the client.
+ *
+ *****************************************************************************/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef _AIX
+# include <strings.h>
+#endif /* _AIX */
+
+#include <syslog.h>
+#include <signal.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <sys/uio.h>
+
+#include "globals.h"
+#include "saslauthd-main.h"
+#include "cache.h"
+#include "utils.h"
+
+/* max login + max realm + '@' */
+#define MAX_LOGIN_REALM_LEN (MAX_REQ_LEN * 2) + 1
+
+/****************************************
+ * declarations/protos
+ *****************************************/
+static void    show_version();
+static void    show_usage();
+
+/****************************************
+ * application globals
+ *****************************************/
+int            flags = 0;              /* Runtime flags                     */
+int            g_argc;                 /* Copy of argc for those who need it*/
+char           **g_argv;               /* Copy of argv for those who need it*/
+char           *run_path = NULL;       /* path to our working directory     */
+authmech_t     *auth_mech = NULL;      /* Authentication mechanism to use   */
+char           *mech_option = NULL;    /* mechanism-specific option         */
+int            num_procs = 5;          /* The max number of worker processes*/
+
+
+/****************************************
+ * module globals
+*****************************************/
+extern char    *optarg;                /* For getopt()                          */
+static int             master_pid;             /* Pid of the master process             */
+static int     pid_fd;                 /* Descriptor to the open pid file       */
+static int     pid_file_lock_fd;               /* Descriptor to the open pid lock file  */
+static char    *pid_file;              /* Pid file name                         */
+static char    *pid_file_lock;         /* Pid lock file name                    */
+static int       startup_pipe[2] = { -1, -1 };
+
+int main(int argc, char **argv) {
+       int             option;
+       int             rc;
+       int             x;
+       struct flock    lockinfo;
+       char            *auth_mech_name = NULL;
+       size_t          pid_file_size;
+
+       SET_AUTH_PARAMETERS(argc, argv);
+
+       g_argc = argc;
+       g_argv = argv;
+
+       /* default flags */
+       flags |= USE_ACCEPT_LOCK;
+       flags |= DETACH_TTY;
+       flags |= LOG_USE_SYSLOG;
+       flags |= LOG_USE_STDERR;
+       flags |= AM_MASTER;
+
+       while ((option = getopt(argc, argv, "a:cdhO:lm:n:rs:t:vV")) != -1) {
+               switch(option) {
+                       case 'a':
+                               /* Only one at a time, please! */
+                               if(auth_mech_name) {
+                                   show_usage();
+                                   break;
+                               }
+
+                               auth_mech_name = strdup(optarg);
+                               if (!auth_mech_name) {
+                                   logger(L_ERR, L_FUNC,
+                                          "could not allocate memory");
+                                   exit(1);
+                               }
+                               break;
+
+                       case 'c':
+                               flags |= CACHE_ENABLED;
+                               break;
+
+                       case 'd':
+                               flags |= VERBOSE;
+                               flags &= ~DETACH_TTY;
+                               break;
+
+                       case 'h':
+                               show_usage();
+                               break;
+                               
+                       case 'O':
+                               set_mech_option(optarg);
+                               break;
+
+                       case 'l':
+                               flags &= ~USE_ACCEPT_LOCK;
+                               break;
+
+                       case 'm':
+                               set_run_path(optarg);
+                               break;
+
+                       case 'n':
+                               set_max_procs(optarg);
+                               break;
+
+                       case 'r':
+                               flags |= CONCAT_LOGIN_REALM;
+                               break;
+
+                       case 's':
+                               cache_set_table_size(optarg);
+                               break;
+
+                       case 't':
+                               cache_set_timeout(optarg);
+                               break;
+
+                       case 'V':
+                               flags |= VERBOSE;                   
+                               break;
+
+                       case 'v':
+                               show_version();
+                               break;
+                               
+                       default:
+                               show_usage();
+                               break;
+               }
+       }
+
+       if (run_path == NULL)
+               run_path = PATH_SASLAUTHD_RUNDIR;
+
+       if (auth_mech_name == NULL) {
+               logger(L_ERR, L_FUNC, "no authentication mechanism specified");
+               show_usage();
+               exit(1);
+       }
+
+       set_auth_mech(auth_mech_name);
+
+       if (flags & VERBOSE)  {
+               logger(L_DEBUG, L_FUNC, "num_procs  : %d", num_procs);
+
+               if (mech_option == NULL)
+                       logger(L_DEBUG, L_FUNC, "mech_option: NULL");
+               else
+                       logger(L_DEBUG, L_FUNC, "mech_option: %s", mech_option);
+
+               logger(L_DEBUG, L_FUNC, "run_path   : %s", run_path);
+               logger(L_DEBUG, L_FUNC, "auth_mech  : %s", auth_mech->name);
+       }
+
+       /*********************************************************
+        * Change our working directory to the dir where the
+        * run path is set to, core dumps will go there to keep
+        * them intact.
+        **********************************************************/
+       if (chdir(run_path) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not chdir to: %s", run_path);
+               logger(L_ERR, L_FUNC, "chdir: %s", strerror(rc));
+               logger(L_ERR, L_FUNC, "Check to make sure the directory exists and is");
+               logger(L_ERR, L_FUNC, "writeable by the user this process runs as.");
+               exit(1);
+       }
+
+       umask(077);
+
+       pid_file_size = strlen(run_path) + sizeof(PID_FILE_LOCK) + 1;
+       if ((pid_file_lock = malloc(pid_file_size)) == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+    
+       strlcpy(pid_file_lock, run_path, pid_file_size);
+       strlcat(pid_file_lock, PID_FILE_LOCK, pid_file_size);
+
+       if ((pid_file_lock_fd = open(pid_file_lock, O_CREAT|O_TRUNC|O_RDWR, 644)) < 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not open pid lock file: %s", pid_file_lock);
+               logger(L_ERR, L_FUNC, "open: %s", strerror(rc));
+               logger(L_ERR, L_FUNC,
+                      "Check to make sure the directory exists and is");
+               logger(L_ERR, L_FUNC, "writeable by the user this process runs as.");
+               exit(1);
+       }
+
+       lockinfo.l_type = F_WRLCK;
+       lockinfo.l_start = 0;
+       lockinfo.l_len = 0;
+       lockinfo.l_whence = SEEK_SET;
+
+       if (fcntl(pid_file_lock_fd, F_SETLK, &lockinfo) == -1) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "could not lock pid lock file: %s", pid_file_lock);
+               logger(L_ERR, L_FUNC, "fcntl: %s", strerror(rc));
+               exit(1);
+       }
+    
+       if(pipe(startup_pipe) == -1) {
+               logger(L_ERR, L_FUNC, "can't create startup pipe");
+               exit(1);
+       }
+
+       /*********************************************************
+        * Enable signal handlers.
+        **********************************************************/
+       signal_setup();
+
+       /*********************************************************
+        * Cache setup, exit if it doesn't succeed (optional would
+        * be to disable the cache and log a warning).
+        **********************************************************/
+       if (cache_init() != 0)
+               exit(1);
+
+       /*********************************************************
+        * Call the ipc specific initializer. This should also
+        * call detach_tty() at the appropriate point.
+        **********************************************************/
+       ipc_init();
+
+       /*********************************************************
+        * Enable general cleanup.
+        **********************************************************/
+       atexit(server_exit);
+
+       /*********************************************************
+        * If required, enable the process model.
+        **********************************************************/
+       if (flags & USE_PROCESS_MODEL) {
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "using process model");
+
+               for (x = 1; x < num_procs; x++) {
+                       if (have_baby() != 0)
+                               continue;               /* parent */
+
+                       break;                          /* child  */
+               }
+       }
+
+       /*********************************************************
+        * Enter the ipc loop, we should never return.
+        **********************************************************/
+       ipc_loop();
+
+       exit(0);
+}
+
+
+/*************************************************************
+ * Performs all authentication centric duties. We should be
+ * getting callbacks from the ipc method here. We'll simply 
+ * return a pointer to a string to send back to the client.
+ * The caller is responsible for freeing the pointer. 
+ **************************************************************/
+char *do_auth(const char *_login, const char *password, const char *service, const char *realm) {
+
+       struct cache_result     lkup_result;
+       char                    *response;
+       int                     cached = 0;
+       char                    login_buff[MAX_LOGIN_REALM_LEN];
+       char                    *login;
+
+
+       /***********************************************************
+        * Check to concat the login and realm into a single login.
+        * Aka, login: foo realm: bar becomes login: foo@bar.
+        * We do this because some mechs have no concept of a realm.
+        * Ie. auth_pam and friends.
+        ***********************************************************/
+       if ((flags & CONCAT_LOGIN_REALM) && realm && realm[0] != '\0') {
+           strlcpy(login_buff, _login, sizeof(login_buff));
+           strlcat(login_buff, "@", sizeof(login_buff));
+           strlcat(login_buff, realm, sizeof(login_buff));
+
+           login = login_buff;
+       } else {
+           login = (char *)_login;
+       }
+
+       if (cache_lookup(login, realm, service, password, &lkup_result) == CACHE_OK) {  
+               response = strdup("OK");
+               cached = 1;
+       } else {
+               response = auth_mech->authenticate(login, password, service, realm);
+
+               if (response == NULL) {
+                       logger(L_ERR, L_FUNC, "internal mechanism failure: %s", auth_mech->name);
+                       response = strdup("NO internal mechanism failure");
+               }
+       }
+
+       if (strncmp(response, "OK", 2) == 0) {
+               cache_commit(&lkup_result);
+
+               if (flags & VERBOSE) {
+                       if (cached) 
+                               logger(L_DEBUG, L_FUNC, "auth success (cached): [user=%s] [service=%s] [realm=%s]", \
+                                       login, service, realm);
+                       else
+                               logger(L_DEBUG, L_FUNC, "auth success: [user=%s] [service=%s] [realm=%s] [mech=%s]", \
+                                       login, service, realm, auth_mech->name);
+               }
+               return response;
+       }
+
+       if (strncmp(response, "NO", 2) == 0) {
+               logger(L_INFO, L_FUNC, "auth failure: [user=%s] [service=%s] [realm=%s] [mech=%s] [reason=%s]", \
+                       login, service, realm, auth_mech->name,
+                       strlen(response) >= 4 ? response+3 : "Unknown");
+
+               return response;
+       }
+
+       logger(L_ERR, L_FUNC, "mechanism returned unknown response: %s", auth_mech->name);
+       response = strdup("NO internal mechanism failure");
+
+       return response;
+}
+
+
+/*************************************************************
+ * Allow someone to set the auth mech to use
+ **************************************************************/
+void set_auth_mech(const char *mech) {
+       for (auth_mech = mechanisms; auth_mech->name != NULL; auth_mech++) {
+               if (strcasecmp(auth_mech->name, mech) == 0)
+                       break;
+       }
+
+       if (auth_mech->name == NULL) {
+               logger(L_ERR, L_FUNC, "unknown authentication mechanism: %s", mech);
+               exit(1);
+       }
+
+       if (auth_mech->initialize) {
+               if(auth_mech->initialize() != 0) {
+                   logger(L_ERR, L_FUNC, "failed to initialize mechanism %s",
+                          auth_mech->name);
+                   exit(1);
+               }
+       }
+}
+
+
+/*************************************************************
+ * Allow someone to set the number of worker processes we
+ * will use. Only applicable to unix ipc.
+ **************************************************************/
+void set_max_procs(const char *procs) {
+       num_procs = atoi(procs);
+
+       if(num_procs < 0) {
+               logger(L_ERR, L_FUNC, "invalid number of worker processes defined");
+               exit(1);
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Allow someone to set the mechanism specific option
+ **************************************************************/
+void set_mech_option(const char *option) {
+
+       free(mech_option);
+       mech_option = NULL;
+
+       if ((mech_option = strdup(option)) == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Allow someone to set the path to our working directory
+ **************************************************************/
+void set_run_path(const char *path) {
+
+       if (*path != '/') {
+               logger(L_ERR, L_FUNC, "-m requires an absolute pathname");
+               exit(1);
+       }
+
+       free(run_path);
+       run_path = NULL;
+
+       if ((run_path = strdup(path)) == NULL) {
+               logger(L_ERR, L_FUNC, "could not allocate memory");
+               exit(1);
+       }
+
+       return;
+}
+
+
+
+/*************************************************************
+ * Setup all the proper signal masks. 
+ **************************************************************/
+void signal_setup() {
+
+       static struct sigaction act_sigchld;
+       static struct sigaction act_sigalrm;
+       static struct sigaction act_sigterm;
+       static struct sigaction act_sigpipe;
+       static struct sigaction act_sighup;
+       static struct sigaction act_sigint;
+       int                     rc;
+
+       /**************************************************************
+        * Handler for SIGCHLD
+        **************************************************************/
+       act_sigchld.sa_handler = handle_sigchld;
+       sigemptyset(&act_sigchld.sa_mask);
+
+       if (sigaction(SIGCHLD, &act_sigchld, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGCHLD");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       /**************************************************************
+        * Handler for SIGALRM  (IGNORE)
+        **************************************************************/
+       act_sigalrm.sa_handler = SIG_IGN;
+       sigemptyset(&act_sigalrm.sa_mask);
+
+       if (sigaction(SIGALRM, &act_sigalrm, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGALRM");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       /**************************************************************
+        * Handler for SIGPIPE  (IGNORE)
+        **************************************************************/
+       act_sigpipe.sa_handler = SIG_IGN;
+       sigemptyset(&act_sigpipe.sa_mask);
+
+       if (sigaction(SIGPIPE, &act_sigpipe, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGPIPE");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       /**************************************************************
+        * Handler for SIGHUP  (IGNORE)
+        **************************************************************/
+       act_sighup.sa_handler = SIG_IGN;
+       sigemptyset(&act_sighup.sa_mask);
+
+       if (sigaction(SIGHUP, &act_sighup, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGHUP");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       /**************************************************************
+        * Handler for SIGTERM
+        **************************************************************/
+       act_sigterm.sa_handler = server_exit;
+       sigemptyset(&act_sigterm.sa_mask);
+
+       if (sigaction(SIGTERM, &act_sigterm, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGTERM");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       /**************************************************************
+        * Handler for SIGINT
+        **************************************************************/
+       act_sigint.sa_handler = server_exit;
+       sigemptyset(&act_sigint.sa_mask);
+
+       if (sigaction(SIGINT, &act_sigint, NULL) != 0) {
+               rc = errno;
+               logger(L_ERR, L_FUNC, "failed to set sigaction for SIGINT");
+               logger(L_ERR, L_FUNC, "sigaction: %s", strerror(rc));
+               exit(1);
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Detaches us from the controlling tty (aka daemonize). 
+ * More than likely this will be called from an ipc_init()
+ * function as we want to stay in the foreground for as long
+ * as possible.
+ **************************************************************/
+void detach_tty() {
+    int                x;
+    int                rc;
+    int                null_fd;
+    int         exit_result;
+    pid_t              pid;
+    char               pid_buf[100];
+    struct flock       lockinfo;
+    
+    /**************************************************************
+     * Make sure we're supposed to do this, the user may have 
+     * requested us to stay in the foreground.
+     **************************************************************/
+    if (flags & DETACH_TTY) {
+       for(x=5; x; x--) {
+           pid = fork();
+           
+           if ((pid == -1) && (errno == EAGAIN)) {
+               logger(L_ERR, L_FUNC,
+                      "fork failed, retrying");
+               sleep(5);
+               continue;
+           }
+           
+           break;
+       }
+       
+       if (pid == -1) {
+           /* Non retryable error. */
+           rc = errno;
+           logger(L_ERR, L_FUNC, "Cannot start saslauthd");
+           logger(L_ERR, L_FUNC, "saslauthd master fork failed: %s",
+                  strerror(rc));
+           exit(1);
+       } else if (pid != 0) {
+           int exit_code;
+           
+           /* Parent, wait for child */
+           if(read(startup_pipe[0], &exit_code, sizeof(exit_code)) == -1) {
+               logger(L_ERR, L_FUNC,
+                      "Cannot start saslauthd");
+               logger(L_ERR, L_FUNC,
+                      "could not read from startup_pipe");
+               unlink(pid_file_lock);
+               exit(1);
+           } else {
+               if (exit_code != 0) {
+                   logger(L_ERR, L_FUNC, "Cannot start saslauthd");
+                   if (exit_code == 2) {
+                       logger(L_ERR, L_FUNC,
+                              "Another instance of saslauthd is currently running");
+                   } else {
+                       logger(L_ERR, L_FUNC, "Check syslog for errors");
+                   }
+               }
+               unlink(pid_file_lock);
+               exit(exit_code);
+           }
+       }
+       
+       /* Child! */
+       close(startup_pipe[0]);
+       
+       free(pid_file_lock);
+       
+       if (setsid() == -1) {
+           exit_result = 1;
+           rc = errno;
+           
+           logger(L_ERR, L_FUNC, "failed to set session id: %s",
+                  strerror(rc));
+           
+           /* Tell our parent that we failed. */
+           write(startup_pipe[1], &exit_result, sizeof(exit_result));
+           
+           exit(1);
+       }
+       
+       if ((null_fd = open("/dev/null", O_RDWR, 0)) == -1) {
+           exit_result = 1;
+           rc = errno;
+           
+           logger(L_ERR, L_FUNC, "failed to open /dev/null: %s",
+                  strerror(rc));
+           
+           /* Tell our parent that we failed. */
+           write(startup_pipe[1], &exit_result, sizeof(exit_result));
+           
+           exit(1);
+       }
+       
+       /*********************************************************
+        * From this point on, stop printing errors out to stderr.
+        **********************************************************/
+       flags &= ~LOG_USE_STDERR;
+
+       close(STDIN_FILENO);
+       close(STDOUT_FILENO);
+       close(STDERR_FILENO);
+       
+       dup2(null_fd, STDIN_FILENO);
+       dup2(null_fd, STDOUT_FILENO);
+       dup2(null_fd, STDERR_FILENO);
+
+       if (null_fd > 2)
+           close(null_fd);
+               
+       /*********************************************************
+        * Locks don't persist across forks. Relock the pid file
+        * to keep folks from having duplicate copies running...
+        *********************************************************/
+       if (!(pid_file = malloc(strlen(run_path) + sizeof(PID_FILE) + 1))) {
+           exit_result = 1;
+           logger(L_ERR, L_FUNC, "could not allocate memory");
+           write(startup_pipe[1], &exit_result, sizeof(exit_result));
+           exit(1);
+       }
+       
+       strcpy(pid_file, run_path);
+       strcat(pid_file, PID_FILE);
+       
+       /* Write out the pidfile */
+       pid_fd = open(pid_file, O_CREAT|O_RDWR, 0644);
+       if(pid_fd == -1) {
+           rc = errno;
+           exit_result = 1;
+
+           logger(L_ERR, L_FUNC, "could not open pid file %s: %s",
+                  pid_file, strerror(rc));
+           
+           /* Tell our parent that we failed. */
+           write(startup_pipe[1], &exit_result, sizeof(exit_result));
+           
+           exit(1);
+       } else {
+           char buf[100];
+           
+           lockinfo.l_type = F_WRLCK;
+           lockinfo.l_start = 0;
+           lockinfo.l_len = 0;
+           lockinfo.l_whence = SEEK_SET;
+           
+           if (fcntl(pid_fd, F_SETLK, &lockinfo) == -1) {
+               exit_result = 2;
+               rc = errno;
+               
+               logger(L_ERR, L_FUNC, "could not lock pid file %s: %s",
+                      pid_file, strerror(rc));
+               
+               /* Tell our parent that we failed. */
+               write(startup_pipe[1], &exit_result, sizeof(exit_result));
+               
+               exit(2);
+           } else {
+               int pid_fd_flags = fcntl(pid_fd, F_GETFD, 0);
+               
+               if (pid_fd_flags != -1) {
+                   pid_fd_flags =
+                       fcntl(pid_fd, F_SETFD, pid_fd_flags | FD_CLOEXEC);
+               }
+               
+               if (pid_fd_flags == -1) {
+                   int exit_result = 1;
+                   
+                   logger(L_ERR, L_FUNC, "unable to set close-on-exec for pidfile");
+                   
+                   /* Tell our parent that we failed. */
+                   write(startup_pipe[1], &exit_result, sizeof(exit_result));
+                   
+                   exit(1);
+               }
+               
+               /* Write PID */
+               master_pid = getpid();
+               snprintf(buf, sizeof(buf), "%lu\n", (unsigned long)master_pid);
+               if (lseek(pid_fd, 0, SEEK_SET) == -1 ||
+                   ftruncate(pid_fd, 0) == -1 ||
+                   write(pid_fd, buf, strlen(buf)) == -1) {
+                   int exit_result = 1;
+                   rc = errno;
+                   
+                   logger(L_ERR, L_FUNC, "could not write to pid file %s: %s", pid_file, strerror(rc));
+                   
+                   /* Tell our parent that we failed. */
+                   write(startup_pipe[1], &exit_result, sizeof(exit_result));
+                   
+                   exit(1);
+               }
+               fsync(pid_fd);
+           }
+       }
+       
+       {
+           int exit_result = 0;
+           
+           /* success! */
+           if(write(startup_pipe[1], &exit_result, sizeof(exit_result)) == -1) {
+               logger(L_ERR, L_FUNC,
+                      "could not write success result to startup pipe");
+               exit(1);
+           }
+       }
+       
+       close(startup_pipe[1]);
+       if(pid_file_lock_fd != -1) close(pid_file_lock_fd);
+    }
+    
+    logger(L_INFO, L_FUNC, "master pid is: %lu", (unsigned long)master_pid);
+    
+    return;
+}
+
+
+/*************************************************************
+ * Fork off a copy of ourselves. Return 0 if we're the child,
+ * > 0 for the parent. Die if we can't fork (the environment
+ * is probably unstable?).
+ **************************************************************/
+pid_t have_baby() {
+        pid_t   pid;
+        int     rc;
+
+        pid = fork();
+
+        if (pid < 0) {
+                rc = errno;
+                logger(L_ERR, L_FUNC, "could not fork child process");
+                logger(L_ERR, L_FUNC, "fork: %s", strerror(rc));
+                exit(1);
+        }
+
+       /*********************************************************
+        * If we're the child, clear the AM_MASTER flag.
+        **********************************************************/
+       if (pid == 0) {
+               flags &= ~AM_MASTER;
+               return pid;
+       }
+
+        if (flags & VERBOSE) {
+                logger(L_DEBUG, L_FUNC, "forked child: %lu",
+                      (unsigned long)pid);
+       }
+
+        return pid;
+}
+
+
+/*************************************************************
+ * Reap in all the dead children
+ **************************************************************/
+void handle_sigchld() {
+       pid_t pid;
+
+       while ((pid = waitpid(-1, 0, WNOHANG)) > 0) {
+               if (flags & VERBOSE) 
+                       logger(L_DEBUG, L_FUNC, "child exited: %lu", (unsigned long)pid);
+
+       }
+
+       return;
+}
+
+
+/*************************************************************
+ * Do some final cleanup here.
+ **************************************************************/
+void server_exit() {
+       struct flock    lock_st;
+
+       /*********************************************************
+        * If we're not the master process, don't do anything
+        **********************************************************/
+       if (!(flags & AM_MASTER)) {
+               if (flags & VERBOSE)
+                       logger(L_DEBUG, L_FUNC, "child exited: %d", getpid());
+
+               _exit(0);
+       }
+
+       kill(-master_pid, SIGTERM);
+
+       /*********************************************************
+        * Tidy up and delete the pid_file. (close will release the lock)
+         * besides, we want to unlink it first anyway to avoid a race.
+        * Note that only one process (the master, in our case) should
+        * unlink it.
+        **********************************************************/
+       if(flags & DETACH_TTY) {
+           if(getpid() == master_pid) unlink(pid_file);
+           close(pid_fd);
+
+           if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "pid file removed: %s", pid_file);
+
+           free(pid_file);
+       } else {
+           /* Tidy up and delete the pid_file_lock. (in the detached
+              case this is covered by the parent process already */
+
+           unlink(pid_file_lock);
+           close(pid_file_lock_fd);
+           
+           if (flags & VERBOSE)
+               logger(L_DEBUG, L_FUNC, "pid file lock removed: %s",
+                      pid_file_lock);
+           free(pid_file_lock);
+       }
+
+       
+
+       /*********************************************************
+        * Cleanup the cache, if it's enabled
+        **********************************************************/
+       if (flags & CACHE_ENABLED) {
+               cache_cleanup_lock();
+               cache_cleanup_mm();
+       }
+
+       /*********************************************************
+        * Tell the IPC method to clean its room. 
+        **********************************************************/
+       ipc_cleanup();
+
+       /*********************************************************
+        * Any other cleanup should go here
+        **********************************************************/
+
+       logger(L_INFO, L_FUNC, "master exited: %d", master_pid);
+
+       _exit(0);
+}
+
+
+/*************************************************************
+ * Dump out our version and all the auth mechs we support
+ **************************************************************/
+void show_version() {
+    authmech_t *authmech;
+    
+    fprintf(stderr, "saslauthd %s\nauthentication mechanisms:", VERSION);
+
+    for (authmech = mechanisms; authmech->name != NULL; authmech++) {
+       fprintf(stderr, " %s", authmech->name);
+    }
+
+    fprintf(stderr, "\n\n");
+    exit(0);
+}
+
+
+/*************************************************************
+ * Dump out our usage info and tag a show_version after it
+ **************************************************************/
+void show_usage() {
+    fprintf(stderr, "usage: saslauthd [options]\n\n");
+    fprintf(stderr, "option information:\n");
+    fprintf(stderr, "  -a <authmech>  Selects the authentication mechanism to use.\n");
+    fprintf(stderr, "  -c             Enable credential caching.\n");
+    fprintf(stderr, "  -d             Debugging (don't detach from tty, implies -V)\n");
+    fprintf(stderr, "  -r             Combine the realm with the login before passing to authentication mechanism\n");
+    fprintf(stderr, "                 Ex. login: \"foo\" realm: \"bar\" will get passed as login: \"foo@bar\"\n");
+    fprintf(stderr, "                 The realm name is passed untouched.\n");
+    fprintf(stderr, "  -O <option>    Optional argument to pass to the authentication\n");
+    fprintf(stderr, "                 mechanism.\n");
+    fprintf(stderr, "  -l             Disable accept() locking. Increases performance, but\n");
+    fprintf(stderr, "                 may not be compatible with some operating systems.\n");
+    fprintf(stderr, "  -m <path>      Alternate path for the saslauthd working directory,\n");
+    fprintf(stderr, "                 must be absolute.\n"); 
+    fprintf(stderr, "  -n <procs>     Number of worker processes to create.\n");
+    fprintf(stderr, "  -s <kilobytes> Size of the credential cache (in kilobytes)\n");
+    fprintf(stderr, "  -t <seconds>   Timeout for items in the credential cache (in seconds)\n");
+    fprintf(stderr, "  -v             Display version information and available mechs\n");
+    fprintf(stderr, "  -V             Enable verbose logging\n");
+    fprintf(stderr, "  -h             Display this message.\n\n");
+
+    show_version();
+    exit(0);
+}
+
diff --git a/saslauthd/saslauthd-main.h b/saslauthd/saslauthd-main.h
new file mode 100644 (file)
index 0000000..87d223b
--- /dev/null
@@ -0,0 +1,107 @@
+/****************************************************************************
+ *
+ * saslauthd-main.h
+ *
+ * Description:  Header file for saslauthd-main.c
+ *               
+ *
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2003 Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE
+ *
+ * HISTORY
+ * 
+ * Feb 2004: Partial rewrite and cleanup  by Jeremy Rumpf jrumpf@heavyload.net
+ * - Merge the doors and unix IPC methods under a common framework.
+ *
+ * This source file created using 8 space tabs.
+ *
+ ****************************************************************************/
+
+#ifndef _SASLAUTHDMAIN_H
+#define _SASLAUTHDMAIN_H
+
+#include <sys/types.h>
+#include "saslauthd.h"
+
+/****************************************************************
+ * Plug in some autoconf magic to determine what IPC method
+ * to use.
+ ****************************************************************/
+#ifdef USE_DOORS
+# define USE_DOORS_IPC
+#else
+# define USE_UNIX_IPC
+#endif
+
+/* AIX uses a slight variant of this */
+#ifdef _AIX
+# define SALEN_TYPE size_t
+#else 
+# define SALEN_TYPE int
+#endif 
+
+/* Define some macros. These help keep the ifdefs out of the
+ * mainline code. */
+#ifdef AUTH_SIA
+#define SET_AUTH_PARAMETERS(argc, argv) set_auth_parameters(argc, argv)
+#else
+#define SET_AUTH_PARAMETERS(argc, argv)
+#endif
+
+/* file name defines - don't forget the '/' in these! */
+#define PID_FILE               "/saslauthd.pid"    
+#define PID_FILE_LOCK          "/saslauthd.pid.lock"
+#define ACCEPT_LOCK_FILE       "/mux.accept"       
+#define SOCKET_FILE            "/mux"              
+#define DOOR_FILE              "/mux"              
+
+/* login, pw, service, realm buffer size */
+#define MAX_REQ_LEN            256     
+
+/* socket backlog when supported */
+#define SOCKET_BACKLOG         32
+
+/* saslauthd-main.c */
+extern char    *do_auth(const char *, const char *,
+                        const char *, const char *);
+extern void    set_auth_mech(const char *);
+extern void    set_max_procs(const char *);
+extern void    set_mech_option(const char *);
+extern void    set_run_path(const char *);
+extern void    signal_setup();
+extern void    detach_tty();
+extern void    handle_sigchld();
+extern void    server_exit();
+extern pid_t   have_baby();
+
+/* ipc api delcarations */
+extern void    ipc_init();
+extern void    ipc_loop();
+extern void    ipc_cleanup();
+
+#endif  /* _SASLAUTHDMAIN_H */
diff --git a/saslauthd/saslauthd.8 b/saslauthd/saslauthd.8
new file mode 100644 (file)
index 0000000..6eab473
--- /dev/null
@@ -0,0 +1,189 @@
+SASLAUTHD(8)              BSD System Manager’s Manual             SASLAUTHD(8)
+
+N\bNA\bAM\bME\bE
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd - sasl authentication server
+
+S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd -\b-a\ba _\ba_\bu_\bt_\bh_\bm_\be_\bc_\bh [-\b-T\bTv\bvd\bdc\bch\bhl\blr\br] [-\b-O\bO _\bo_\bp_\bt_\bi_\bo_\bn] [-\b-m\bm _\bm_\bu_\bx_\b__\bp_\ba_\bt_\bh] [-\b-n\bn _\bt_\bh_\br_\be_\ba_\bd_\bs]
+               [-\b-s\bs _\bs_\bi_\bz_\be] [-\b-t\bt _\bt_\bi_\bm_\be_\bo_\bu_\bt]
+
+D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd is a daemon process that handles plaintext authentication
+     requests on behalf of the SASL library.
+
+     The server fulfills two roles: it isolates all code requiring superuser
+     privileges into a single process, and it can be used to provide _\bp_\br_\bo_\bx_\by
+     authentication services to clients that do not understand SASL based
+     authentication.
+
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd should be started from the system boot scripts when going to
+     multi-user mode. When running against a protected authentication database
+     (e.g. the shadow mechanism), it must be run as the superuser.
+
+   O\bOp\bpt\bti\bio\bon\bns\bs
+     Options named by lower-case letters configure the server itself.
+     Upper-case options control the behavior of specific authentication mecha-
+     nisms; their applicability to a particular authentication mechanism is
+     described in the _\bA_\bU_\bT_\bH_\bE_\bN_\bT_\bI_\bC_\bA_\bT_\bI_\bO_\bN _\bM_\bE_\bC_\bH_\bA_\bN_\bI_\bS_\bM_\bS section.
+
+     -\b-a\ba _\ba_\bu_\bt_\bh_\bm_\be_\bc_\bh
+             Use _\ba_\bu_\bt_\bh_\bm_\be_\bc_\bh as the authentication mechanism. (See the
+             _\bA_\bU_\bT_\bH_\bE_\bN_\bT_\bI_\bC_\bA_\bT_\bI_\bO_\bN _\bM_\bE_\bC_\bH_\bA_\bN_\bI_\bS_\bM_\bS section below.) This parameter is
+             mandatory.
+
+     -\b-O\bO _\bo_\bp_\bt_\bi_\bo_\bn
+             A mechanism specific option (e.g. rimap hostname or config file
+             path)
+
+     -\b-H\bH _\bh_\bo_\bs_\bt_\bn_\ba_\bm_\be
+             The remote host to be contacted by the rimap authentication mech-
+             anism. (Depricated, use -O instead)
+
+     -\b-m\bm _\bp_\ba_\bt_\bh
+             Use _\bp_\ba_\bt_\bh as the pathname to the named socket to listen on for
+             connection requests. This must be an absolute pathname, and MUST
+             NOT include the trailing "/mux".  Note that the default for this
+             value is "/var/state/saslauthd" (or what was specified at compile
+             time) and that this directory must exist for saslauthd to func-
+             tion.
+
+     -\b-n\bn _\bt_\bh_\br_\be_\ba_\bd_\bs
+             Use _\bt_\bh_\br_\be_\ba_\bd_\bs processes for responding to authentication queries.
+             (default: 5)  A value of zero will indicate that saslauthd should
+             fork an individual process for each connection.  This can solve
+             leaks that occur in some deployments..
+
+     -\b-s\bs _\bs_\bi_\bz_\be
+             Use _\bs_\bi_\bz_\be as the table size of the hash table (in kilobytes)
+
+     -\b-t\bt _\bt_\bi_\bm_\be_\bo_\bu_\bt
+             Use _\bt_\bi_\bm_\be_\bo_\bu_\bt as the expiration time of the authentication cache
+             (in seconds)
+
+     -\b-T\bT      Honour time-of-day login restrictions.
+
+     -\b-h\bh      Show usage information
+
+     -\b-c\bc      Enable cacheing of authentication credentials
+
+     -\b-l\bl      Disable the use of a lock file for controlling access to
+             accept().
+
+     -\b-r\br      Combine the realm with the login (with an â€™@’ sign in between).
+             e.g.  login: "foo" realm: "bar" will get passed as login:
+             "foo@bar".  Note that the realm will still be passed, which may
+             lead to unexpected behavior.
+
+     -\b-v\bv      Print the version number and available authentication mechanisms
+             on standard error, then exit.
+
+     -\b-d\bd      Debugging mode.
+
+   L\bLo\bog\bgg\bgi\bin\bng\bg
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd logs it’s activities via s\bsy\bys\bsl\blo\bog\bgd\bd using the LOG_AUTH facility.
+
+A\bAU\bUT\bTH\bHE\bEN\bNT\bTI\bIC\bCA\bAT\bTI\bIO\bON\bN M\bME\bEC\bCH\bHA\bAN\bNI\bIS\bSM\bMS\bS
+     s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd supports one or more "authentication mechanisms", dependent
+     upon the facilities provided by the underlying operating system.  The
+     mechanism is selected by the -\b-a\bah\bho\bo flag from the following list of
+     choices:
+
+     dce        _\b(_\bA_\bI_\bX_\b)
+
+                Authenticate using the DCE authentication environment.
+
+     getpwent   _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs_\b)
+
+                Authenticate using the g\bge\bet\btp\bpw\bwe\ben\bnt\bt() library function. Typically
+                this authenticates against the local password file. See your
+                systems getpwent(3) man page for details.
+
+     kerberos4  _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs_\b)
+
+                Authenticate against the local Kerberos 4 realm. (See the
+                _\bN_\bO_\bT_\bE_\bS section for caveats about this driver.)
+
+     kerberos5  _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs_\b)
+
+                Authenticate against the local Kerberos 5 realm.
+
+     pam        _\b(_\bL_\bi_\bn_\bu_\bx_\b, _\bS_\bo_\bl_\ba_\br_\bi_\bs_\b)
+
+                Authenticate using Pluggable Authentication Modules (PAM).
+
+     rimap      _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs_\b)
+
+                Forward authentication requests to a remote IMAP server. This
+                driver connects to a remote IMAP server, specified using the
+                -O flag, and attempts to login (via an IMAP â€˜LOGIN’ command)
+                using the credentials supplied to the local server. If the
+                remote authentication succeeds the local connection is also
+                considered to be authenticated. The remote connection is
+                closed as soon as the tagged response from the â€˜LOGIN’ command
+                is received from the remote server.
+
+                The _\bo_\bp_\bt_\bi_\bo_\bn parameter to the -\b-O\bO flag describes the remote
+                server to forward authentication requests to.  _\bh_\bo_\bs_\bt_\bn_\ba_\bm_\be can be
+                a hostname (imap.example.com) or a dotted-quad IP address
+                (192.168.0.1). The latter is useful if the remote server is
+                multi-homed and has network interfaces that are unreachable
+                from the local IMAP server. The remote host is contacted on
+                the â€˜imap’ service port. A non-default port can be specified
+                by appending a slash and the port name or number to the
+                _\bh_\bo_\bs_\bt_\bn_\ba_\bm_\be argument.
+
+                The -\b-O\bO flag and argument are mandatory when using the rimap
+                mechanism.
+
+     shadow     _\b(_\bA_\bI_\bX_\b, _\bI_\br_\bi_\bx_\b, _\bL_\bi_\bn_\bu_\bx_\b, _\bS_\bo_\bl_\ba_\br_\bi_\bs_\b)
+
+                Authenticate against the local "shadow password file".  The
+                exact mechanism is system dependent.  s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd currently
+                understands the g\bge\bet\bts\bsp\bpn\bna\bam\bm() and g\bge\bet\btu\bus\bse\ber\brp\bpw\bw() library routines.
+                Some systems honour the -\b-T\bT flag.
+
+     sasldb     _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs_\b)
+
+                Authenticate against the SASL authentication database.  Note
+                that this is probabally not what you want to be using, and is
+                even disabled at compile-time by default.  If you want to use
+                sasldb with the SASL library, you probably want to use the
+                pwcheck_method of "auxprop" along with the sasldb auxprop plu-
+                gin instead.
+
+     ldap       _\b(_\bA_\bl_\bl _\bp_\bl_\ba_\bt_\bf_\bo_\br_\bm_\bs _\bt_\bh_\ba_\bt _\bs_\bu_\bp_\bp_\bo_\br_\bt _\bO_\bp_\be_\bn_\bL_\bD_\bA_\bP _\b2_\b._\b0 _\bo_\br _\bh_\bi_\bg_\bh_\be_\br_\b)
+
+                Authenticate against an ldap server.  The ldap configuration
+                parameters are read from /usr/local/etc/saslauthd.conf.  The
+                location of this file can be changed with the -O parameter.
+                See the LDAP_SASLAUTHD file included with the distribution for
+                the list of available parameters.
+
+     sia        _\b(_\bD_\bi_\bg_\bi_\bt_\ba_\bl _\bU_\bN_\bI_\bX_\b)
+
+                Authenticate using the Digital UNIX Security Integration
+                Architecture (a.k.a.  "enhanced security").
+
+N\bNO\bOT\bTE\bES\bS
+     The kerberos4 authentication driver consumes considerable resources. To
+     perform an authentication it must obtain a ticket granting ticket from
+     the TGT server o\bon\bn e\bev\bve\ber\bry\by a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn r\bre\beq\bqu\bue\bes\bst\bt.\b. The Kerberos library rou-
+     tines that obtain the TGT also create a local ticket file, on the reason-
+     able assumption that you will want to save the TGT for use by other Ker-
+     beros applications. These ticket files are unusable by s\bsa\bas\bsl\bla\bau\but\bth\bhd\bd , how-
+     ever there is no way not to create them. The overhead of creating and
+     removing these ticket files can cause serious performance degradation on
+     busy servers. (Kerberos was never intended to be used in this manner,
+     anyway.)
+
+F\bFI\bIL\bLE\bES\bS
+     /var/run/saslauthd/mux  The default communications socket.
+
+     /usr/local/etc/saslauthd.conf
+                             The default configuration file for ldap support.
+
+S\bSE\bEE\bE A\bAL\bLS\bSO\bO
+     passwd(1), getpwent(3), getspnam(3), getuserpw(3), sasl_checkpass(3)
+     sia_authenticate_user(3),
+
+CMU-SASL                          10 24 2002                          CMU-SASL
diff --git a/saslauthd/saslauthd.h.in b/saslauthd/saslauthd.h.in
new file mode 100644 (file)
index 0000000..b816dca
--- /dev/null
@@ -0,0 +1,319 @@
+/* saslauthd.h.in.  Generated from configure.in by autoheader.  */
+
+
+#ifndef _SASLAUTHD_H
+#define _SASLAUTHD_H
+
+#include <stdio.h>
+
+
+/* Include SASLdb Support */
+#undef AUTH_SASLDB
+
+/* Define if your getpwnam_r()/getspnam_r() functions take 5 arguments */
+#undef GETXXNAM_R_5ARG
+
+/* Define to 1 if you have the <crypt.h> header file. */
+#undef HAVE_CRYPT_H
+
+/* Define to 1 if you have the `dns_lookup' function. */
+#undef HAVE_DNS_LOOKUP
+
+/* Define to 1 if you have the `dn_expand' function. */
+#undef HAVE_DN_EXPAND
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Does the compiler understand __func__ */
+#undef HAVE_FUNC
+
+/* Does compiler understand __FUNCTION__ */
+#undef HAVE_FUNCTION
+
+/* Do we have a getaddrinfo? */
+#undef HAVE_GETADDRINFO
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Do we have a getnameinfo() function? */
+#undef HAVE_GETNAMEINFO
+
+/* Define to 1 if you have the `getspnam' function. */
+#undef HAVE_GETSPNAM
+
+/* Define to 1 if you have the `getuserpw' function. */
+#undef HAVE_GETUSERPW
+
+/* Include GSSAPI/Kerberos 5 Support */
+#undef HAVE_GSSAPI
+
+/* Define if you have the gssapi.h header file */
+#undef HAVE_GSSAPI_H
+
+/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function.
+   */
+#undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY
+
+/* Define if your GSSAPI implimentation defines GSS_C_NT_HOSTBASED_SERVICE */
+#undef HAVE_GSS_C_NT_HOSTBASED_SERVICE
+
+/* Define if your GSSAPI implimentation defines GSS_C_NT_USER_NAME */
+#undef HAVE_GSS_C_NT_USER_NAME
+
+/* Include HTTP form Support */
+#undef HAVE_HTTPFORM
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Do we have Kerberos 4 Support? */
+#undef HAVE_KRB
+
+/* Define to 1 if you have the <krb5.h> header file. */
+#undef HAVE_KRB5_H
+
+/* Define to 1 if you have the `krb_get_err_text' function. */
+#undef HAVE_KRB_GET_ERR_TEXT
+
+/* Support for LDAP? */
+#undef HAVE_LDAP
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdir' function. */
+#undef HAVE_MKDIR
+
+/* Do we have OpenSSL? */
+#undef HAVE_OPENSSL
+
+/* Support for PAM? */
+#undef HAVE_PAM
+
+/* Does compiler understand __PRETTY_FUNCTION__ */
+#undef HAVE_PRETTY_FUNCTION
+
+/* Include support for saslauthd? */
+#undef HAVE_SASLAUTHD
+
+/* Include SIA Support */
+#undef HAVE_SIA
+
+/* Does sockaddr have an sa_len? */
+#undef HAVE_SOCKADDR_SA_LEN
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Do we have a socklen_t? */
+#undef HAVE_SOCKLEN_T
+
+/* Is there an ss_family in sockaddr_storage? */
+#undef HAVE_SS_FAMILY
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlcat' function. */
+#undef HAVE_STRLCAT
+
+/* Define to 1 if you have the `strlcpy' function. */
+#undef HAVE_STRLCPY
+
+/* Do we have a sockaddr_storage struct? */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#undef HAVE_SYS_UIO_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Using Heimdal */
+#undef KRB5_HEIMDAL
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Location of saslauthd socket */
+#undef PATH_SASLAUTHD_RUNDIR
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* Saslauthd runs threaded? */
+#undef SASLAUTHD_THREADED
+
+/* Use BerkeleyDB for SASLdb */
+#undef SASL_BERKELEYDB
+
+/* Path to default SASLdb database */
+#undef SASL_DB_PATH
+
+/* Use GDBM for SASLdb */
+#undef SASL_GDBM
+
+/* Use NDBM for SASLdb */
+#undef SASL_NDBM
+
+/* The size of a `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* User KERBEROS_V4 Staticly */
+#undef STATIC_KERBEROS4
+
+/* Link SASLdb Staticly */
+#undef STATIC_SASLDB
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Use the doors IPC API */
+#undef USE_DOORS
+
+/* Version number of package */
+#undef VERSION
+
+/* Use DES */
+#undef WITH_DES
+
+/* Use OpenSSL DES Implementation */
+#undef WITH_SSL_DES
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+
+
+#ifndef HAVE___ATTRIBUTE__
+/* Can't use attributes... */
+#define __attribute__(foo)
+#endif
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifndef WIN32
+# include <netdb.h>   
+# include <sys/param.h>
+#else /* WIN32 */
+# include <winsock2.h>
+#endif /* WIN32 */ 
+#include <string.h>
+
+#include <netinet/in.h>
+
+#ifndef HAVE_SOCKLEN_T
+typedef unsigned int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+#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
+
+/* Create a struct iovec if we need one */
+#if !defined(HAVE_SYS_UIO_H)
+struct iovec {
+    long iov_len;
+    char *iov_base;
+};
+#else
+#include <sys/types.h>
+#include <sys/uio.h>
+#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
+
+#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
+#define        AI_NUMERICHOST  4
+#define NI_NUMERICHOST 2
+#define NI_NAMEREQD    4
+#define NI_NUMERICSERV 8
+#endif
+
+/* handy string manipulation functions */
+#ifndef HAVE_STRLCPY
+extern size_t saslauthd_strlcpy(char *dst, const char *src, size_t len);
+#define strlcpy(x,y,z) saslauthd_strlcpy((x),(y),(z))
+#endif
+#ifndef HAVE_STRLCAT
+extern size_t saslauthd_strlcat(char *dst, const char *src, size_t len);
+#define strlcat(x,y,z) saslauthd_strlcat((x),(y),(z))
+#endif
+
+#endif
+
diff --git a/saslauthd/saslauthd.mdoc b/saslauthd/saslauthd.mdoc
new file mode 100644 (file)
index 0000000..ee011bf
--- /dev/null
@@ -0,0 +1,261 @@
+.\" $Id: saslauthd.mdoc,v 1.18 2004/03/25 18:24:26 rjs3 Exp $
+.\" Copyright 1997-2001 Messaging Direct Ltd. All rights reserved.
+.\"
+.\" This manpage uses the BSD mdoc manpage macros. Please don't
+.\" downgrade it to -man. The -mdoc macros are included with
+.\" GNU roff, and, of course, with the BSD distributions.
+.\"
+.\" To make life easier for sites that don't support -mdoc,
+.\" please generate (and commit!) an updated pre-formatted
+.\" manpage in saslauthd.8 whenever you change this source
+.\" version. Only the pre-formatted manpage is installed.
+.\"
+.Dd 10 24 2002
+.Dt SASLAUTHD 8
+.Os "CMU-SASL"
+.Sh NAME
+.Nm saslauthd
+.Nd sasl authentication server
+.Sh SYNOPSIS
+.Nm
+.Fl a
+.Ar authmech
+.Op Fl \&Tvdchlr
+.Op Fl O Ar option
+.Op Fl m Ar mux_path
+.Op Fl n Ar threads
+.Op Fl s Ar size
+.Op Fl t Ar timeout
+.Sh DESCRIPTION
+.Nm
+is a daemon process that handles plaintext authentication requests
+on behalf of the SASL library.
+.Pp
+The server fulfills two roles: it isolates all code requiring superuser
+privileges into a single process, and it can be used to provide
+.Em proxy
+authentication services to clients that do not understand
+SASL based authentication.
+.Pp
+.Nm
+should be
+started from the system boot scripts when going to
+multi-user mode. When running against a protected authentication
+database (e.g. the
+.Li shadow
+mechanism),
+it must be run as the superuser.
+.Ss Options
+Options named by lower\-case letters configure the server itself.
+Upper\-case options control the behavior of specific authentication
+mechanisms; their applicability to a particular authentication
+mechanism is described in the
+.Sx AUTHENTICATION MECHANISMS
+section.
+.Bl -tag -width indent
+.It Fl a Ar authmech
+Use
+.Ar authmech
+as the authentication mechanism. (See the
+.Sx AUTHENTICATION MECHANISMS
+section below.) This parameter is mandatory.
+.It Fl O Ar option
+A mechanism specific option (e.g. rimap hostname or config file path)
+.It Fl H Ar hostname
+The remote host to be contacted by the
+.Li rimap
+authentication mechanism. (Depricated, use -O instead)
+.It Fl m Ar path
+Use
+.Ar path
+as the pathname to the named socket to listen on for
+connection requests. This must be an absolute pathname, and MUST NOT
+include the trailing "/mux".  Note that the default for this value
+is "/var/state/saslauthd" (or what was specified at compile time)
+and that this directory must exist for saslauthd to function.
+.It Fl n Ar threads
+Use
+.Ar threads
+processes for responding to authentication queries. (default: 5)  A
+value of zero will indicate that saslauthd should fork an individual
+process for each connection.  This can solve leaks that occur in some
+deployments..
+.It Fl s Ar size
+Use
+.Ar size
+as the table size of the hash table (in kilobytes)
+.It Fl t Ar timeout
+Use
+.Ar timeout
+as the expiration time of the authentication cache (in seconds)
+.It Fl T
+Honour time-of-day login restrictions.
+.It Fl h
+Show usage information
+.It Fl c
+Enable cacheing of authentication credentials
+.It Fl l
+Disable the use of a lock file for controlling access to accept().
+.It Fl r
+Combine the realm with the login (with an '@' sign in between).  e.g.
+login: "foo" realm: "bar" will get passed as login: "foo@bar".  Note that
+the realm will still be passed, which may lead to unexpected behavior.
+.It Fl v
+Print the version number and available authentication
+mechanisms on standard error, then exit.
+.It Fl d
+Debugging mode.
+.El
+.Ss Logging
+.Nm
+logs it's activities via
+.Nm syslogd
+using the
+.Dv LOG_AUTH
+facility.
+.Sh AUTHENTICATION MECHANISMS
+.Nm
+supports one or more
+.Qq authentication mechanisms ,
+dependent upon the facilities provided by the underlying operating system.
+The mechanism is selected by the
+.Fl aho
+flag from the following list of choices:
+.Bl -tag -width "kerberos4"
+.It Li dce
+.Em (AIX)
+.Pp
+Authenticate using the DCE authentication environment.
+.It Li getpwent
+.Em (All platforms)
+.Pp
+Authenticate using the
+.Fn getpwent
+library function. Typically this authenticates against the
+local password file. See your systems
+.Xr getpwent 3
+man page for details.
+.It Li kerberos4
+.Em (All platforms)
+.Pp
+Authenticate against the local Kerberos 4 realm. (See the
+.Sx NOTES
+section for caveats about this driver.)
+.It Li kerberos5
+.Em (All platforms)
+.Pp
+Authenticate against the local Kerberos 5 realm.
+.It Li pam
+.Em (Linux, Solaris)
+.Pp
+Authenticate using Pluggable Authentication Modules (PAM).
+.It Li rimap
+.Em (All platforms)
+.Pp
+Forward authentication requests to a remote IMAP server. This driver
+connects to a remote IMAP server, specified using the -O flag,
+and attempts to login (via an IMAP
+.Ql LOGIN
+command) using the credentials 
+supplied to the local
+server. If the remote authentication succeeds the local connection
+is also considered to be authenticated. The remote connection is closed
+as soon as the tagged response from the
+.Ql LOGIN
+command is received from the remote
+server.
+.Pp
+The
+.Ar option
+parameter to the
+.Fl O
+flag describes the remote server to forward
+authentication requests to.
+.Ar hostname
+can be a hostname (imap.example.com) or a dotted\-quad IP address
+(192.168.0.1). The latter is useful if the remote server is
+multi\-homed and has network interfaces that are unreachable from
+the local IMAP server. The remote host is contacted on the
+.Ql imap
+service port. A non\-default port can be specified by appending
+a slash and the port name or number
+to the
+.Ar hostname
+argument.
+.Pp
+The
+.Fl O
+flag and argument are mandatory when using the
+.Li rimap
+mechanism.
+.It Li shadow
+.Em (AIX, Irix, Linux, Solaris)
+.Pp
+Authenticate against the local
+.Qq shadow password file .
+The exact mechanism is system dependent.
+.Nm
+currently understands the
+.Fn getspnam
+and
+.Fn getuserpw
+library routines. Some systems
+honour the
+.Fl T
+flag.
+.It Li sasldb
+.Em (All platforms)
+.Pp
+Authenticate against the
+SASL authentication database.  Note that this is probabally not what you
+want to be using, and is even disabled at compile-time by default.
+If you want to use sasldb with the SASL library, you probably want to
+use the pwcheck_method of "auxprop" along with the sasldb auxprop plugin
+instead.
+.It Li ldap
+.Em (All platforms that support OpenLDAP 2.0 or higher)
+.Pp
+Authenticate against an ldap server.  The ldap configuration parameters are
+read from /usr/local/etc/saslauthd.conf.  The location of this file can be
+changed with the -O parameter. See the LDAP_SASLAUTHD file included with the
+distribution for the list of available parameters.
+.It Li sia
+.Em (Digital UNIX)
+.Pp
+Authenticate using the Digital
+.Ux
+Security Integration Architecture
+(a.k.a.
+.Qq enhanced security ) .
+.El
+.Sh NOTES
+The
+.Li kerberos4
+authentication driver consumes considerable resources. To perform an
+authentication it must obtain a ticket granting ticket
+from the TGT server
+.Sy on every authentication request.
+The Kerberos library routines that obtain the TGT also create a
+local ticket file, on the reasonable assumption that you will want
+to save the TGT for use by other Kerberos applications. These ticket
+files are unusable by
+.Nm No ,
+however there is no way not to create them. The overhead of creating
+and removing
+these ticket files can cause serious performance degradation on busy
+servers. (Kerberos
+was never intended to be used in this manner, anyway.)
+.Sh FILES
+.Bl -tag -width "/var/run/saslauthd/mux"
+.It Pa /var/run/saslauthd/mux
+The default communications socket.
+.It Pa /usr/local/etc/saslauthd.conf
+The default configuration file for ldap support.
+.El
+.Sh SEE ALSO
+.Xr passwd 1 ,
+.Xr getpwent 3 ,
+.Xr getspnam 3 ,
+.Xr getuserpw 3 ,
+.Xr sasl_checkpass 3
+.Xr sia_authenticate_user 3 ,
diff --git a/saslauthd/saslauthd_md5.h b/saslauthd/saslauthd_md5.h
new file mode 100644 (file)
index 0000000..1d25449
--- /dev/null
@@ -0,0 +1,37 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* MD5 context. */
+typedef struct {
+  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 _saslauthd_MD5Init PROTO_LIST ((MD5_CTX *));
+void _saslauthd_MD5Update PROTO_LIST
+  ((MD5_CTX *, unsigned char *, unsigned int));
+void _saslauthd_MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
+
+void _saslauthd_hmac_md5 PROTO_LIST ((unsigned char *, int, unsigned char *, int, caddr_t));
diff --git a/saslauthd/saslcache.c b/saslauthd/saslcache.c
new file mode 100644 (file)
index 0000000..a22371c
--- /dev/null
@@ -0,0 +1,313 @@
+/*******************************************************************************
+ * *****************************************************************************
+ * *
+ * * saslcache.c
+ * *
+ * * Description:  A small utility that can attach to saslauthd's shared
+ * *               memory region and display/dump information in the cache.
+ * *
+ * * Copyright (C) 2003 Jeremy Rumpf
+ * *
+ * * 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.
+ * *
+ * * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * * THE POSSIBILITY OF SUCH DAMAGE
+ * *
+ * * Jeremy Rumpf
+ * * jrumpf@heavyload.net
+ * *
+ * ******************************************************************************
+ ********************************************************************************/
+
+/****************************************
+* * includes
+*****************************************/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+#include "cache.h"
+
+
+/****************************************
+* * declarations/protos
+*****************************************/
+void   show_usage(void);
+void   dump_cache_stats(void);
+void   dump_cache_users(void);
+char   *make_time(time_t);
+
+/****************************************
+* * module globals
+*****************************************/
+static  void            *shm_base = NULL;
+static  struct bucket   *table = NULL;
+static  struct stats    *table_stats = NULL;
+
+/****************************************
+*****************************************/
+
+
+/*************************************************************
+* * Main
+**************************************************************/
+int main(int argc, char **argv) {
+
+       int             option;
+       int             dump_user_info = 0;
+       int             dump_stat_info = 0;
+       char            *file = NULL;
+       int             file_fd;
+       int             shmid = 0;
+       char            shmid_buff[256];
+       char            cache_magic[64];
+       struct stat     stat_buff;
+
+       while ((option = getopt(argc, argv, "dm:s")) != -1) {
+               switch(option) {
+
+                       case 'd':
+                               dump_user_info = 1;
+                               break;
+
+                       case 's':
+                               dump_stat_info = 1;
+                               break;
+
+                       case 'm':
+                               file = strdup(optarg);
+                               break;
+
+                       default:
+                               show_usage();
+               }
+       }
+
+       if (file == NULL)
+               file = PATH_SASLAUTHD_RUNDIR "/cache.mmap";
+
+       if (stat(file, &stat_buff) == -1) {
+               fprintf(stderr, "could not stat mmap file: %s\n", file);
+               fprintf(stderr, "stat: %s\n", strerror(errno));
+               exit(1);
+       }
+
+       if ((file_fd = open(file, O_RDONLY)) < 0) {
+               fprintf(stderr, "could not open mmap file: %s\n", file);
+               fprintf(stderr, "open: %s\n", strerror(errno));
+               fprintf(stderr, "perhaps saslcache -m <path>\n");
+               exit(1);
+       }
+
+       if ((shm_base = mmap(NULL, stat_buff.st_size, PROT_READ, MAP_SHARED, file_fd, 0))== (void *)-1) {
+               fprintf(stderr, "could not mmap shared memory file: %s\n", file);
+               fprintf(stderr, "mmap: %s\n", strerror(errno));
+               exit(1);
+       }       
+
+       memcpy(cache_magic, shm_base, 64);
+       cache_magic[63] = '\0';
+
+       if (strcmp(cache_magic, CACHE_CACHE_MAGIC) != 0) {
+               fprintf(stderr, "mmap file [%s] is not a valid saslauthd cache\n", file);
+               exit(1);
+       }
+
+       table_stats = shm_base + 64;
+       (char *)table = (char *)table_stats + 128;
+
+       if (dump_stat_info == 0 && dump_user_info == 0)
+               dump_stat_info = 1;
+
+       if (dump_stat_info)
+               dump_cache_stats();
+
+       if (dump_user_info)
+               dump_cache_users();
+
+       exit(0);        
+}
+
+
+/****************************************************
+* * Dump a delimited record for each item in the
+* * cache to stdout.
+****************************************************/
+void dump_cache_users(void) {
+
+       unsigned int            x;
+       struct bucket           *ref_bucket;
+        time_t                 epoch_to;
+
+       epoch_to = time(NULL) - table_stats->timeout;
+
+       fprintf(stdout, "\"user\",\"realm\",\"service\",\"created\",\"created_localtime\"\n");
+
+       for (x = 0; x < (table_stats->table_size * table_stats->max_buckets_per); x++) {
+
+               ref_bucket = table + x;
+
+               if (ref_bucket->created > epoch_to && *(ref_bucket->creds) != '\0') {
+                       fprintf(stderr, "\"%s\",", ref_bucket->creds + ref_bucket->user_offt);
+                       fprintf(stderr, "\"%s\",", ref_bucket->creds + ref_bucket->realm_offt);
+                       fprintf(stderr, "\"%s\",", ref_bucket->creds + ref_bucket->service_offt);
+                       fprintf(stderr, "\"%lu\",", ref_bucket->created);
+                       fprintf(stderr, "\"%s\"\n", make_time(ref_bucket->created));
+               }
+       }
+}
+
+/****************************************************
+* * Dump some usage statistics about the cred cache.
+* * (clean this up someday)
+****************************************************/
+void dump_cache_stats(void) {
+
+        unsigned int           x, y, z;
+        float                  a;
+        unsigned int           max_chain_length = 0;
+        unsigned int           min_chain_length = 0;
+        unsigned int           buckets_in_use = 0;
+        unsigned int           slots_in_use = 0;
+        unsigned int           slots_max_chain = 0;
+        unsigned int           slots_min_chain = 0;
+        time_t                 epoch_to;
+
+
+       min_chain_length = table_stats->max_buckets_per;
+       epoch_to = time(NULL) - table_stats->timeout;
+
+       for (x = 0; x < table_stats->table_size; x++) {
+
+               z = 0;
+
+               for (y = (x * table_stats->max_buckets_per); y < ((x + 1) * table_stats->max_buckets_per); y++) { 
+                       if (table[y].created > epoch_to) {
+                               buckets_in_use++;
+                               z++;
+                       }
+               }
+
+               if (z == min_chain_length)
+                       slots_min_chain++;
+
+               if (z == max_chain_length)
+                       slots_max_chain++;
+
+               if (z > 0)
+                       slots_in_use++;
+
+               if (z > max_chain_length) {
+                       max_chain_length = z;
+                       slots_max_chain = 1;
+               }
+
+               if (z < min_chain_length) {
+                       min_chain_length = z;
+                       slots_min_chain = 1;
+               }
+       }
+
+       fprintf(stdout, "----------------------------------------\n");
+       fprintf(stdout, "Saslauthd Cache Detail:\n");
+       fprintf(stdout, "\n");
+       fprintf(stdout, "  timeout (seconds)           :  %d\n", table_stats->timeout);
+       fprintf(stdout, "  total slots allocated       :  %d\n", table_stats->table_size);
+       fprintf(stdout, "  slots in use                :  %d\n", slots_in_use);
+       fprintf(stdout, "  total buckets               :  %d\n", (table_stats->max_buckets_per * table_stats->table_size));
+       fprintf(stdout, "  buckets per slot            :  %d\n", table_stats->max_buckets_per);
+       fprintf(stdout, "  buckets in use              :  %d\n", buckets_in_use);
+       fprintf(stdout, "  hash table size (bytes)     :  %d\n", table_stats->bytes);
+       fprintf(stdout, "  bucket size (bytes)         :  %d\n", table_stats->sizeof_bucket);
+       fprintf(stdout, "  minimum slot allocation     :  %d\n", min_chain_length);
+       fprintf(stdout, "  maximum slot allocation     :  %d\n", max_chain_length);
+       fprintf(stdout, "  slots at maximum allocation :  %d\n", slots_max_chain);
+       fprintf(stdout, "  slots at minimum allocation :  %d\n", slots_min_chain);
+
+       if (table_stats->table_size == 0)
+               a = 0;
+       else
+               a = slots_in_use / (float)table_stats->table_size;
+
+       fprintf(stdout, "  overall hash table load     :  %0.2f\n", a);
+       fprintf(stdout, "\n");
+       fprintf(stdout, "  hits*                       :  %d\n", table_stats->hits);
+       fprintf(stdout, "  misses*                     :  %d\n", table_stats->misses);
+       fprintf(stdout, "  total lookup attempts*      :  %d\n", table_stats->attempts);
+
+       if (table_stats->attempts == 0)
+               a = 0;
+       else
+               a = (table_stats->hits / (float)table_stats->attempts) * 100;
+
+       fprintf(stdout, "  hit ratio*                  :  %0.2f\n", a);
+       fprintf(stdout, "  flock failures*             :  %d\n", table_stats->lock_failures);
+       fprintf(stdout, "----------------------------------------\n");
+       fprintf(stdout, "* May not be completely accurate\n");
+       fprintf(stdout, "----------------------------------------\n\n");
+}
+
+
+/**************************************************
+* * Create a human readable time representation
+****************************************************/
+char   *make_time(time_t epoch) {
+
+       static char     created_str[128];
+       struct  tm      *tm_st = NULL;
+
+
+       tm_st = localtime(&epoch);      
+
+       if (tm_st == NULL) 
+               return "unknown";
+
+       strftime(created_str, 127, "%c", tm_st);
+       created_str[127] = '\0';
+
+       return created_str;
+}
+
+
+/**************************************************
+* * Dump out the usage information and exit
+****************************************************/
+void show_usage(void) {
+
+    fprintf(stderr, "usage: saslcache [options]\n\n");
+    fprintf(stderr, "option information:\n");
+    fprintf(stderr, "  -d             Dumps a csv list of information in the cache.\n");
+    fprintf(stderr, "  -f             Purges all entries from the cache.\n");
+    fprintf(stderr, "  -m <path>      Alternate path to the cache.mmap file.\n");
+    fprintf(stderr, "                 Defaults to: %s\n", PATH_SASLAUTHD_RUNDIR "/cache.mmap");
+    fprintf(stderr, "  -s             Dumps general statistic information about the cache.\n");
+    fprintf(stderr, "\n");
+    fprintf(stderr, "  All data is delivered to stdout.\n");
+
+    exit(1);
+
+}
+
diff --git a/saslauthd/testsaslauthd.c b/saslauthd/testsaslauthd.c
new file mode 100644 (file)
index 0000000..f1e837a
--- /dev/null
@@ -0,0 +1,308 @@
+/* test-saslauthd.c: saslauthd test utility
+ * Rob Siemborski
+ */
+/* 
+ * 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.
+ */
+
+#include <saslauthd.h>
+#include <stdio.h>
+
+#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef USE_DOORS
+#include <door.h>
+#endif
+#include <assert.h>
+
+#include "globals.h"
+#include "utils.h"
+
+/* make utils.c happy */
+int flags = LOG_USE_STDERR;
+
+/*
+ * Keep calling the read() system call with 'fd', 'buf', and 'nbyte'
+ * until all the data is read in or an error occurs.
+ */
+int retry_read(int fd, void *inbuf, unsigned nbyte)
+{
+    int n;
+    int nread = 0;
+    char *buf = (char *)inbuf;
+
+    if (nbyte == 0) return 0;
+
+    for (;;) {
+       n = read(fd, buf, nbyte);
+       if (n == -1 || n == 0) {
+           if (errno == EINTR || errno == EAGAIN) continue;
+           return -1;
+       }
+
+       nread += n;
+
+       if (n >= (int) nbyte) return nread;
+
+       buf += n;
+       nbyte -= n;
+    }
+}
+
+/* saslauthd-authenticated login */
+static int saslauthd_verify_password(const char *saslauthd_path,
+                                  const char *userid, 
+                                  const char *passwd,
+                                  const char *service,
+                                  const char *user_realm)
+{
+    char response[1024];
+    char query[8192];
+    char *query_end = query;
+    int s;
+    struct sockaddr_un srvaddr;
+    int r;
+    unsigned short count;
+    void *context;
+    char pwpath[sizeof(srvaddr.sun_path)];
+    const char *p = NULL;
+#ifdef USE_DOORS
+    door_arg_t arg;
+#endif
+
+    if(!service) service = "imap";
+    if(!user_realm) user_realm = "";
+    if(!userid || !passwd) return -1;
+    
+    if (saslauthd_path) {
+       strncpy(pwpath, saslauthd_path, sizeof(pwpath));
+    } else {
+       if (strlen(PATH_SASLAUTHD_RUNDIR) + 4 + 1 > sizeof(pwpath))
+           return -1;
+
+       strcpy(pwpath, PATH_SASLAUTHD_RUNDIR);
+       strcat(pwpath, "/mux");
+    }
+
+    /*
+     * build request of the form:
+     *
+     * count authid count password count service count realm
+     */
+    {
+       unsigned short u_len, p_len, s_len, r_len;
+       struct iovec iov[8];
+       u_len = htons(strlen(userid));
+       p_len = htons(strlen(passwd));
+       s_len = htons(strlen(service));
+       r_len = htons((user_realm ? strlen(user_realm) : 0));
+
+       memcpy(query_end, &u_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*userid) *query_end++ = *userid++;
+
+       memcpy(query_end, &p_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*passwd) *query_end++ = *passwd++;
+
+       memcpy(query_end, &s_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       while (*service) *query_end++ = *service++;
+
+       memcpy(query_end, &r_len, sizeof(unsigned short));
+       query_end += sizeof(unsigned short);
+       if (user_realm) while (*user_realm) *query_end++ = *user_realm++;
+    }
+
+#ifdef USE_DOORS
+    s = open(pwpath, O_RDONLY);
+    if (s < 0) {
+       perror("open");
+       return -1;
+    }
+
+    arg.data_ptr = query;
+    arg.data_size = query_end - query;
+    arg.desc_ptr = NULL;
+    arg.desc_num = 0;
+    arg.rbuf = response;
+    arg.rsize = sizeof(response);
+
+    if(door_call(s, &arg) != 0) {
+       printf("NO \"door_call failed\"\n");
+       return -1;      
+    }
+
+    assert(arg.data_size < sizeof(response));
+    response[arg.data_size] = '\0';
+
+    close(s);
+#else
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s == -1) {
+       perror("socket() ");
+       return -1;
+    }
+
+    memset((char *)&srvaddr, 0, sizeof(srvaddr));
+    srvaddr.sun_family = AF_UNIX;
+    strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path));
+
+    r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr));
+    if (r == -1) {
+        perror("connect() ");
+       return -1;
+    }
+
+    {
+       struct iovec iov[8];
+       iov[0].iov_len = query_end - query;
+       iov[0].iov_base = query;
+
+       if (retry_writev(s, iov, 1) == -1) {
+            fprintf(stderr,"write failed\n");
+           return -1;
+       }
+    }
+  
+    /*
+     * read response of the form:
+     *
+     * count result
+     */
+    if (retry_read(s, &count, sizeof(count)) < (int) sizeof(count)) {
+        fprintf(stderr,"size read failed\n");
+       return -1;
+    }
+  
+    count = ntohs(count);
+    if (count < 2) { /* MUST have at least "OK" or "NO" */
+       close(s);
+        fprintf(stderr,"bad response from saslauthd\n");
+       return -1;
+    }
+  
+    count = (int)sizeof(response) < count ? sizeof(response) : count;
+    if (retry_read(s, response, count) < count) {
+       close(s);
+        fprintf(stderr,"read failed\n");
+       return -1;
+    }
+    response[count] = '\0';
+  
+    close(s);
+#endif /* USE_DOORS */
+  
+    if (!strncmp(response, "OK", 2)) {
+       printf("OK \"Success.\"\n");
+       return 0;
+    }
+  
+    printf("NO \"authentication failed\"\n");
+    return -1;
+}
+
+int
+main(int argc, char *argv[])
+{
+  const char *user = NULL, *password = NULL;
+  const char *realm = NULL, *service = NULL, *path = NULL;
+  int c;
+  int flag_error = 0;
+  unsigned passlen, verifylen;
+  const char *errstr = NULL;
+  int result;
+  char *user_domain = NULL;
+  int repeat = 0;
+
+  while ((c = getopt(argc, argv, "p:u:r:s:f:R:")) != EOF)
+      switch (c) {
+      case 'R':
+         repeat = atoi(optarg);
+         break;
+      case 'f':
+         path = optarg;
+         break;
+      case 's':
+         service = optarg;
+         break;
+      case 'r':
+         realm = optarg;
+         break;
+      case 'u':
+         user = optarg;
+         break;
+      case 'p':
+         password = optarg;
+         break;
+      default:
+         flag_error = 1;
+         break;
+    }
+
+  if (!user || !password)
+    flag_error = 1;
+
+  if (flag_error) {
+    (void)fprintf(stderr,
+                 "%s: usage: %s -u username -p password\n"
+                 "              [-r realm] [-s servicename]\n"
+                 "              [-f socket path] [-R repeatnum]\n",
+                 argv[0], argv[0]);
+    exit(1);
+  }
+
+  if (!repeat) repeat = 1;
+  for (c = 0; c < repeat; c++) {
+      /* saslauthd-authenticated login */
+      printf("%d: ", c);
+      result = saslauthd_verify_password(path, user, password, service, realm);
+  }
+  return result;
+}
+
+
diff --git a/saslauthd/utils.c b/saslauthd/utils.c
new file mode 100644 (file)
index 0000000..df7162f
--- /dev/null
@@ -0,0 +1,276 @@
+/******************************************************************************
+ *
+ * utils.c
+ *
+ * Description:  Central utility functions that may be frequently needed
+ *               accross the application.
+ *
+ * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2003 Jeremy Rumpf
+ * jrumpf@heavyload.net
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MESSAGING DIRECT LTD. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MESSAGING DIRECT LTD. OR
+ * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ *
+ * HISTORY
+ *
+ *
+ * This source file created using 8 space tabs.
+ *
+ *****************************************************************************/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "utils.h"
+#include "globals.h"
+
+
+/****************************************
+ * flags     global from saslauthd-main.c
+ *****************************************/
+
+/*************************************************************
+ * Variadic logging function to simplify printing of log
+ * messages
+ **************************************************************/
+void logger(int priority, const char *function, const char *format, ...) {
+        va_list        arg_list;
+        char           buffer[1024];
+       static int      have_syslog = 0;
+
+        va_start(arg_list, format);
+        vsnprintf(buffer, 1023, format, arg_list);
+       va_end(arg_list);
+
+        buffer[1023] = '\0';
+
+        if (flags & LOG_USE_STDERR)
+                fprintf(stderr, L_STDERR_FORMAT, getpid(), function, buffer);
+
+        if (flags & LOG_USE_SYSLOG) {
+               if (!have_syslog) {
+                       openlog("saslauthd", LOG_PID|LOG_NDELAY, LOG_AUTH);
+                       have_syslog = 1;
+               }
+
+                syslog(priority, "%-16s: %s", function, buffer);
+       }
+}
+
+
+/**************************************************************
+ * I/O wrapper to attempt to ensure a full record gets
+ * transmitted. If the function returns anything less than
+ * bytesrequested, it should be considered a failure.
+ **************************************************************/
+ssize_t tx_rec(int filefd, void *prebuff, size_t bytesrequested) {
+       int             rc;
+        ssize_t                bytesio = 0;
+        size_t         bytesleft = 0;
+        void           *buff;
+
+        bytesleft = bytesrequested;
+        buff = prebuff;
+
+        while (bytesleft > 0) {
+                bytesio = write(filefd, buff, bytesleft);
+               rc = errno;
+
+                if (bytesio < 0) {
+                       logger(L_ERR, L_FUNC, "write failure");
+                       logger(L_ERR, L_FUNC, "write: %s", strerror(rc));
+                        return(bytesio);
+               }
+
+                if (bytesio == 0 && errno != EINTR)
+                        return(bytesrequested - bytesleft);
+
+                bytesleft -= bytesio;
+                buff = (void *)((char *)buff + bytesio);
+
+        }
+
+        return(bytesrequested);
+}
+
+
+/**************************************************************
+ * I/O wrapper to attempt to read in the specified amount of
+ * data, without any guarantees. If the function returns 
+ * anything less than bytesrequested, it should be considered
+ * a failure.
+ **************************************************************/
+ssize_t rx_rec(int filefd, void *prebuff, size_t bytesrequested) {
+       int             rc;
+        ssize_t                bytesio = 0;
+        size_t         bytesleft = 0;
+        void           *buff;
+
+        bytesleft = bytesrequested;
+        buff = prebuff;
+
+        while (bytesleft > 0) {
+                bytesio = read(filefd, buff, bytesleft);
+               rc = errno;
+
+                if (bytesio < 0) {
+                       logger(L_ERR, L_FUNC, "read failure");
+                       logger(L_ERR, L_FUNC, "read: %s", strerror(rc));
+                        return(bytesio);
+               }
+
+                if (bytesio == 0 && errno != EINTR)
+                        return(bytesrequested - bytesleft);
+
+                bytesleft -= bytesio;
+                buff = (void *)((char *)buff + bytesio);
+
+        }
+
+        return(bytesrequested);
+}
+
+
+/**************************************************************
+ * I/O wrapper to attempt to write out the specified vector.
+ * data, without any guarantees. If the function returns 
+ * -1, the vector wasn't completely written.
+ **************************************************************/
+int retry_writev(int fd, struct iovec *iov, int iovcnt) {
+       int n;               /* return value from writev() */
+       int i;               /* loop counter */
+       int written;         /* bytes written so far */
+       static int iov_max;  /* max number of iovec entries */
+
+#ifdef MAXIOV
+       iov_max = MAXIOV;
+#else 
+# ifdef IOV_MAX
+       iov_max = IOV_MAX;
+# else 
+       iov_max = 8192;
+# endif 
+#endif
+
+       written = 0;
+
+       for (;;) {
+
+               while (iovcnt && iov[0].iov_len == 0) {
+                       iov++;
+                       iovcnt--;
+               }
+
+               if (!iovcnt) {
+                       return written;
+               }
+
+               n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt);
+
+               if (n == -1) {
+                       if (errno == EINVAL && iov_max > 10) {
+                               iov_max /= 2;
+                               continue;
+                       }
+
+                       if (errno == EINTR) {
+                               continue;
+                       }
+
+                       return -1;
+
+               } else {
+                       written += n;
+               }
+
+               for (i = 0; i < iovcnt; i++) {
+                       if ((int) iov[i].iov_len > n) {
+                               iov[i].iov_base = (char *)iov[i].iov_base + n;
+                               iov[i].iov_len -= n;
+                               break;
+                       }
+
+                       n -= iov[i].iov_len;
+                       iov[i].iov_len = 0;
+               }
+
+               if (i == iovcnt) {
+                       return written;
+               }
+       }
+}
+
+#ifndef HAVE_STRLCPY
+/* strlcpy -- copy string smartly.
+ *
+ * i believe/hope this is compatible with the BSD strlcpy(). 
+ */
+size_t saslauthd_strlcpy(char *dst, const char *src, size_t len)
+{
+       size_t n;
+
+       if (len <= 0) {
+               /* we can't do anything ! */
+               return strlen(src);
+       }
+
+       /* assert(len >= 1); */
+       for (n = 0; n < len-1; n++) {
+               if ((dst[n] = src[n]) == '\0') break;
+       }
+       if (n >= len-1) {
+               /* ran out of space */
+               dst[n] = '\0';
+               while(src[n]) n++;
+       }
+       return n;
+}
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t saslauthd_strlcat(char *dst, const char *src, size_t len)
+{
+       size_t i, j, o;
+
+       o = strlen(dst);
+       if (len < o + 1)
+               return o + strlen(src);
+       len -= o + 1;
+       for (i = 0, j = o; i < len; i++, j++) {
+               if ((dst[j] = src[i]) == '\0') break;
+       }
+       dst[j] = '\0';
+       if (src[i] == '\0') {
+               return j;
+       } else {
+               return j + strlen(src + i);
+       }
+}
+#endif
diff --git a/saslauthd/utils.h b/saslauthd/utils.h
new file mode 100644 (file)
index 0000000..a2556c4
--- /dev/null
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * *****************************************************************************
+ * *
+ * * utils.h
+ * *
+ * * Description:  Header file for utils.c
+ * *               
+ * *
+ * * Copyright (c) 1997-2000 Messaging Direct Ltd.
+ * * All rights reserved.
+ * *
+ * * Portions Copyright (c) 2003 Jeremy Rumpf
+ * * jrumpf@heavyload.net
+ * *
+ * * 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.
+ * *
+ * * THIS SOFTWARE IS PROVIDED ``AS IS''. ANY EXPRESS OR IMPLIED WARRANTIES,
+ * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * * IN NO EVENT SHALL JEREMY RUMPF OR ANY CONTRIBUTER TO THIS SOFTWARE BE
+ * * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
+ * * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * * THE POSSIBILITY OF SUCH DAMAGE
+ * *
+ * * HISTORY
+ * * 
+ * *
+ * * This source file created using 8 space tabs.
+ * *
+ * ******************************************************************************
+ ********************************************************************************/
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include "saslauthd.h"
+
+
+/* log prioities */
+#define L_ERR                  LOG_ERR
+#define L_INFO                 LOG_INFO
+#define L_DEBUG                        LOG_DEBUG
+
+
+/* some magic to grab function names */
+#ifdef HAVE_FUNC
+# define L_FUNC __func__
+# define HAVE_L_FUNC 1
+#elif defined(HAVE_PRETTY_FUNCTION)
+# define L_FUNC __PRETTY_FUNCTION__
+# define HAVE_L_FUNC 1
+#elif defined(HAVE_FUNCTION)
+# define L_FUNC __FUNCTION__
+# define HAVE_L_FUNC 1
+#else
+# define L_FUNC ""
+# undef HAVE_L_FUNC
+#endif
+
+#ifdef HAVE_L_FUNC
+# define L_STDERR_FORMAT        "saslauthd[%d] :%-16s: %s\n"
+#else
+# define L_STDERR_FORMAT        "saslauthd[%d] :%s%s\n"
+#endif 
+
+
+/* utils.c */
+extern void    logger(int, const char *, const char *, ...);
+extern ssize_t tx_rec(int filefd, void *, size_t);
+extern ssize_t rx_rec(int , void *, size_t);
+extern int     retry_writev(int, struct iovec *, int);
+
+
+#endif  /* _UTILS_H */
diff --git a/sasldb/Makefile.am b/sasldb/Makefile.am
new file mode 100644 (file)
index 0000000..870b939
--- /dev/null
@@ -0,0 +1,68 @@
+# Makefile.am for the SASLdb library
+# Rob Siemborski
+# $Id: Makefile.am,v 1.31.2.1 2009/04/27 17:58:26 murch Exp $
+# Copyright (c) 2000 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.
+#
+
+# Library version info - here at the top, for sanity
+# Note that this doesn't necessaraly follow the libsasl2 verison info
+sasl_version = 1:23:0
+
+INCLUDES=-I$(top_srcdir)/include -I$(top_builddir)/include @SASL_DB_INC@
+
+extra_common_sources = db_none.c db_ndbm.c db_gdbm.c db_berkeley.c
+
+EXTRA_DIST = NTMakefile
+
+noinst_LTLIBRARIES = libsasldb.la
+noinst_LIBRARIES = libsasldb.a
+
+libsasldb_la_SOURCES = allockey.c sasldb.h
+EXTRA_libsasldb_la_SOURCES = $(extra_common_sources)
+libsasldb_la_DEPENDENCIES = $(SASL_DB_BACKEND)
+libsasldb_la_LIBADD = $(SASL_DB_BACKEND) 
+
+# Prevent make dist stupidity
+libsasldb_a_SOURCES =
+EXTRA_libsasldb_a_SOURCES =
+
+libsasldb.a: libsasldb.la $(SASL_DB_BACKEND_STATIC)
+       $(AR) cru .libs/$@ $(SASL_DB_BACKEND_STATIC)
+
+
diff --git a/sasldb/Makefile.in b/sasldb/Makefile.in
new file mode 100644 (file)
index 0000000..f82c5aa
--- /dev/null
@@ -0,0 +1,550 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the SASLdb library
+# Rob Siemborski
+# $Id: Makefile.am,v 1.31.2.1 2009/04/27 17:58:26 murch Exp $
+# Copyright (c) 2000 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.
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+# Library version info - here at the top, for sanity
+# Note that this doesn't necessaraly follow the libsasl2 verison info
+sasl_version = 1:23:0
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include @SASL_DB_INC@
+
+extra_common_sources = db_none.c db_ndbm.c db_gdbm.c db_berkeley.c
+
+EXTRA_DIST = NTMakefile
+
+noinst_LTLIBRARIES = libsasldb.la
+noinst_LIBRARIES = libsasldb.a
+
+libsasldb_la_SOURCES = allockey.c sasldb.h
+EXTRA_libsasldb_la_SOURCES = $(extra_common_sources)
+libsasldb_la_DEPENDENCIES = $(SASL_DB_BACKEND)
+libsasldb_la_LIBADD = $(SASL_DB_BACKEND) 
+
+# Prevent make dist stupidity
+libsasldb_a_SOURCES = 
+EXTRA_libsasldb_a_SOURCES = 
+subdir = sasldb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+
+libsasldb_a_AR = $(AR) cru
+libsasldb_a_LIBADD =
+am_libsasldb_a_OBJECTS =
+libsasldb_a_OBJECTS = $(am_libsasldb_a_OBJECTS)
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+
+libsasldb_la_LDFLAGS =
+am_libsasldb_la_OBJECTS = allockey.lo
+libsasldb_la_OBJECTS = $(am_libsasldb_la_OBJECTS)
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/allockey.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/db_berkeley.Plo ./$(DEPDIR)/db_gdbm.Plo \
+@AMDEP_TRUE@   ./$(DEPDIR)/db_ndbm.Plo ./$(DEPDIR)/db_none.Plo
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libsasldb_a_SOURCES) $(EXTRA_libsasldb_a_SOURCES) \
+       $(libsasldb_la_SOURCES) $(EXTRA_libsasldb_la_SOURCES)
+DIST_COMMON = $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(libsasldb_a_SOURCES) $(EXTRA_libsasldb_a_SOURCES) $(libsasldb_la_SOURCES) $(EXTRA_libsasldb_la_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  sasldb/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+
+AR = ar
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+       @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libsasldb.la: $(libsasldb_la_OBJECTS) $(libsasldb_la_DEPENDENCIES) 
+       $(LINK)  $(libsasldb_la_LDFLAGS) $(libsasldb_la_OBJECTS) $(libsasldb_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/allockey.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_berkeley.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_gdbm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_ndbm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db_none.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES)
+
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+       clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \
+       ctags distclean distclean-compile distclean-generic \
+       distclean-libtool distclean-tags distdir dvi dvi-am info \
+       info-am install install-am install-data install-data-am \
+       install-exec install-exec-am install-info install-info-am \
+       install-man install-strip installcheck installcheck-am \
+       installdirs maintainer-clean maintainer-clean-generic \
+       mostlyclean mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+       uninstall-am uninstall-info-am
+
+
+libsasldb.a: libsasldb.la $(SASL_DB_BACKEND_STATIC)
+       $(AR) cru .libs/$@ $(SASL_DB_BACKEND_STATIC)
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sasldb/NTMakefile b/sasldb/NTMakefile
new file mode 100644 (file)
index 0000000..e3919e6
--- /dev/null
@@ -0,0 +1,65 @@
+# NTMakefile for SASL, sasldb directory\r
+# Alexey Melnikov\r
+#\r
+################################################################\r
+# Copyright (c) 2003 Carnegie Mellon University.  All rights reserved.\r
+#\r
+# Redistribution and use in source and binary forms, with or without\r
+# modification, are permitted provided that the following conditions\r
+# are met:\r
+#\r
+# 1. Redistributions of source code must retain the above copyright\r
+#    notice, this list of conditions and the following disclaimer. \r
+#\r
+# 2. Redistributions in binary form must reproduce the above copyright\r
+#    notice, this list of conditions and the following disclaimer in\r
+#    the documentation and/or other materials provided with the\r
+#    distribution.\r
+#\r
+# 3. The name "Carnegie Mellon University" must not be used to\r
+#    endorse or promote products derived from this software without\r
+#    prior written permission. For permission or any other legal\r
+#    details, please contact  \r
+#      Office of Technology Transfer\r
+#      Carnegie Mellon University\r
+#      5000 Forbes Avenue\r
+#      Pittsburgh, PA  15213-3890\r
+#      (412) 268-4387, fax: (412) 268-7395\r
+#      tech-transfer@andrew.cmu.edu\r
+#\r
+# 4. Redistributions of any form whatsoever must retain the following\r
+#    acknowledgment:\r
+#    "This product includes software developed by Computing Services\r
+#     at Carnegie Mellon University (http://www.cmu.edu/computing/)."\r
+#\r
+# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO\r
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r
+# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE\r
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN\r
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING\r
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+#\r
+################################################################\r
+\r
+#Suppress verbose output from defaulting values\r
+VERBOSE=0\r
+\r
+!INCLUDE ..\win32\common.mak\r
+\r
+includedir = $(prefix)\include\r
+\r
+saslincludedir = $(includedir)\sasl\\r
+\r
+saslinclude_HEADERS = sasldb.h\r
+\r
+# The first target get executed by default. We don't want this to be "install"\r
+all:\r
+       @echo Nothing to be done for $@\r
+\r
+#\r
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels\r
+#\r
+install: $(saslinclude_HEADERS)\r
+       !xcopy sasldb*.h $(saslincludedir) /I /F /Y\r
+       !xcopy $? $(saslincludedir) /I /F /Y\r
diff --git a/sasldb/allockey.c b/sasldb/allockey.c
new file mode 100644 (file)
index 0000000..4c1529c
--- /dev/null
@@ -0,0 +1,276 @@
+/* db_berkeley.c--SASL berkeley db interface
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: allockey.c,v 1.8 2006/04/10 13:26:51 mel 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include "sasldb.h"
+
+/*
+ * Construct a key
+ *
+ */
+int _sasldb_alloc_key(const sasl_utils_t *utils,
+                     const char *auth_identity,
+                     const char *realm,
+                     const char *propName,
+                     char **key,
+                     size_t *key_len)
+{
+  size_t auth_id_len, realm_len, prop_len;
+
+  if(!utils || !auth_identity || !realm || !propName || !key || !key_len)
+       return SASL_BADPARAM;
+
+  auth_id_len = strlen(auth_identity);
+  realm_len = strlen(realm);
+  prop_len = strlen(propName);
+
+  *key_len = auth_id_len + realm_len + prop_len + 2;
+  *key = utils->malloc(*key_len);
+  if (! *key)
+    return SASL_NOMEM;
+  memcpy(*key, auth_identity, auth_id_len);
+  (*key)[auth_id_len] = '\0';
+  memcpy(*key + auth_id_len + 1, realm, realm_len);
+  (*key)[auth_id_len + realm_len + 1] = '\0';
+  memcpy(*key + auth_id_len + realm_len + 2, propName, prop_len);
+
+  return SASL_OK;
+}
+
+/*
+ * decode a key
+ */
+int _sasldb_parse_key(const char *key, const size_t key_len,
+                     char *authid, const size_t max_authid,
+                     char *realm, const size_t max_realm,
+                     char *propName, const size_t max_propname) 
+{
+    unsigned i = 0;
+    unsigned numnulls = 0;
+    size_t alen = 0, rlen = 0, pnlen = 0;
+
+    if(!key || !key_len
+       || (authid && !max_authid)
+       || (realm && !max_realm)
+       || (propName && !max_propname))
+       return SASL_BADPARAM;
+
+    for(i=0; i<key_len; i++) {
+       if(key[i] == '\0') numnulls++;
+    }
+
+    if(numnulls != 2) return SASL_BADPARAM;
+
+    alen = strlen(key);
+    rlen = strlen(key + alen + 1);
+    pnlen = key_len - alen - rlen - 2;
+    
+
+    if(authid) {
+       if(alen >= max_authid)
+           return SASL_BUFOVER;
+       strncpy(authid, key, max_authid);
+    }
+
+    if(realm) {
+       if(rlen >= max_realm)
+           return SASL_BUFOVER;
+       strncpy(realm, key + alen + 1, max_realm);
+    }
+    
+    if(propName) {
+       if(pnlen >= max_propname)
+           return SASL_BUFOVER;
+       strncpy(propName, key + alen + rlen + 2, pnlen);
+
+       /* Have to add the missing NULL */
+       propName[pnlen] = '\0';
+    }
+
+    return SASL_OK;
+}
+
+/* These are more or less aliases to the correct functions */
+int _sasldb_getsecret(const sasl_utils_t *utils,
+                     sasl_conn_t *context,
+                     const char *authid,
+                     const char *realm,
+                     sasl_secret_t ** secret) 
+{
+    char buf[8192];
+    size_t len;
+    sasl_secret_t *out;
+    int ret;
+    const char *param = SASL_AUX_PASSWORD;
+    param++;
+    
+    if(!secret) {
+       utils->seterror(context, 0, "No secret pointer in _sasldb_getsecret");
+       return SASL_BADPARAM;
+    }
+
+    ret = _sasldb_getdata(utils, context, authid, realm, param,
+                         buf, 8192, &len);
+    
+    if(ret != SASL_OK) {
+       return ret;
+    }
+    
+    out = utils->malloc(sizeof(sasl_secret_t) + len);
+    if(!out) {
+       utils->seterror(context, 0, "Out of Memory in _sasldb_getsecret");
+       return SASL_NOMEM;
+    }
+
+    out->len = (unsigned) len;
+    memcpy(out->data, buf, len);
+    out->data[len]='\0';
+
+    *secret = out;
+
+    return SASL_OK;
+}
+
+int _sasldb_putsecret(const sasl_utils_t *utils,
+                     sasl_conn_t *context,
+                     const char *authid,
+                     const char *realm,
+                     const sasl_secret_t * secret) 
+{
+    const char *param = SASL_AUX_PASSWORD;
+    param++; /* skip leading * */
+    return _sasldb_putdata(utils, context, authid, realm, param,
+                          (secret ? secret->data : NULL),
+                          (secret ? secret->len : 0));
+}
+
+int __sasldb_internal_list (const char *authid,
+                           const char *realm,
+                           const char *property,
+                           void *rock __attribute__((unused)))
+{
+    printf("%s@%s: %s\n", authid, realm, property);
+
+    return (SASL_OK);
+}
+
+/* List all users in database */
+int _sasldb_listusers (const sasl_utils_t *utils,
+                      sasl_conn_t *context,
+                      sasldb_list_callback_t callback,
+                      void *callback_rock)
+{
+    int result;
+    char key_buf[32768];
+    size_t key_len;
+    sasldb_handle dbh;
+
+    if (callback == NULL) {
+       callback = &__sasldb_internal_list;
+       callback_rock = NULL;
+    }
+
+    dbh = _sasldb_getkeyhandle(utils, context);
+
+    if(!dbh) {
+       utils->log (context, SASL_LOG_ERR, "_sasldb_getkeyhandle has failed");
+       return SASL_FAIL;
+    }
+
+    result = _sasldb_getnextkey(utils,
+                               dbh,
+                               key_buf,
+                               32768,
+                               &key_len);
+
+    while (result == SASL_CONTINUE)
+    {
+       char authid_buf[16384];
+       char realm_buf[16384];
+       char property_buf[16384];
+       int ret;
+
+       ret = _sasldb_parse_key(key_buf, key_len,
+                               authid_buf, 16384,
+                               realm_buf, 16384,
+                               property_buf, 16384);
+
+       if(ret == SASL_BUFOVER) {
+           utils->log (context, SASL_LOG_ERR, "Key is too large in _sasldb_parse_key");
+           continue;
+       } else if(ret != SASL_OK) {
+           utils->log (context, SASL_LOG_ERR, "Bad Key in _sasldb_parse_key");
+           continue;
+       }
+       
+       result = callback (authid_buf,
+                          realm_buf,
+                          property_buf,
+                          callback_rock);
+
+       if (result != SASL_OK && result != SASL_CONTINUE) {
+           break;
+       }
+
+       result = _sasldb_getnextkey(utils,
+                                   dbh,
+                                   key_buf,
+                                   32768,
+                                   &key_len);
+    }
+
+    if (result == SASL_BUFOVER) {
+       utils->log (context, SASL_LOG_ERR, "Key is too large in _sasldb_getnextkey");
+    } else if (result != SASL_OK) {
+       utils->log (context, SASL_LOG_ERR, "DB failure in _sasldb_getnextkey");
+    }
+
+    return _sasldb_releasekeyhandle(utils, dbh);
+}
diff --git a/sasldb/db_berkeley.c b/sasldb/db_berkeley.c
new file mode 100644 (file)
index 0000000..f655687
--- /dev/null
@@ -0,0 +1,528 @@
+/* db_berkeley.c--SASL berkeley db interface
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: db_berkeley.c,v 1.8 2006/04/03 10:58:19 mel 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.
+ */
+
+#include <config.h>
+
+#include <db.h>
+
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "sasldb.h"
+
+static int db_ok = 0;
+#if defined(KEEP_DB_OPEN)
+static DB * g_db = NULL;
+#endif
+
+/*
+ * Open the database
+ */
+static int berkeleydb_open(const sasl_utils_t *utils,
+                          sasl_conn_t *conn,
+                          int rdwr, DB **mbdb)
+{
+    const char *path = SASL_DB_PATH;
+    int ret;
+    int flags;
+    void *cntxt;
+    sasl_getopt_t *getopt;
+
+#if defined(KEEP_DB_OPEN)
+    if (g_db) {
+       *mbdb = g_db;
+       return SASL_OK;
+    }
+#endif
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                         &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    if (rdwr) flags = DB_CREATE;
+    else flags = DB_RDONLY;
+#if defined(KEEP_DB_OPEN)
+#if defined(DB_THREAD)
+    flags |= DB_THREAD;
+#endif
+#endif
+
+#if DB_VERSION_MAJOR < 3
+    ret = db_open(path, DB_HASH, flags, 0660, NULL, NULL, mbdb);
+#else /* DB_VERSION_MAJOR < 3 */
+    ret = db_create(mbdb, NULL, 0);
+    if (ret == 0 && *mbdb != NULL)
+    {
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
+       ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, flags, 0660);
+#else
+       ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, flags, 0660);
+#endif
+       if (ret != 0)
+       {
+           (void) (*mbdb)->close(*mbdb, 0);
+           *mbdb = NULL;
+       }
+    }
+#endif /* DB_VERSION_MAJOR < 3 */
+
+    if (ret != 0) {
+       utils->log(conn, SASL_LOG_ERR,
+                  "unable to open Berkeley db %s: %s",
+                  path, db_strerror(ret));
+       utils->seterror(conn, SASL_NOLOG, "Unable to open DB");
+       return SASL_FAIL;
+    }
+
+#if defined(KEEP_DB_OPEN)
+    /* Save the DB handle for later use */
+    g_db = *mbdb;
+#endif
+    return SASL_OK;
+}
+
+/*
+ * Close the database
+ */
+static void berkeleydb_close(const sasl_utils_t *utils, DB *mbdb)
+{
+    int ret;
+
+#if defined(KEEP_DB_OPEN)
+    /* Prevent other threads from reusing the same handle */
+    /* msdb == g_db */    
+    g_db = NULL;
+#endif
+
+    ret = mbdb->close(mbdb, 0);
+    if (ret!=0) {
+       /* error closing! */
+       utils->log(NULL, SASL_LOG_ERR,
+                  "error closing sasldb: %s",
+                  db_strerror(ret));
+    }
+}
+
+
+/*
+ * Retrieve the secret from the database. 
+ * 
+ * Return SASL_NOUSER if the entry doesn't exist,
+ * SASL_OK on success.
+ *
+ */
+int _sasldb_getdata(const sasl_utils_t *utils,
+                   sasl_conn_t *context,
+                   const char *auth_identity,
+                   const char *realm,
+                   const char *propName,
+                   char *out, const size_t max_out, size_t *out_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  DBT dbkey, data;
+  DB *mbdb = NULL;
+
+  if(!utils) return SASL_BADPARAM;
+
+  /* check parameters */
+  if (!auth_identity || !realm || !propName || !out || !max_out) {
+      utils->seterror(context, 0,
+                     "Bad parameter in db_berkeley.c: _sasldb_getdata");
+      return SASL_BADPARAM;
+  }
+
+  if (!db_ok) {
+      utils->seterror(context, 0,
+                     "Database not checked");
+      return SASL_FAIL;
+  }
+
+  /* allocate a key */
+  result = _sasldb_alloc_key(utils, auth_identity, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+      utils->seterror(context, 0,
+                     "Could not allocate key in _sasldb_getdata");
+      return result;
+  }
+
+  /* zero out */
+  memset(&dbkey, 0, sizeof(dbkey));
+  memset(&data, 0, sizeof(data));
+
+  /* open the db */
+  result = berkeleydb_open(utils, context, 0, &mbdb);
+  if (result != SASL_OK) goto cleanup;
+
+  /* create the key to search for */
+  dbkey.data = key;
+  dbkey.size = (u_int32_t) key_len;
+  dbkey.flags = DB_DBT_USERMEM;
+  data.flags = DB_DBT_MALLOC;
+
+  /* ask berkeley db for the entry */
+  result = mbdb->get(mbdb, NULL, &dbkey, &data, 0);
+
+  switch (result) {
+  case 0:
+    /* success */
+    break;
+
+  case DB_NOTFOUND:
+    result = SASL_NOUSER;
+    utils->seterror(context, SASL_NOLOG,
+                   "user: %s@%s property: %s not found in sasldb",
+                   auth_identity,realm,propName);
+    goto cleanup;
+    break;
+  default:
+    utils->seterror(context, 0,
+                   "error fetching from sasldb: %s",
+                   db_strerror(result));
+    result = SASL_FAIL;
+    goto cleanup;
+    break;
+  }
+
+  if(data.size > max_out + 1)
+      return SASL_BUFOVER;
+
+  if(out_len) *out_len = data.size;
+  memcpy(out, data.data, data.size);
+  out[data.size] = '\0';
+  
+ cleanup:
+
+#if !defined(KEEP_DB_OPEN)
+  if (mbdb != NULL) berkeleydb_close(utils, mbdb);
+#endif
+
+  utils->free(key);
+  utils->free(data.data);
+
+  return result;
+}
+
+/*
+ * Put or delete an entry
+ * 
+ *
+ */
+
+int _sasldb_putdata(const sasl_utils_t *utils,
+                   sasl_conn_t *context,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   const char *data_in, size_t data_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  DBT dbkey;
+  DB *mbdb = NULL;
+
+  if (!utils) return SASL_BADPARAM;
+
+  if (!authid || !realm || !propName) {
+      utils->seterror(context, 0,
+                     "Bad parameter in db_berkeley.c: _sasldb_putdata");
+      return SASL_BADPARAM;
+  }
+  
+  if (!db_ok) {
+      utils->seterror(context, 0,
+                     "Database not checked");   
+      return SASL_FAIL;
+  }
+
+  result = _sasldb_alloc_key(utils, authid, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+       utils->seterror(context, 0,
+                     "Could not allocate key in _sasldb_putdata");     
+       return result;
+  }
+
+  /* open the db */
+  result=berkeleydb_open(utils, context, 1, &mbdb);
+  if (result!=SASL_OK) goto cleanup;
+
+  /* create the db key */
+  memset(&dbkey, 0, sizeof(dbkey));
+  dbkey.data = key;
+  dbkey.size = (u_int32_t) key_len;
+
+  if (data_in) {   /* putting secret */
+    DBT data;
+
+    memset(&data, 0, sizeof(data));    
+
+    data.data = (char *)data_in;
+    if(!data_len) data_len = strlen(data_in);
+    data.size = (u_int32_t) data_len;
+
+    result = mbdb->put(mbdb, NULL, &dbkey, &data, 0);
+
+    if (result != 0)
+    {
+      utils->log(NULL, SASL_LOG_ERR,
+                "error updating sasldb: %s", db_strerror(result));
+      utils->seterror(context, SASL_NOLOG,
+                     "Couldn't update db");
+      result = SASL_FAIL;
+      goto cleanup;
+    }
+  } else {        /* removing secret */
+    result=mbdb->del(mbdb, NULL, &dbkey, 0);
+
+    if (result != 0)
+    {
+      utils->log(NULL, SASL_LOG_ERR,
+                "error deleting entry from sasldb: %s", db_strerror(result));
+      utils->seterror(context, SASL_NOLOG,
+                     "Couldn't update db");
+      if (result == DB_NOTFOUND)
+         result = SASL_NOUSER;
+      else       
+         result = SASL_FAIL;
+      goto cleanup;
+    }
+  }
+
+ cleanup:
+
+#if !defined(KEEP_DB_OPEN)
+  if (mbdb != NULL) berkeleydb_close(utils, mbdb);
+#endif
+
+  utils->free(key);
+
+  return result;
+}
+
+int _sasl_check_db(const sasl_utils_t *utils,
+                  sasl_conn_t *conn)
+{
+    const char *path = SASL_DB_PATH;
+    int ret;
+    void *cntxt;
+    sasl_getopt_t *getopt;
+    sasl_verifyfile_t *vf;
+
+    if (!utils) return SASL_BADPARAM;
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                         &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    ret = utils->getcallback(conn, SASL_CB_VERIFYFILE,
+                            &vf, &cntxt);
+    if (ret != SASL_OK) {
+       utils->seterror(conn, 0, "verifyfile failed");
+       return ret;
+    }
+
+    ret = vf(cntxt, path, SASL_VRFY_PASSWD);
+
+    if (ret == SASL_OK) {
+       db_ok = 1;
+    }
+
+    if (ret == SASL_OK || ret == SASL_CONTINUE) {
+        return SASL_OK;
+    } else {
+       return ret;
+    }
+}
+
+#if defined(KEEP_DB_OPEN)
+void sasldb_auxprop_free (void *glob_context,
+                          const sasl_utils_t *utils)
+{
+    if (g_db != NULL) berkeleydb_close(utils, g_db);
+}
+#endif
+
+typedef struct berkeleydb_handle 
+{
+    DB *mbdb;
+    DBC *cursor;
+} berkleyhandle_t;
+
+sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
+                                  sasl_conn_t *conn) 
+{
+    int ret;
+    DB *mbdb;
+    berkleyhandle_t *handle;
+    
+    if(!utils || !conn) return NULL;
+
+    if(!db_ok) {
+       utils->seterror(conn, 0, "Database not OK in _sasldb_getkeyhandle");
+       return NULL;
+    }
+
+    ret = berkeleydb_open(utils, conn, 0, &mbdb);
+
+    if (ret != SASL_OK) {
+       return NULL;
+    }
+
+    handle = utils->malloc(sizeof(berkleyhandle_t));
+    if(!handle) {
+#if !defined(KEEP_DB_OPEN)
+       (void)mbdb->close(mbdb, 0);
+#endif
+       utils->seterror(conn, 0, "Memory error in _sasldb_gethandle");
+       return NULL;
+    }
+    
+    handle->mbdb = mbdb;
+    handle->cursor = NULL;
+
+    return (sasldb_handle)handle;
+}
+
+int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
+                      sasldb_handle handle, char *out,
+                      const size_t max_out, size_t *out_len) 
+{
+    DB *mbdb;
+    int result;
+    berkleyhandle_t *dbh = (berkleyhandle_t *)handle;
+    DBT key, data;
+
+    if(!utils || !handle || !out || !max_out)
+       return SASL_BADPARAM;
+
+    mbdb = dbh->mbdb;
+
+    memset(&key,0, sizeof(key));
+    memset(&data,0,sizeof(data));
+
+    if(!dbh->cursor) {
+        /* make cursor */
+#if DB_VERSION_MAJOR < 3
+#if DB_VERSION_MINOR < 6
+       result = mbdb->cursor(mbdb, NULL,&dbh->cursor); 
+#else
+       result = mbdb->cursor(mbdb, NULL,&dbh->cursor, 0); 
+#endif /* DB_VERSION_MINOR < 7 */
+#else /* DB_VERSION_MAJOR < 3 */
+       result = mbdb->cursor(mbdb, NULL,&dbh->cursor, 0); 
+#endif /* DB_VERSION_MAJOR < 3 */
+
+       if (result!=0) {
+           return SASL_FAIL;
+       }
+
+       /* loop thru */
+       result = dbh->cursor->c_get(dbh->cursor, &key, &data,
+                                   DB_FIRST);
+    } else {
+       result = dbh->cursor->c_get(dbh->cursor, &key, &data,
+                                   DB_NEXT);
+    }
+
+    if (result == DB_NOTFOUND) return SASL_OK;
+
+    if (result != 0) {
+       return SASL_FAIL;
+    }
+    
+    if (key.size > max_out) {
+       return SASL_BUFOVER;
+    }
+    
+    memcpy(out, key.data, key.size);
+    if (out_len) *out_len = key.size;
+
+    return SASL_CONTINUE;
+}
+
+
+int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
+                            sasldb_handle handle) 
+{
+    berkleyhandle_t *dbh = (berkleyhandle_t *)handle;
+    int ret = 0;
+    
+    if (!utils || !dbh) return SASL_BADPARAM;
+
+    if (dbh->cursor) {
+       dbh->cursor->c_close(dbh->cursor);
+    }
+
+#if !defined(KEEP_DB_OPEN)
+    /* This is almost the same berkeleydb_close(), except that
+       berkeleydb_close logs a message on error and does not return
+       any error */
+    if (dbh->mbdb) {
+         ret = dbh->mbdb->close(dbh->mbdb, 0);
+    }
+#endif
+    
+    utils->free(dbh);
+    
+    if (ret) {
+       return SASL_FAIL;
+    } else {
+       return SASL_OK;
+    }
+}
diff --git a/sasldb/db_gdbm.c b/sasldb/db_gdbm.c
new file mode 100644 (file)
index 0000000..8f4a790
--- /dev/null
@@ -0,0 +1,362 @@
+/* db_gdbm.c--SASL gdbm interface
+ * Rob Siemborski
+ * Rob Earhart
+ * $Id: db_gdbm.c,v 1.4 2003/02/13 19:56:14 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.
+ */
+
+#include <config.h>
+#include <gdbm.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "sasldb.h"
+
+static int db_ok = 0;
+
+int _sasldb_getdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   char *out, const size_t max_out, size_t *out_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  GDBM_FILE db;
+  datum gkey, gvalue;  
+  void *cntxt;
+  sasl_getopt_t *getopt;
+  const char *path = SASL_DB_PATH;
+
+  if (!utils) return SASL_BADPARAM;
+  if (!authid || !propName || !realm || !out || !max_out) {
+      utils->seterror(conn, 0,
+                     "Bad parameter in db_gdbm.c: _sasldb_getdata");
+      return SASL_BADPARAM;
+  }
+
+  if (!db_ok) {
+      utils->seterror(conn, 0,
+                     "Database not checked");
+      return SASL_FAIL;
+  }
+
+  result = _sasldb_alloc_key(utils, authid, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+      utils->seterror(conn, 0,
+                     "Could not allocate key in _sasldb_getdata");
+      return result;
+  }
+
+  if (utils->getcallback(conn, SASL_CB_GETOPT,
+                        &getopt, &cntxt) == SASL_OK) {
+      const char *p;
+      if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+         && p != NULL && *p != 0) {
+          path = p;
+      }
+  }
+  db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
+  if (! db) {
+      utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d",
+                     path, gdbm_errno);
+      result = SASL_FAIL;
+      goto cleanup;
+  }
+  gkey.dptr = key;
+  gkey.dsize = key_len;
+  gvalue = gdbm_fetch(db, gkey);
+  gdbm_close(db);
+  if (! gvalue.dptr) {
+      if (gdbm_errno == GDBM_ITEM_NOT_FOUND) {
+          utils->seterror(conn, SASL_NOLOG,
+                         "user: %s@%s property: %s not found in %s",
+                         authid, realm, propName, path);
+         result = SASL_NOUSER;
+      } else {
+         utils->seterror(conn, 0,
+                         "Couldn't fetch entry from %s: gdbm_errno=%d",
+                         path, gdbm_errno);
+         result = SASL_FAIL;
+      }
+      goto cleanup;
+  }
+
+  if((size_t)gvalue.dsize > max_out + 1) {
+      utils->seterror(cntxt, 0, "buffer overflow");
+      return SASL_BUFOVER;
+  }
+  
+  if(out_len) *out_len = gvalue.dsize;
+  memcpy(out, gvalue.dptr, gvalue.dsize);
+  out[gvalue.dsize] = '\0';
+
+  /* Note: not sasl_FREE!  This is memory allocated by gdbm,
+   * which is using libc malloc/free. */
+  free(gvalue.dptr);
+
+ cleanup:
+  utils->free(key);
+
+  return result;
+}
+
+int _sasldb_putdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   const char *data, size_t data_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  GDBM_FILE db;
+  datum gkey;
+  void *cntxt;
+  sasl_getopt_t *getopt;
+  const char *path = SASL_DB_PATH;
+
+  if (!utils) return SASL_BADPARAM;
+
+  if (!authid || !realm || !propName) {
+      utils->seterror(conn, 0,
+                     "Bad parameter in db_gdbm.c: _sasldb_putdata");
+      return SASL_BADPARAM;
+  }
+
+  result = _sasldb_alloc_key(utils, authid, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+      utils->seterror(conn, 0,
+                     "Could not allocate key in _sasldb_putdata"); 
+      return result;
+  }
+
+  if (utils->getcallback(conn, SASL_CB_GETOPT,
+                        &getopt, &cntxt) == SASL_OK) {
+      const char *p;
+      if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+         && p != NULL && *p != 0) {
+          path = p;
+      }
+  }
+  db = gdbm_open((char *)path, 0, GDBM_WRCREAT, S_IRUSR | S_IWUSR, NULL);
+  if (! db) {
+      utils->log(conn, SASL_LOG_ERR,
+                "SASL error opening password file. "
+                "Do you have write permissions?\n");
+      utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d",
+                     path, gdbm_errno);
+      result = SASL_FAIL;
+      goto cleanup;
+  }
+  gkey.dptr = key;
+  gkey.dsize = key_len;
+  if (data) {
+    datum gvalue;
+    gvalue.dptr = (char *)data;
+    if(!data_len) data_len = strlen(data);
+    gvalue.dsize = data_len;
+    if (gdbm_store(db, gkey, gvalue, GDBM_REPLACE)) {
+       utils->seterror(conn, 0,
+                       "Couldn't replace entry in %s: gdbm_errno=%d",
+                       path, gdbm_errno);
+       result = SASL_FAIL;
+    }
+  } else {
+      if (gdbm_delete(db, gkey)) {
+         utils->seterror(conn, 0,
+                         "Couldn't delete entry in %s: gdbm_errno=%d",
+                         path, gdbm_errno);
+         result = SASL_NOUSER;
+      }
+  }
+  gdbm_close(db);
+
+ cleanup:
+  utils->free(key);
+
+  return result;
+}
+
+int _sasl_check_db(const sasl_utils_t *utils,
+                  sasl_conn_t *conn)
+{
+    const char *path = SASL_DB_PATH;
+    int ret;
+    void *cntxt;
+    sasl_getopt_t *getopt;
+    sasl_verifyfile_t *vf;
+
+    if(!utils) return SASL_BADPARAM;
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                          &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE,
+                            &vf, &cntxt);
+    if(ret != SASL_OK) {
+       utils->seterror(conn, 0,
+                       "No verifyfile callback");
+       return ret;
+    }
+
+    ret = vf(cntxt, path, SASL_VRFY_PASSWD);
+    if (ret == SASL_OK) {
+       db_ok = 1;
+    }
+
+    if (ret == SASL_OK || ret == SASL_CONTINUE) {
+       return SASL_OK;
+    } else {
+       utils->seterror(conn, 0,
+                       "Verifyfile failed");
+       return ret;
+    }
+}
+
+typedef struct gdbm_handle 
+{
+    GDBM_FILE db;
+    datum dkey;
+    int first;
+} handle_t;
+
+sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
+                                  sasl_conn_t *conn) 
+{
+    const char *path = SASL_DB_PATH;
+    sasl_getopt_t *getopt;
+    void *cntxt;
+    GDBM_FILE db;
+    handle_t *handle;
+    
+    if(!utils || !conn) return NULL;
+
+    if(!db_ok) {
+       utils->seterror(conn, 0, "Database not OK in _sasldb_getkeyhandle");
+       return NULL;
+    }
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                          &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
+
+    if(!db) {
+        utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d",
+                        path, gdbm_errno);
+       return NULL;
+    }
+
+    handle = utils->malloc(sizeof(handle_t));
+    if(!handle) {
+       utils->seterror(conn, 0, "no memory in _sasldb_getkeyhandle");
+       gdbm_close(db);
+       return NULL;
+    }
+    
+    handle->db = db;
+    handle->first = 1;
+
+    return (sasldb_handle)handle;
+}
+
+int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
+                      sasldb_handle handle, char *out,
+                      const size_t max_out, size_t *out_len) 
+{
+    handle_t *dbh = (handle_t *)handle;
+    datum nextkey;
+
+    if(!utils || !handle || !out || !max_out)
+       return SASL_BADPARAM;
+
+    if(dbh->first) {
+       dbh->dkey = gdbm_firstkey(dbh->db);
+       dbh->first = 0;
+    } else {
+       nextkey = gdbm_nextkey(dbh->db, dbh->dkey);
+       dbh->dkey = nextkey;
+    }
+
+    if(dbh->dkey.dptr == NULL)
+       return SASL_OK;
+    
+    if((unsigned)dbh->dkey.dsize > max_out)
+       return SASL_BUFOVER;
+    
+    memcpy(out, dbh->dkey.dptr, dbh->dkey.dsize);
+    if(out_len) *out_len = dbh->dkey.dsize;
+    
+    return SASL_CONTINUE;
+}
+
+int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
+                            sasldb_handle handle) 
+{
+    handle_t *dbh = (handle_t *)handle;
+    
+    if(!utils || !dbh) return SASL_BADPARAM;
+
+    if(dbh->db) gdbm_close(dbh->db);
+
+    utils->free(dbh);
+    
+    return SASL_OK;
+}
+
diff --git a/sasldb/db_ndbm.c b/sasldb/db_ndbm.c
new file mode 100644 (file)
index 0000000..035ea1e
--- /dev/null
@@ -0,0 +1,384 @@
+/* db_ndbm.c--SASL ndbm interface
+ * Rob Siemborski
+ * Rob Earhart
+ * $Id: db_ndbm.c,v 1.5 2003/02/13 19:56:14 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <ndbm.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "sasldb.h"
+
+static int db_ok = 0;
+
+/* This provides a version of _sasl_db_getsecret and
+ * _sasl_db_putsecret which work with ndbm. */
+int _sasldb_getdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   char *out, const size_t max_out, size_t *out_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  DBM *db;
+  datum dkey, dvalue;
+  void *cntxt;
+  sasl_getopt_t *getopt;
+  const char *path = SASL_DB_PATH;
+
+  if (!utils) return SASL_BADPARAM;
+  if (!authid || !propName || !realm || !out || !max_out) {
+      utils->seterror(conn, 0,
+                     "Bad parameter in db_ndbm.c: _sasldb_getdata");    
+      return SASL_BADPARAM;
+  }
+  if (!db_ok) {
+      utils->seterror(conn, 0, "Database not checked");
+      return SASL_FAIL;
+  }
+
+  result = _sasldb_alloc_key(utils, authid, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+      utils->seterror(conn, 0,
+                     "Could not allocate key in _sasldb_getdata");
+      return result;
+  }
+
+  if (utils->getcallback(conn, SASL_CB_GETOPT,
+                        &getopt, &cntxt) == SASL_OK) {
+      const char *p;
+      if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+         && p != NULL && *p != 0) {
+          path = p;
+      }
+  }
+  db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR);
+  if (! db) {
+      utils->seterror(cntxt, 0, "Could not open db");
+      result = SASL_FAIL;
+      goto cleanup;
+  }
+  dkey.dptr = key;
+  dkey.dsize = key_len;
+  dvalue = dbm_fetch(db, dkey);
+  if (! dvalue.dptr) {
+      utils->seterror(cntxt, 0, "no user in db");
+      result = SASL_NOUSER;
+      goto cleanup;
+  }
+
+  if((size_t)dvalue.dsize > max_out + 1) {
+      utils->seterror(cntxt, 0, "buffer overflow");
+      return SASL_BUFOVER;
+  }
+
+  if(out_len) *out_len = dvalue.dsize;
+  memcpy(out, dvalue.dptr, dvalue.dsize); 
+  out[dvalue.dsize] = '\0';
+
+#if NDBM_FREE
+  /* Note: not sasl_FREE!  This is memory allocated by ndbm,
+   * which is using libc malloc/free. */
+  free(dvalue.dptr);
+#endif
+
+ cleanup:
+  utils->free(key);
+  if(db)
+    dbm_close(db);
+
+  return result;
+}
+
+int _sasldb_putdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   const char *data, size_t data_len)
+{
+  int result = SASL_OK;
+  char *key;
+  size_t key_len;
+  DBM *db;
+  datum dkey;
+  void *cntxt;
+  sasl_getopt_t *getopt;
+  const char *path = SASL_DB_PATH;
+
+  if (!utils) return SASL_BADPARAM;
+
+  if (!authid || !realm || !propName) {
+      utils->seterror(conn, 0,
+                     "Bad parameter in db_ndbm.c: _sasldb_putdata");
+      return SASL_BADPARAM;
+  }
+
+  result = _sasldb_alloc_key(utils, authid, realm, propName,
+                            &key, &key_len);
+  if (result != SASL_OK) {
+      utils->seterror(conn, 0,
+                     "Could not allocate key in _sasldb_putdata"); 
+      return result;
+  }
+
+  if (utils->getcallback(conn, SASL_CB_GETOPT,
+                        &getopt, &cntxt) == SASL_OK) {
+      const char *p;
+      if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+         && p != NULL && *p != 0) {
+          path = p;
+      }
+  }
+
+  db = dbm_open(path,
+               O_RDWR | O_CREAT,
+               S_IRUSR | S_IWUSR);
+  if (! db) {
+      utils->log(conn, SASL_LOG_ERR,
+                "SASL error opening password file. "
+                "Do you have write permissions?\n");
+      utils->seterror(conn, 0, "Could not open db for write");
+      goto cleanup;
+  }
+  dkey.dptr = key;
+  dkey.dsize = key_len;
+  if (data) {
+    datum dvalue;
+    dvalue.dptr = (void *)data;
+    if(!data_len) data_len = strlen(data);
+    dvalue.dsize = data_len;
+    if (dbm_store(db, dkey, dvalue, DBM_REPLACE)) {
+       utils->seterror(conn, 0,
+                       "Couldn't update db");
+       result = SASL_FAIL;
+    }
+  } else {
+      if (dbm_delete(db, dkey)) {
+         utils->seterror(conn, 0,
+                         "Couldn't update db");
+         result = SASL_NOUSER;
+      }
+  }
+  dbm_close(db);
+
+ cleanup:
+  utils->free(key);
+
+  return result;
+}
+
+#ifdef DBM_SUFFIX
+#define SUFLEN (strlen(DBM_SUFFIX) + 1)
+#else
+#define SUFLEN 5
+#endif
+
+int _sasl_check_db(const sasl_utils_t *utils,
+                  sasl_conn_t *conn)
+{
+    const char *path = SASL_DB_PATH;
+    void *cntxt;
+    sasl_getopt_t *getopt;
+    sasl_verifyfile_t *vf;
+    int ret = SASL_OK;
+    char *db;
+
+    if(!utils) return SASL_BADPARAM;
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                          &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    db = utils->malloc(strlen(path) + SUFLEN);
+
+    if (db == NULL) {
+       ret = SASL_NOMEM;
+    }
+
+    ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE,
+                            &vf, &cntxt);
+    if(ret != SASL_OK) {
+       utils->seterror(conn, 0,
+                       "No verifyfile callback");
+       return ret;
+    }
+
+#ifdef DBM_SUFFIX
+    if (ret == SASL_OK) {
+       sprintf(db, "%s%s", path, DBM_SUFFIX);
+       ret = vf(cntxt, db, SASL_VRFY_PASSWD);
+    }
+#else
+    if (ret == SASL_OK) {
+       sprintf(db, "%s.dir", path);
+       ret = vf(cntxt, db, SASL_VRFY_PASSWD);
+    }
+    if (ret == SASL_OK) {
+       sprintf(db, "%s.pag", path);
+       ret = vf(cntxt, db, SASL_VRFY_PASSWD);
+    }
+#endif
+    if (db) {
+       utils->free(db);
+    }
+    if (ret == SASL_OK) {
+       db_ok = 1;
+    }
+
+    if (ret == SASL_OK || ret == SASL_CONTINUE) {
+       return SASL_OK;
+    } else {
+       utils->seterror(conn, 0,
+                       "Verifyfile failed");
+       return ret;
+    }
+}
+
+typedef struct ndbm_handle 
+{
+    DBM *db;
+    datum dkey;
+    int first;
+} handle_t;
+
+sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
+                                  sasl_conn_t *conn) 
+{
+    const char *path = SASL_DB_PATH;
+    sasl_getopt_t *getopt;
+    void *cntxt;
+    DBM *db;
+    handle_t *handle;
+    
+    if(!utils || !conn) return NULL;
+
+    if(!db_ok) {
+       utils->seterror(conn, 0, "Database not OK in _sasldb_getkeyhandle");
+       return NULL;
+    }
+
+    if (utils->getcallback(conn, SASL_CB_GETOPT,
+                          &getopt, &cntxt) == SASL_OK) {
+       const char *p;
+       if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK 
+           && p != NULL && *p != 0) {
+           path = p;
+       }
+    }
+
+    db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR);
+
+    if(!db) {
+       utils->seterror(conn, 0, "Could not open db");
+       return NULL;
+    }
+
+    handle = utils->malloc(sizeof(handle_t));
+    if(!handle) {
+       utils->seterror(conn, 0, "no memory in _sasldb_getkeyhandle");
+       dbm_close(db);
+       return NULL;
+    }
+    
+    handle->db = db;
+    handle->first = 1;
+
+    return (sasldb_handle)handle;
+}
+
+int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
+                      sasldb_handle handle, char *out,
+                      const size_t max_out, size_t *out_len) 
+{
+    handle_t *dbh = (handle_t *)handle;
+    datum nextkey;
+
+    if(!utils || !handle || !out || !max_out)
+       return SASL_BADPARAM;
+
+    if(dbh->first) {
+       dbh->dkey = dbm_firstkey(dbh->db);
+       dbh->first = 0;
+    } else {
+       nextkey = dbm_nextkey(dbh->db);
+       dbh->dkey = nextkey;
+    }
+
+    if(dbh->dkey.dptr == NULL)
+       return SASL_OK;
+    
+    if((unsigned)dbh->dkey.dsize > max_out)
+       return SASL_BUFOVER;
+    
+    memcpy(out, dbh->dkey.dptr, dbh->dkey.dsize);
+    if(out_len) *out_len = dbh->dkey.dsize;
+    
+    return SASL_CONTINUE;
+}
+
+int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
+                            sasldb_handle handle) 
+{
+    handle_t *dbh = (handle_t *)handle;
+    
+    if(!utils || !dbh) return SASL_BADPARAM;
+
+    if(dbh->db) dbm_close(dbh->db);
+
+    utils->free(dbh);
+    
+    return SASL_OK;
+}
diff --git a/sasldb/db_none.c b/sasldb/db_none.c
new file mode 100644 (file)
index 0000000..45c4bbe
--- /dev/null
@@ -0,0 +1,103 @@
+/* db_none.c--provides linkage for systems which lack a backend db lib
+ * Rob Siemborski
+ * Rob Earhart
+ * $Id: db_none.c,v 1.3 2003/02/13 19:56:14 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.
+ */
+
+#include <config.h>
+#include "sasldb.h"
+
+/* This just exists to provide these symbols on systems where configure
+ * couldn't find a database library (or the user says we do not want one). */
+int _sasldb_getdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid __attribute__((unused)),
+                   const char *realm __attribute__((unused)),
+                   const char *propName __attribute__((unused)),
+                   char *out __attribute__((unused)),
+                   const size_t max_out __attribute__((unused)),
+                   size_t *out_len __attribute__((unused)))
+{
+    if(conn) utils->seterror(conn, 0, "No Database Driver");
+    return SASL_FAIL;
+}
+
+int _sasldb_putdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid __attribute__((unused)),
+                   const char *realm __attribute__((unused)),
+                   const char *propName __attribute__((unused)),
+                   const char *data __attribute__((unused)),
+                   size_t data_len __attribute__((unused)))
+{
+    if(conn) utils->seterror(conn, 0, "No Database Driver");
+    return SASL_FAIL;
+}
+
+int _sasl_check_db(const sasl_utils_t *utils,
+                  sasl_conn_t *conn)
+{
+    if(conn) utils->seterror(conn, 0, "No Database Driver");
+    return SASL_FAIL;
+}
+
+sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
+                                   sasl_conn_t *conn) 
+{
+    if(conn) utils->seterror(conn, 0, "No Database Driver");
+    return NULL;
+}
+
+int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
+                       sasldb_handle handle __attribute__((unused)),
+                      char *out __attribute__((unused)),
+                       const size_t max_out __attribute__((unused)),
+                      size_t *out_len __attribute__((unused))) 
+{
+    return SASL_FAIL;
+}
+
+int _sasldb_releasekeyhandle(const sasl_utils_t *utils __attribute__((unused)),
+                             sasldb_handle handle __attribute__((unused)))  
+{
+    return SASL_FAIL;
+}
diff --git a/sasldb/sasldb.h b/sasldb/sasldb.h
new file mode 100644 (file)
index 0000000..0cef3b4
--- /dev/null
@@ -0,0 +1,134 @@
+/* sasldb.h - SASLdb library header
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: sasldb.h,v 1.6 2006/04/03 10:58:20 mel 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 SASLDB_H
+#define SASLDB_H
+
+#include "sasl.h"
+#include "saslplug.h"
+
+/*
+ * Note that some of these require a sasl_conn_t in order for
+ * the getcallback stuff to work correctly.  This is great for
+ * when they are called from a plugin or the library but makes
+ * for much wierdness when an otherwise non-sasl application needs
+ * to make use of this functionality.
+ */
+
+int _sasldb_getdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   char *out, const size_t max_out, size_t *out_len);
+
+/* pass NULL for data to delete it */
+int _sasldb_putdata(const sasl_utils_t *utils,
+                   sasl_conn_t *conn,
+                   const char *authid,
+                   const char *realm,
+                   const char *propName,
+                   const char *data, size_t data_len);
+
+/* Should be run before any db access is attempted */
+LIBSASL_API int _sasl_check_db(const sasl_utils_t *utils,
+                  sasl_conn_t *conn);
+
+/* These allow iterating through the keys of the database */
+typedef void* sasldb_handle;
+
+typedef int (* sasldb_list_callback_t) (const char *authid,
+                                       const char *realm,
+                                       const char *property,
+                                       void *rock);
+
+LIBSASL_API sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
+                                  sasl_conn_t *conn);
+LIBSASL_API int _sasldb_getnextkey(const sasl_utils_t *utils,
+                      sasldb_handle handle, char *out,
+                      const size_t max_out, size_t *out_len);
+LIBSASL_API int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
+                            sasldb_handle handle);
+
+LIBSASL_API int _sasldb_listusers(const sasl_utils_t *utils,
+                                 sasl_conn_t *context,
+                                 sasldb_list_callback_t callback,
+                                 void *callback_rock);
+
+#if defined(KEEP_DB_OPEN)
+void sasldb_auxprop_free (void *glob_context, const sasl_utils_t *utils);
+#else
+#define sasldb_auxprop_free    NULL
+#endif
+
+/* The rest are implemented in allockey.c and individual drivers need not
+ * do so */
+/* These two are aliases for getdata/putdata */
+int _sasldb_getsecret(const sasl_utils_t *utils,
+                     sasl_conn_t *context,
+                     const char *auth_identity,
+                     const char *realm,
+                     sasl_secret_t ** secret);
+
+int _sasldb_putsecret(const sasl_utils_t *utils,
+                     sasl_conn_t *context,
+                     const char *auth_identity,
+                     const char *realm,
+                     const sasl_secret_t * secret);
+
+LIBSASL_API int _sasldb_parse_key(const char *key, const size_t key_len,
+                     char *authid, const size_t max_authid,
+                     char *realm, const size_t max_realm,
+                     char *propName, const size_t max_propname);
+
+/* This function is internal, but might be useful to have around */
+int _sasldb_alloc_key(const sasl_utils_t *utils,
+                     const char *auth_identity,
+                     const char *realm,
+                     const char *propName,
+                     char **key,
+                     size_t *key_len);
+
+#endif /* SASLDB_H */
diff --git a/utils/Makefile.am b/utils/Makefile.am
new file mode 100644 (file)
index 0000000..7e2f983
--- /dev/null
@@ -0,0 +1,99 @@
+# Makefile.am for the SASL utilities
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+all_sasl_libs = ../lib/libsasl2.la $(SASL_DB_LIB) $(LIB_SOCKET)
+all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE)
+
+sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer
+EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer
+
+noinst_PROGRAMS = dbconverter-2
+
+if NO_SASL_DB_MANS
+man_MANS = 
+else
+man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8
+endif
+
+saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+saslpasswd2_SOURCES = saslpasswd.c
+sasldblistusers2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+sasldblistusers2_SOURCES = sasldblistusers.c
+dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+pluginviewer_LDADD = $(all_sasl_libs)
+pluginviewer_SOURCES = pluginviewer.c
+
+testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@
+
+CLEANFILES=$(EXTRA_PROGRAMS)
+
+testsuitestatic_SOURCES = testsuite.c
+testsuitestatic_LDADD = $(all_sasl_static_libs) @DMALLOC_LIBS@ @SASL_DL_LIB@
+testsuitestatic_DEPENDENCIES = ../lib/.libs/libsasl2.a
+
+smtptest_SOURCES =
+smtptest_DEPENDENCIES = ./smtptest.lo ./libsfsasl2.la
+smtptest_LDADD = ./smtptest.lo ./libsfsasl2.la @SFIO_LIB_FLAGS@ @DMALLOC_LIBS@ $(all_sasl_libs)
+
+saslincludedir = $(includedir)/sasl
+
+saslinclude_HEADERS = @SASL_UTIL_HEADERS_EXTRA@
+EXTRA_HEADERS = sfsasl.h
+
+# Note: we explicitly do *not* link to libsfio, as people will need to
+# link to that anyway if they want to use this. 
+lib_LTLIBRARIES = @SASL_UTIL_LIBS_EXTRA@
+EXTRA_LTLIBRARIES = libsfsasl2.la
+libsfsasl2_la_SOURCES = 
+libsfsasl2_la_LIBADD = sfsasl.lo
+libsfsasl2_la_LDFLAGS = -version-info 1:0:0 -export-dynamic -rpath $(libdir)
+
+INCLUDES=-I$(top_srcdir)/include -I$(top_builddir)/include @SASL_DB_INC@
+EXTRA_DIST = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 sfsasl.h sfsasl.c smtptest.c testsuite.c pluginviewer.c NTMakefile
+
+sfsasl.lo: sfsasl.c
+       $(LIBTOOL) --mode=compile $(COMPILE) @SFIO_INC_FLAGS@ -c $(srcdir)/sfsasl.c
+
+smtptest.lo: smtptest.c
+       $(LIBTOOL) --mode=compile $(COMPILE) @SFIO_INC_FLAGS@ -c $(srcdir)/smtptest.c
diff --git a/utils/Makefile.in b/utils/Makefile.in
new file mode 100644 (file)
index 0000000..fcb5415
--- /dev/null
@@ -0,0 +1,760 @@
+# Makefile.in generated by automake 1.7.9 from Makefile.am.
+# @configure_input@
+
+# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+# Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for the SASL utilities
+# Rob Earhart
+#
+################################################################
+# Copyright (c) 2000 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.
+#
+################################################################
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_triplet = @host@
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CMU_LIB_SUBDIR = @CMU_LIB_SUBDIR@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DIRS = @DIRS@
+DMALLOC_LIBS = @DMALLOC_LIBS@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+GETADDRINFOOBJS = @GETADDRINFOOBJS@
+GETNAMEINFOOBJS = @GETNAMEINFOOBJS@
+GETSUBOPT = @GETSUBOPT@
+GSSAPIBASE_LIBS = @GSSAPIBASE_LIBS@
+GSSAPI_LIBS = @GSSAPI_LIBS@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+IPCTYPE = @IPCTYPE@
+JAVAC = @JAVAC@
+JAVADOC = @JAVADOC@
+JAVAH = @JAVAH@
+JAVAROOT = @JAVAROOT@
+JAVA_FALSE = @JAVA_FALSE@
+JAVA_INCLUDES = @JAVA_INCLUDES@
+JAVA_TRUE = @JAVA_TRUE@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIB_CRYPT = @LIB_CRYPT@
+LIB_DES = @LIB_DES@
+LIB_DOOR = @LIB_DOOR@
+LIB_LDAP = @LIB_LDAP@
+LIB_MYSQL = @LIB_MYSQL@
+LIB_PGSQL = @LIB_PGSQL@
+LIB_SOCKET = @LIB_SOCKET@
+LIB_SQLITE = @LIB_SQLITE@
+LN_S = @LN_S@
+LTGETADDRINFOOBJS = @LTGETADDRINFOOBJS@
+LTGETNAMEINFOOBJS = @LTGETNAMEINFOOBJS@
+LTLIBOBJS = @LTLIBOBJS@
+LTSNPRINTFOBJS = @LTSNPRINTFOBJS@
+MACOSX_FALSE = @MACOSX_FALSE@
+MACOSX_TRUE = @MACOSX_TRUE@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NO_SASL_DB_MANS_FALSE = @NO_SASL_DB_MANS_FALSE@
+NO_SASL_DB_MANS_TRUE = @NO_SASL_DB_MANS_TRUE@
+NTLM_LIBS = @NTLM_LIBS@
+OBJEXT = @OBJEXT@
+OTP_LIBS = @OTP_LIBS@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PASSDSS_LIBS = @PASSDSS_LIBS@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PLAIN_LIBS = @PLAIN_LIBS@
+PURECOV = @PURECOV@
+PURIFY = @PURIFY@
+PWCHECKMETH = @PWCHECKMETH@
+PWCHECK_FALSE = @PWCHECK_FALSE@
+PWCHECK_TRUE = @PWCHECK_TRUE@
+RANLIB = @RANLIB@
+SAMPLE_FALSE = @SAMPLE_FALSE@
+SAMPLE_TRUE = @SAMPLE_TRUE@
+SASLAUTHD_FALSE = @SASLAUTHD_FALSE@
+SASLAUTHD_TRUE = @SASLAUTHD_TRUE@
+SASL_DB_BACKEND = @SASL_DB_BACKEND@
+SASL_DB_BACKEND_STATIC = @SASL_DB_BACKEND_STATIC@
+SASL_DB_INC = @SASL_DB_INC@
+SASL_DB_LIB = @SASL_DB_LIB@
+SASL_DB_MANS = @SASL_DB_MANS@
+SASL_DB_UTILS = @SASL_DB_UTILS@
+SASL_DL_LIB = @SASL_DL_LIB@
+SASL_KRB_LIB = @SASL_KRB_LIB@
+SASL_MECHS = @SASL_MECHS@
+SASL_STATIC_LIBS = @SASL_STATIC_LIBS@
+SASL_STATIC_OBJS = @SASL_STATIC_OBJS@
+SASL_STATIC_SRCS = @SASL_STATIC_SRCS@
+SASL_UTIL_HEADERS_EXTRA = @SASL_UTIL_HEADERS_EXTRA@
+SASL_UTIL_LIBS_EXTRA = @SASL_UTIL_LIBS_EXTRA@
+SET_MAKE = @SET_MAKE@
+SFIO_INC_FLAGS = @SFIO_INC_FLAGS@
+SFIO_LIB_FLAGS = @SFIO_LIB_FLAGS@
+SHELL = @SHELL@
+SMTPTEST_PROGRAM = @SMTPTEST_PROGRAM@
+SNPRINTFOBJS = @SNPRINTFOBJS@
+SRP_LIBS = @SRP_LIBS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+configdir = @configdir@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+oldincludedir = @oldincludedir@
+plugindir = @plugindir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+
+all_sasl_libs = ../lib/libsasl2.la $(SASL_DB_LIB) $(LIB_SOCKET)
+all_sasl_static_libs = ../lib/.libs/libsasl2.a $(SASL_DB_LIB) $(LIB_SOCKET) $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(SASL_KRB_LIB) $(LIB_DES) $(PLAIN_LIBS) $(SRP_LIBS) $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE)
+
+sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer
+EXTRA_PROGRAMS = saslpasswd2 sasldblistusers2 testsuite testsuitestatic smtptest pluginviewer
+
+noinst_PROGRAMS = dbconverter-2
+@NO_SASL_DB_MANS_FALSE@man_MANS = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8
+
+@NO_SASL_DB_MANS_TRUE@man_MANS = 
+
+saslpasswd2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+saslpasswd2_SOURCES = saslpasswd.c
+sasldblistusers2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+sasldblistusers2_SOURCES = sasldblistusers.c
+dbconverter_2_LDADD = ../sasldb/libsasldb.la $(all_sasl_libs)
+pluginviewer_LDADD = $(all_sasl_libs)
+pluginviewer_SOURCES = pluginviewer.c
+
+testsuite_LDADD = $(all_sasl_libs) @DMALLOC_LIBS@
+
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+testsuitestatic_SOURCES = testsuite.c
+testsuitestatic_LDADD = $(all_sasl_static_libs) @DMALLOC_LIBS@ @SASL_DL_LIB@
+testsuitestatic_DEPENDENCIES = ../lib/.libs/libsasl2.a
+
+smtptest_SOURCES = 
+smtptest_DEPENDENCIES = ./smtptest.lo ./libsfsasl2.la
+smtptest_LDADD = ./smtptest.lo ./libsfsasl2.la @SFIO_LIB_FLAGS@ @DMALLOC_LIBS@ $(all_sasl_libs)
+
+saslincludedir = $(includedir)/sasl
+
+saslinclude_HEADERS = @SASL_UTIL_HEADERS_EXTRA@
+EXTRA_HEADERS = sfsasl.h
+
+# Note: we explicitly do *not* link to libsfio, as people will need to
+# link to that anyway if they want to use this. 
+lib_LTLIBRARIES = @SASL_UTIL_LIBS_EXTRA@
+EXTRA_LTLIBRARIES = libsfsasl2.la
+libsfsasl2_la_SOURCES = 
+libsfsasl2_la_LIBADD = sfsasl.lo
+libsfsasl2_la_LDFLAGS = -version-info 1:0:0 -export-dynamic -rpath $(libdir)
+
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include @SASL_DB_INC@
+EXTRA_DIST = saslpasswd2.8 sasldblistusers2.8 pluginviewer.8 sfsasl.h sfsasl.c smtptest.c testsuite.c pluginviewer.c NTMakefile
+subdir = utils
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/config/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+libsfsasl2_la_DEPENDENCIES = sfsasl.lo
+am_libsfsasl2_la_OBJECTS =
+libsfsasl2_la_OBJECTS = $(am_libsfsasl2_la_OBJECTS)
+EXTRA_PROGRAMS = saslpasswd2$(EXEEXT) sasldblistusers2$(EXEEXT) \
+       testsuite$(EXEEXT) testsuitestatic$(EXEEXT) smtptest$(EXEEXT) \
+       pluginviewer$(EXEEXT)
+noinst_PROGRAMS = dbconverter-2$(EXEEXT)
+sbin_PROGRAMS = @SASL_DB_UTILS@ @SMTPTEST_PROGRAM@ pluginviewer$(EXEEXT)
+PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS)
+
+dbconverter_2_SOURCES = dbconverter-2.c
+dbconverter_2_OBJECTS = dbconverter-2.$(OBJEXT)
+dbconverter_2_DEPENDENCIES = ../sasldb/libsasldb.la ../lib/libsasl2.la
+dbconverter_2_LDFLAGS =
+am_pluginviewer_OBJECTS = pluginviewer.$(OBJEXT)
+pluginviewer_OBJECTS = $(am_pluginviewer_OBJECTS)
+pluginviewer_DEPENDENCIES = ../lib/libsasl2.la
+pluginviewer_LDFLAGS =
+am_sasldblistusers2_OBJECTS = sasldblistusers.$(OBJEXT)
+sasldblistusers2_OBJECTS = $(am_sasldblistusers2_OBJECTS)
+sasldblistusers2_DEPENDENCIES = ../sasldb/libsasldb.la \
+       ../lib/libsasl2.la
+sasldblistusers2_LDFLAGS =
+am_saslpasswd2_OBJECTS = saslpasswd.$(OBJEXT)
+saslpasswd2_OBJECTS = $(am_saslpasswd2_OBJECTS)
+saslpasswd2_DEPENDENCIES = ../sasldb/libsasldb.la ../lib/libsasl2.la
+saslpasswd2_LDFLAGS =
+am_smtptest_OBJECTS =
+smtptest_OBJECTS = $(am_smtptest_OBJECTS)
+smtptest_LDFLAGS =
+testsuite_SOURCES = testsuite.c
+testsuite_OBJECTS = testsuite.$(OBJEXT)
+testsuite_DEPENDENCIES = ../lib/libsasl2.la
+testsuite_LDFLAGS =
+am_testsuitestatic_OBJECTS = testsuite.$(OBJEXT)
+testsuitestatic_OBJECTS = $(am_testsuitestatic_OBJECTS)
+testsuitestatic_LDFLAGS =
+
+DEFAULT_INCLUDES =  -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dbconverter-2.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/pluginviewer.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/sasldblistusers.Po \
+@AMDEP_TRUE@   ./$(DEPDIR)/saslpasswd.Po ./$(DEPDIR)/testsuite.Po
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) \
+       $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libsfsasl2_la_SOURCES) dbconverter-2.c \
+       $(pluginviewer_SOURCES) $(sasldblistusers2_SOURCES) \
+       $(saslpasswd2_SOURCES) $(smtptest_SOURCES) testsuite.c \
+       $(testsuitestatic_SOURCES)
+
+NROFF = nroff
+MANS = $(man_MANS)
+HEADERS = $(saslinclude_HEADERS)
+
+DIST_COMMON = $(saslinclude_HEADERS) $(srcdir)/Makefile.in Makefile.am
+SOURCES = $(libsfsasl2_la_SOURCES) dbconverter-2.c $(pluginviewer_SOURCES) $(sasldblistusers2_SOURCES) $(saslpasswd2_SOURCES) $(smtptest_SOURCES) testsuite.c $(testsuitestatic_SOURCES)
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.in $(ACLOCAL_M4)
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  utils/Makefile
+Makefile:  $(srcdir)/Makefile.in  $(top_builddir)/config.status
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
+libLTLIBRARIES_INSTALL = $(INSTALL)
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         if test -f $$p; then \
+           f="`echo $$p | sed -e 's|^.*/||'`"; \
+           echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f"; \
+           $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$f; \
+         else :; fi; \
+       done
+
+uninstall-libLTLIBRARIES:
+       @$(NORMAL_UNINSTALL)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+           p="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
+         $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+       done
+
+clean-libLTLIBRARIES:
+       -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+       @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+         dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+         test "$$dir" = "$$p" && dir=.; \
+         echo "rm -f \"$${dir}/so_locations\""; \
+         rm -f "$${dir}/so_locations"; \
+       done
+libsfsasl2.la: $(libsfsasl2_la_OBJECTS) $(libsfsasl2_la_DEPENDENCIES) 
+       $(LINK)  $(libsfsasl2_la_LDFLAGS) $(libsfsasl2_la_OBJECTS) $(libsfsasl2_la_LIBADD) $(LIBS)
+
+clean-noinstPROGRAMS:
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(sbindir)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         if test -f $$p \
+            || test -f $$p1 \
+         ; then \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+          echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f"; \
+          $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(sbinPROGRAMS_INSTALL) $$p $(DESTDIR)$(sbindir)/$$f || exit 1; \
+         else :; fi; \
+       done
+
+uninstall-sbinPROGRAMS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+         echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
+         rm -f $(DESTDIR)$(sbindir)/$$f; \
+       done
+
+clean-sbinPROGRAMS:
+       @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+dbconverter-2$(EXEEXT): $(dbconverter_2_OBJECTS) $(dbconverter_2_DEPENDENCIES) 
+       @rm -f dbconverter-2$(EXEEXT)
+       $(LINK) $(dbconverter_2_LDFLAGS) $(dbconverter_2_OBJECTS) $(dbconverter_2_LDADD) $(LIBS)
+pluginviewer$(EXEEXT): $(pluginviewer_OBJECTS) $(pluginviewer_DEPENDENCIES) 
+       @rm -f pluginviewer$(EXEEXT)
+       $(LINK) $(pluginviewer_LDFLAGS) $(pluginviewer_OBJECTS) $(pluginviewer_LDADD) $(LIBS)
+sasldblistusers2$(EXEEXT): $(sasldblistusers2_OBJECTS) $(sasldblistusers2_DEPENDENCIES) 
+       @rm -f sasldblistusers2$(EXEEXT)
+       $(LINK) $(sasldblistusers2_LDFLAGS) $(sasldblistusers2_OBJECTS) $(sasldblistusers2_LDADD) $(LIBS)
+saslpasswd2$(EXEEXT): $(saslpasswd2_OBJECTS) $(saslpasswd2_DEPENDENCIES) 
+       @rm -f saslpasswd2$(EXEEXT)
+       $(LINK) $(saslpasswd2_LDFLAGS) $(saslpasswd2_OBJECTS) $(saslpasswd2_LDADD) $(LIBS)
+smtptest$(EXEEXT): $(smtptest_OBJECTS) $(smtptest_DEPENDENCIES) 
+       @rm -f smtptest$(EXEEXT)
+       $(LINK) $(smtptest_LDFLAGS) $(smtptest_OBJECTS) $(smtptest_LDADD) $(LIBS)
+testsuite$(EXEEXT): $(testsuite_OBJECTS) $(testsuite_DEPENDENCIES) 
+       @rm -f testsuite$(EXEEXT)
+       $(LINK) $(testsuite_LDFLAGS) $(testsuite_OBJECTS) $(testsuite_LDADD) $(LIBS)
+testsuitestatic$(EXEEXT): $(testsuitestatic_OBJECTS) $(testsuitestatic_DEPENDENCIES) 
+       @rm -f testsuitestatic$(EXEEXT)
+       $(LINK) $(testsuitestatic_LDFLAGS) $(testsuitestatic_OBJECTS) $(testsuitestatic_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT) core *.core
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbconverter-2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pluginviewer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sasldblistusers.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saslpasswd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testsuite.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `test -f '$<' || echo '$(srcdir)/'`$<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
+@am__fastdepCC_TRUE@     -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
+@am__fastdepCC_TRUE@   else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+@am__fastdepCC_TRUE@   fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+man8dir = $(mandir)/man8
+install-man8: $(man8_MANS) $(man_MANS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(man8dir)
+       @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.8*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+         else file=$$i; fi; \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           8*) ;; \
+           *) ext='8' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst"; \
+         $(INSTALL_DATA) $$file $(DESTDIR)$(man8dir)/$$inst; \
+       done
+uninstall-man8:
+       @$(NORMAL_UNINSTALL)
+       @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+       l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+       for i in $$l2; do \
+         case "$$i" in \
+           *.8*) list="$$list $$i" ;; \
+         esac; \
+       done; \
+       for i in $$list; do \
+         ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           8*) ;; \
+           *) ext='8' ;; \
+         esac; \
+         inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+         inst=`echo $$inst | sed -e 's/^.*\///'`; \
+         inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+         echo " rm -f $(DESTDIR)$(man8dir)/$$inst"; \
+         rm -f $(DESTDIR)$(man8dir)/$$inst; \
+       done
+saslincludeHEADERS_INSTALL = $(INSTALL_HEADER)
+install-saslincludeHEADERS: $(saslinclude_HEADERS)
+       @$(NORMAL_INSTALL)
+       $(mkinstalldirs) $(DESTDIR)$(saslincludedir)
+       @list='$(saslinclude_HEADERS)'; for p in $$list; do \
+         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " $(saslincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(saslincludedir)/$$f"; \
+         $(saslincludeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(saslincludedir)/$$f; \
+       done
+
+uninstall-saslincludeHEADERS:
+       @$(NORMAL_UNINSTALL)
+       @list='$(saslinclude_HEADERS)'; for p in $$list; do \
+         f="`echo $$p | sed -e 's|^.*/||'`"; \
+         echo " rm -f $(DESTDIR)$(saslincludedir)/$$f"; \
+         rm -f $(DESTDIR)$(saslincludedir)/$$f; \
+       done
+
+ETAGS = etags
+ETAGSFLAGS =
+
+CTAGS = ctags
+CTAGSFLAGS =
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$tags$$unique" \
+         || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+            $$tags $$unique
+
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+top_distdir = ..
+distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkinstalldirs) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS)
+
+installdirs:
+       $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(sbindir) $(DESTDIR)$(man8dir) $(DESTDIR)$(saslincludedir)
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+       -rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+       clean-noinstPROGRAMS clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-saslincludeHEADERS
+
+install-exec-am: install-libLTLIBRARIES install-sbinPROGRAMS
+
+install-info: install-info-am
+
+install-man: install-man8
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-libLTLIBRARIES uninstall-man \
+       uninstall-saslincludeHEADERS uninstall-sbinPROGRAMS
+
+uninstall-man: uninstall-man8
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
+       clean-sbinPROGRAMS ctags distclean distclean-compile \
+       distclean-generic distclean-libtool distclean-tags distdir dvi \
+       dvi-am info info-am install install-am install-data \
+       install-data-am install-exec install-exec-am install-info \
+       install-info-am install-libLTLIBRARIES install-man install-man8 \
+       install-saslincludeHEADERS install-sbinPROGRAMS install-strip \
+       installcheck installcheck-am installdirs maintainer-clean \
+       maintainer-clean-generic mostlyclean mostlyclean-compile \
+       mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+       tags uninstall uninstall-am uninstall-info-am \
+       uninstall-libLTLIBRARIES uninstall-man uninstall-man8 \
+       uninstall-saslincludeHEADERS uninstall-sbinPROGRAMS
+
+
+sfsasl.lo: sfsasl.c
+       $(LIBTOOL) --mode=compile $(COMPILE) @SFIO_INC_FLAGS@ -c $(srcdir)/sfsasl.c
+
+smtptest.lo: smtptest.c
+       $(LIBTOOL) --mode=compile $(COMPILE) @SFIO_INC_FLAGS@ -c $(srcdir)/smtptest.c
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/utils/NTMakefile b/utils/NTMakefile
new file mode 100644 (file)
index 0000000..bf8543d
--- /dev/null
@@ -0,0 +1,83 @@
+!INCLUDE ..\win32\common.mak
+
+sasl_apps=saslpasswd2.exe sasldblistusers2.exe testsuite.exe pluginviewer.exe
+sasl_out=saslpasswd2.pdb sasldblistusers2.pdb testsuite.pdb pluginviewer.pdb
+
+saslpwd_objs = saslpasswd.obj
+sasldblistusers_objs = sasldblistusers.obj
+testsuite_objs = testsuite.obj
+pluginviewer_objs = pluginviewer.obj
+
+all_objs = $(saslpwd_objs) $(sasldblistusers_objs) $(testsuite_objs) $(pluginviewer_objs)
+all_out = $(sasl_apps) $(sasl_out)
+
+DB_FLAGS = /I $(DB_INCLUDE) /I "..\sasldb"
+CPPFLAGS = /I "..\win32\include" /I "." /I "..\include" $(DB_FLAGS) /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL"
+CPPFLAGS = $(CPPFLAGS) /DNEED_GETOPT
+
+
+DB_LIBS=/libpath:$(DB_LIBPATH) $(DB_LIB)
+SASL_LIB=/libpath:"..\lib" libsasl.lib
+SASL_DB_LIB=/libpath:"..\plugins" saslSASLDB.lib
+
+# EXTRA_LIBS is automatically included into LINK32EXE_FLAGS/LINK32DLL_FLAGS
+EXTRA_LIBS=$(SASL_LIB) 
+
+# Where to install files from this directory
+bindir = $(prefix)\bin
+
+
+all : all-recursive
+
+#
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels
+#
+# In order to force xcopy not to confirm if the second parameter is file or directory,
+# the first parameter has to contain a wildcard character. For example, we use libsasl.l*,
+# instead of libsasl.lib. Ugly, but works!
+#
+# Note, that we will copy all executabless here, not just $(sasl_apps). This is a bug, but it allows
+# us to copy optionally built executables, which might not be in $(sasl_apps). The latter is a feature.
+#
+install: $(sasl_apps)
+       @xcopy *.exe $(bindir) /I /F /Y
+
+all-recursive : $(sasl_apps)
+
+saslpasswd2.exe: $(saslpwd_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"saslpasswd2.pdb" /out:"saslpasswd2.exe" $(saslpwd_objs)
+<<
+
+sasldblistusers2.exe: $(sasldblistusers_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) $(SASL_DB_LIB) /pdb:"sasldblistusers2.pdb" /out:"sasldblistusers2.exe" $(sasldblistusers_objs)
+<<
+
+testsuite.exe: $(testsuite_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"testsuite.pdb" /out:"testsuite.exe" $(testsuite_objs)
+<<
+
+pluginviewer.exe: $(pluginviewer_objs)
+       $(LINK32EXE) @<< $(LINK32EXE_FLAGS) /pdb:"pluginviewer.pdb" /out:"pluginviewer.exe" $(pluginviewer_objs)
+<<
+
+CLEAN :
+       -@erase $(all_objs)
+       -@erase "*.idb"
+       -@erase "*.pch"
+       -@erase "*.pdb"
+       -@erase $(all_out)
+
+.c.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cpp.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
+
+.cxx.obj::
+   $(CPP) @<<
+   $(CPP_PROJ) $< 
+<<
diff --git a/utils/dbconverter-2.c b/utils/dbconverter-2.c
new file mode 100644 (file)
index 0000000..d188e00
--- /dev/null
@@ -0,0 +1,437 @@
+/* dbconverter-2.c -- convert libsasl v1 sasldb's to SASLv2 format
+ * $Id: dbconverter-2.c,v 1.8 2003/02/13 19:56:17 rjs3 Exp $
+ * Rob Siemborski
+ * based on SASLv1 sasldblistusers
+ */
+/* 
+ * 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sasl.h>
+#include <saslplug.h>
+#include "../sasldb/sasldb.h"
+
+/* Cheating to make the utils work out right */
+extern const sasl_utils_t *sasl_global_utils;
+sasl_conn_t *globalconn;
+
+typedef void *listcb_t(const char *, const char *, const char *,
+                      const char *, unsigned);
+
+void listusers_cb(const char *authid, const char *realm,
+                 const char *mechanism, const char *secret,
+                 unsigned seclen)
+{
+    char newPropBuffer[8192];
+
+    if (!authid || !mechanism || !realm) {
+       fprintf(stderr,"userlist callback has bad param");
+       return;
+    }
+
+    /* the entries that just say the mechanism exists */
+    if (strlen(authid)==0) return;
+
+    printf("Converting: %s@%s (%s)...",authid,realm,mechanism);
+
+    /* Maybe we have a plaintext password? */
+    if(!strcmp(mechanism,"PLAIN-APOP")) {
+       sprintf(newPropBuffer, "userPassword");
+       /* Skip salt + NULL */
+       secret = secret + 17;
+       seclen -= 17;
+    } else {
+       sprintf(newPropBuffer, "cmusaslsecret%s", mechanism);
+    }
+    
+    _sasldb_putdata(sasl_global_utils, globalconn,
+                   authid, realm, newPropBuffer,
+                   secret, seclen);
+
+    printf("ok\n");
+}
+
+/*
+ * List all users in database
+ */
+
+#if defined(SASL_GDBM)
+
+#include <gdbm.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int listusers(const char *path, listcb_t *cb)
+{
+    GDBM_FILE indb;
+    datum dkey, nextkey, dvalue;
+
+    indb = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
+
+    if (!indb) {
+       fprintf(stderr, "can't open %s\n", path);
+       return 1;
+    }
+
+    memset(&dkey, 0, sizeof(datum));
+
+    dkey = gdbm_firstkey(indb);
+
+    while (dkey.dptr != NULL) {
+       char *authid = dkey.dptr;
+       char *realm  = dkey.dptr+strlen(authid)+1;
+       char *tmp    = realm + strlen(realm)+1;
+       char mech[1024];
+       int len = dkey.dsize - (tmp - ((char *)dkey.dptr));
+
+       if (len >= (int) sizeof mech) {
+           fprintf(stderr, "malformed database entry\n");
+           break;
+       }
+       memcpy(mech, tmp, len);
+       mech[dkey.dsize - (tmp - dkey.dptr)] = '\0';
+
+       dvalue = gdbm_fetch(indb, dkey);
+
+       if (*authid && dvalue.dptr) {
+           /* don't check return values */
+           cb(authid,realm,mech,dvalue.dptr,dvalue.dsize);
+       }
+
+       nextkey=gdbm_nextkey(indb, dkey);
+       dkey=nextkey;
+    }
+
+    gdbm_close(indb);
+    return 0;
+}
+
+#elif defined(SASL_NDBM)
+
+#include <ndbm.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+int listusers(const char *path, listcb_t *cb)
+{
+    DBM *indb;
+    datum dkey, nextkey, dvalue;
+
+    indb = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR);
+
+    if (!indb) {
+       fprintf(stderr, "can't open %s\n", path);
+       return 1;
+    }
+
+    dkey = dbm_firstkey(indb);
+
+    while (dkey.dptr != NULL) {
+       char *authid = dkey.dptr;
+       char *realm  = dkey.dptr+strlen(authid)+1;
+       char *tmp    = realm + strlen(realm)+1;
+       char mech[1024];
+       int len = dkey.dsize - (tmp - ((char *)dkey.dptr));
+
+       if (len >= (int) sizeof mech) {
+           fprintf(stderr, "malformed database entry\n");
+           break;
+       }
+       memcpy(mech, tmp, len);
+       mech[dkey.dsize - (tmp - ((char *)dkey.dptr))] = '\0';
+
+       dvalue = dbm_fetch(indb, dkey);
+
+       if (*authid && dvalue.dptr) {
+           /* don't check return values */
+           cb(authid,realm,mech,dvalue.dptr,dvalue.dsize);
+       }
+
+       nextkey=dbm_nextkey(indb);
+       dkey=nextkey;
+    }
+
+    dbm_close(indb);
+    return 0;
+}
+
+#elif defined(SASL_BERKELEYDB)
+
+#include <db.h>
+
+/*
+ * Open the database
+ *
+ */
+static int berkeleydb_open(const char *path,DB **mbdb)
+{
+    int ret;
+
+#if DB_VERSION_MAJOR < 3
+    ret = db_open(path, DB_HASH, DB_CREATE, 0664, NULL, NULL, mbdb);
+#else /* DB_VERSION_MAJOR < 3 */
+    ret = db_create(mbdb, NULL, 0);
+    if (ret == 0 && *mbdb != NULL)
+    {
+#if DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 1
+       ret = (*mbdb)->open(*mbdb, NULL, path, NULL, DB_HASH, DB_CREATE, 0664);
+#else
+       ret = (*mbdb)->open(*mbdb, path, NULL, DB_HASH, DB_CREATE, 0664);
+#endif
+       if (ret != 0)
+       {
+           (void) (*mbdb)->close(*mbdb, 0);
+           *mbdb = NULL;
+       }
+    }
+#endif /* DB_VERSION_MAJOR < 3 */
+
+    if (ret != 0) {
+       fprintf(stderr,"Error opening password file %s\n", path);
+       return SASL_FAIL;
+    }
+
+    return SASL_OK;
+}
+
+/*
+ * Close the database
+ *
+ */
+
+static void berkeleydb_close(DB *mbdb)
+{
+    int ret;
+    
+    ret = mbdb->close(mbdb, 0);
+    if (ret!=0) {
+       fprintf(stderr,"error closing sasldb: %s",
+               db_strerror(ret));
+    }
+}
+
+int listusers(const char *path, listcb_t *cb)
+{
+    int result;
+    DB *mbdb = NULL;
+    DBC *cursor;
+    DBT key, data;
+
+    /* open the db */
+    result=berkeleydb_open(path, &mbdb);
+    if (result!=SASL_OK) goto cleanup;
+
+    /* make cursor */
+#if DB_VERSION_MAJOR < 3
+#if DB_VERSION_MINOR < 6
+    result = mbdb->cursor(mbdb, NULL,&cursor); 
+#else
+    result = mbdb->cursor(mbdb, NULL,&cursor, 0); 
+#endif /* DB_VERSION_MINOR < 7 */
+#else /* DB_VERSION_MAJOR < 3 */
+    result = mbdb->cursor(mbdb, NULL,&cursor, 0); 
+#endif /* DB_VERSION_MAJOR < 3 */
+
+    if (result!=0) {
+       fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result));
+      result = SASL_FAIL;
+      goto cleanup;
+    }
+
+    memset(&key,0, sizeof(key));
+    memset(&data,0,sizeof(data));
+
+    /* loop thru */
+    result = cursor->c_get(cursor, &key, &data,
+                          DB_FIRST);
+
+    while (result != DB_NOTFOUND)
+    {
+       char *authid;
+       char *realm;
+       char *tmp;
+       unsigned int len;
+       char mech[1024];
+       int numnulls = 0;
+       unsigned int lup;
+
+       /* make sure there are exactly 2 null's */
+       for (lup=0;lup<key.size;lup++)
+           if (((char *)key.data)[lup]=='\0')
+               numnulls++;
+
+       if (numnulls != 2) {
+           fprintf(stderr,"warning: probable database corruption\n");
+           result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+           continue;
+       }
+
+       authid = key.data;
+       realm  = authid + strlen(authid)+1;
+       tmp    = realm + strlen(realm)+1;
+       len = key.size - (tmp - authid);
+
+       /* make sure we have enough space of mech */
+       if (len >=sizeof(mech)) {
+           fprintf(stderr,"warning: absurdly long mech name\n");
+           result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+           continue;
+       }
+
+       memcpy(mech, tmp, key.size - (tmp - ((char *)key.data)));
+       mech[key.size - (tmp - ((char *)key.data))] = '\0';
+
+       if (*authid) {
+           /* don't check return values */
+           cb(authid,realm,mech,data.data,data.size);
+       }
+
+       result = cursor->c_get(cursor, &key, &data, DB_NEXT);
+    }
+
+    if (result != DB_NOTFOUND) {
+       fprintf(stderr,"failure: %s\n",db_strerror(result));
+       result = SASL_FAIL;
+       goto cleanup;
+    }
+
+    result = cursor->c_close(cursor);
+    if (result!=0) result = SASL_FAIL;
+
+    result = SASL_OK;
+
+ cleanup:
+
+    if (mbdb != NULL) berkeleydb_close(mbdb);
+    return result;
+}
+
+#else 
+
+/* ARGSUSED */
+
+int listusers(const char *path __attribute__((unused)),
+             listcb_t *cb __attribute__((unused)))
+{
+    fprintf(stderr,"Unsupported DB format");
+    exit(1);
+}
+
+#endif
+
+char *db_new=SASL_DB_PATH;
+
+int good_getopt(void *context __attribute__((unused)), 
+               const char *plugin_name __attribute__((unused)), 
+               const char *option,
+               const char **result,
+               unsigned *len)
+{
+    if (db_new && !strcmp(option, "sasldb_path")) {
+       *result = db_new;
+       if (len)
+           *len = strlen(db_new);
+       return SASL_OK;
+    }
+
+    return SASL_FAIL;
+}
+
+static struct sasl_callback goodsasl_cb[] = {
+    { SASL_CB_GETOPT, &good_getopt, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int main(int argc, char **argv)
+{
+    const char *db="/etc/sasldb";
+    int result;
+
+    if (argc > 1) {
+       db = argv[1];
+       if(argc > 2) {
+           db_new = argv[2];
+       }
+    }
+
+    result = sasl_server_init(goodsasl_cb, "dbconverter");
+    if (result != SASL_OK) {
+       printf("couldn't init saslv2\n");
+       return 1;
+    }
+
+    result = sasl_server_new("sasldb",
+                            "localhost",
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            0,
+                            &globalconn);
+    if (result != SASL_OK) {
+       printf("couldn't create globalconn\n");
+       return 1;
+    }
+
+    if(_sasl_check_db(sasl_global_utils,globalconn) != SASL_OK) {
+       printf("target DB %s is not OK\n", db_new);
+       return 1;
+    }
+    
+    printf("\nThis program will take the sasldb file specified on the\n"
+           "command line and convert it to a new sasldb file in the default\n"
+           "location (usually /etc/sasldb). It is STRONGLY RECOMMENDED that you\n"
+           "backup sasldb before allowing this program to run\n\n"
+          "We are going to convert %s and our output will be in %s\n\n"
+           "Press return to continue\n", db, db_new);
+
+    getchar();
+
+    listusers(db, (listcb_t *) &listusers_cb);
+
+    sasl_dispose(&globalconn);
+    sasl_done();
+    
+    exit(0);
+}
diff --git a/utils/pluginviewer.8 b/utils/pluginviewer.8
new file mode 100644 (file)
index 0000000..312d1b7
--- /dev/null
@@ -0,0 +1,104 @@
+.\" pluginviewer.8 -- pluginviewer man page
+.\" Alexey Melnikov
+.\"
+
+.\" Copyright (c) 2006 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.
+
+.\"
+.TH PLUGINVIEWER 8 "Apr 10, 2006" "CMU SASL"
+.SH NAME
+pluginviewer \- list loadable SASL plugins and their properties
+.SH SYNOPSIS
+.B pluginviewer
+.RB [ -a ]
+.RB [ -s ]
+.RB [ -c ]
+.RB [ -b\ min=N,max=N ]
+.RB [ -e\ ssf=N,id=ID ]
+.RB [ -m\ MECHS ]
+.RB [ -x\ AUXPROP_MECH ]
+.RB [ -f\ FLAGS ]
+.RB [ -p\ PATH ]
+.SH DESCRIPTION
+.I pluginviewer
+can be used by a server administrator to troubleshoot SASL installations.
+The utility can list loadable (properly configured) client and server
+side plugins, as well as auxprop plugins.
+.
+.SH OPTIONS
+.TP
+.B -a
+List auxprop plugins.
+.TP
+.B -s
+List server authentication (SASL) plugins.
+.TP
+.B -c
+List client authentication (SASL) plugins.
+.TP
+.B -b min=N1,max=N2
+List client authentication (SASL) plugins.
+Strength of the SASL security layer in bits. min=N1 specifies the minumum strength
+to use (1 => integrity protection). max=N2 specifies the maximum strength to use.
+Only SASL mechanisms which support security layer with strength M such that N1 <= M <= N2
+will be shown.
+.TP
+.B -e ssf=N,id=ID
+Assume that an external security layer (e.g. TLS) with N-bit strength is installed.
+The ID is the authentication identity used by the external security layer.
+.TP
+.B -m MECHS
+Limit listed SASL plugins to the ones included in the MECHS (space separated) list.
+.TP
+.B -x AUXPROP_MECHS
+Limit listed auxprop plugins to the one listed in the AUXPROP_MECHS (space separated) list.
+.TP
+.B -f FLAGS
+Set security flags. FLAGS is a comma separated list of one or more of the following security flags:
+noplain (SASL mechanism doesn\'t send password in the clear during authentication),
+noactive (require protection from active attacks), nodict (require mechanisms which are
+secure against passive dictionary attacks), forwardsec (require forward secrecy),
+passcred (require mechanisms that can delegate client credentials),
+maximum (require all security flags).
+.TP
+.B -p PATH
+Specifies a colon-separated search path for plugins.
+.SH SEE ALSO
+.TP
+rfc2222 \- Simple Authentication and Security Layer (SASL)
diff --git a/utils/pluginviewer.c b/utils/pluginviewer.c
new file mode 100644 (file)
index 0000000..a0fbab1
--- /dev/null
@@ -0,0 +1,805 @@
+/* pluginviewer.c -- Plugin Viewer for CMU SASL
+ * Alexey Melnikov, Isode Ltd.
+ *
+ * $Id: pluginviewer.c,v 1.4 2006/04/26 15:34:34 mel Exp $
+ */
+/* 
+ * Copyright (c) 2004 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.
+ */
+#include <config.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#ifdef WIN32
+# include <winsock.h>
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+__declspec(dllimport) int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#else  /* WIN32 */
+# include <netinet/in.h>
+#endif /* WIN32 */
+#include <sasl.h>
+#include <saslutil.h>
+#include <saslplug.h>
+
+#ifdef macintosh
+#include <sioux.h>
+#include <parse_cmd_line.h>
+#define MAX_ARGC (100)
+int xxx_main(int argc, char *argv[]);
+int main(void)
+{
+       char *argv[MAX_ARGC];
+       int argc;
+       char line[400];
+       SIOUXSettings.asktosaveonclose = 0;
+       SIOUXSettings.showstatusline = 1;
+       argc=parse_cmd_line(MAX_ARGC,argv,sizeof(line),line);
+       return xxx_main(argc,argv);
+}
+#define main xxx_main
+#endif
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef HAVE_GETSUBOPT
+int getsubopt(char **optionp, const char * const *tokens, char **valuep);
+#endif
+
+static const char
+build_ident[] = "$Build: pluginviewer " PACKAGE "-" VERSION " $";
+
+static const char *progname = NULL;
+/* SASL authentication methods (client or server side). NULL means all. */
+static char *mech = NULL;
+/* auxprop methods. NULL means all. */
+static char *auxprop_mech = NULL;
+
+#define N_CALLBACKS (16)
+
+#define NOT_NULL       (void *) -1
+
+#define SAMPLE_SEC_BUF_SIZE (2048)
+
+static const char *bit_subopts[] = {
+#define OPT_MIN (0)
+  "min",
+#define OPT_MAX (1)
+  "max",
+  NULL
+};
+
+static const char *ext_subopts[] = {
+#define OPT_EXT_SSF (0)
+  "ssf",
+#define OPT_EXT_ID (1)
+  "id",
+  NULL
+};
+
+static const char *flag_subopts[] = {
+#define OPT_NOPLAIN (0)
+  "noplain",
+#define OPT_NOACTIVE (1)
+  "noactive",
+#define OPT_NODICT (2)
+  "nodict",
+#define OPT_FORWARDSEC (3)
+  "forwardsec",
+#define OPT_NOANONYMOUS (4)
+  "noanonymous",
+#define OPT_PASSCRED (5)
+  "passcred",
+  NULL
+};
+
+static const char *ip_subopts[] = {
+#define OPT_IP_LOCAL (0)
+  "local",
+#define OPT_IP_REMOTE (1)
+  "remote",
+  NULL
+};
+
+/* Whitespace separated list of mechanisms to allow (e.g. 'plain otp').
+   Used to restrict the mechanisms to a subset of the installed plugins.
+   Default: NULL (i.e. all available) */
+#define SASL_OPT_MECH_LIST                 "mech_list"
+/* Name of canon_user plugin to use, default is "INTERNAL" */
+#define SASL_OPT_CANON_USER_PLUGIN         "canon_user_plugin"
+/* Name of auxiliary plugin to use, you may specify a space-separated list
+   of plugin names, and the plugins will be queried in order. Default is NULL (i.e. query all) */
+#define SASL_OPT_AUXPROP_PLUGIN                    "auxprop_plugin"
+
+static sasl_conn_t *server_conn = NULL;
+static sasl_conn_t *client_conn = NULL;
+
+static void
+free_conn(void)
+{
+    if (server_conn) {
+        sasl_dispose(&server_conn);
+    }
+    if (client_conn) {
+        sasl_dispose(&client_conn);
+    }
+}
+
+static int
+sasl_my_log(void *context __attribute__((unused)),
+           int priority,
+           const char *message) 
+{
+    const char *label;
+
+    if (! message) {
+        return SASL_BADPARAM;
+    }
+
+    switch (priority) {
+    case SASL_LOG_ERR:
+        label = "Error";
+        break;
+    case SASL_LOG_NOTE:
+        label = "Info";
+        break;
+    default:
+        label = "Other";
+        break;
+    }
+
+    fprintf(stderr, "%s: SASL %s: %s\n",
+           progname, label, message);
+
+    return SASL_OK;
+}
+
+static int
+getpath(void *context,
+       const char ** path) 
+{
+    const char *searchpath = (const char *) context;
+
+    if (! path) {
+        return SASL_BADPARAM;
+    }
+
+    if (searchpath) {
+        *path = searchpath;
+    } else {
+        *path = PLUGINDIR;
+    }
+
+    return SASL_OK;
+}
+
+static int
+sasl_getopt (
+    void *context,
+    const char *plugin_name,
+    const char *option,
+    const char **result,
+    unsigned *len
+)
+{
+    if (strcasecmp (option, SASL_OPT_MECH_LIST) == 0) {
+        /* Whitespace separated list of mechanisms to allow (e.g. 'plain otp').
+           Used to restrict the mechanisms to a subset of the installed plugins.
+           Default: NULL (i.e. all available) */
+        if (result != NULL) {
+           *result = mech;
+        }
+
+        if (len != NULL) {
+    /* This might be NULL, which means "all mechanisms" */
+           *len = mech ? strlen(mech) : 0;
+        }
+        return (SASL_OK);
+    } 
+    else {
+        /* Unrecognized */
+        return (SASL_FAIL);
+    }
+}
+
+static void
+sasldebug(int why, const char *what, const char *errstr)
+{
+    fprintf(stderr, "%s: %s: %s",
+           progname,
+           what,
+           sasl_errstring(why, NULL, NULL));
+    if (errstr) {
+        fprintf(stderr, " (%s)\n", errstr);
+    } else {
+        putc('\n', stderr);
+    }
+}
+
+static void
+saslfail(int why, const char *what, const char *errstr)
+{
+    sasldebug(why, what, errstr);
+    free_conn();
+    /* Call sasl_done twice - one for the client side SASL and
+       one for the server side. */
+    sasl_done();
+    sasl_done();
+    exit(EXIT_FAILURE);
+}
+
+static void
+fail(const char *what)
+{
+    fprintf(stderr, "%s: %s\n",
+           progname, what);
+    exit(EXIT_FAILURE);
+}
+
+static void
+osfail()
+{
+    perror(progname);
+    exit(EXIT_FAILURE);
+}
+
+/* Produce a space separated list of installed mechanisms */
+static void
+list_installed_server_mechanisms (
+  server_sasl_mechanism_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char ** list_of_mechs = (char **) rock;
+    char * new_list;
+
+    if (stage == SASL_INFO_LIST_START || stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    if (m->plug != NULL) {
+       if (*list_of_mechs == NULL) {
+           *list_of_mechs = strdup(m->plug->mech_name);
+       } else {
+           /* This is suboptimal, but works */
+           new_list = malloc (strlen(*list_of_mechs) + strlen(m->plug->mech_name) + 2);
+           sprintf (new_list, "%s %s", *list_of_mechs, m->plug->mech_name);
+           free (*list_of_mechs);
+           *list_of_mechs = new_list;
+       }
+    }
+}
+
+/* Produce a space separated list of installed mechanisms */
+static void
+list_installed_client_mechanisms (
+  client_sasl_mechanism_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char ** list_of_mechs = (char **) rock;
+    char * new_list;
+
+    if (stage == SASL_INFO_LIST_START || stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    if (m->plug != NULL) {
+       if (*list_of_mechs == NULL) {
+           *list_of_mechs = strdup(m->plug->mech_name);
+       } else {
+           /* This is suboptimal, but works */
+           new_list = malloc (strlen(*list_of_mechs) + strlen(m->plug->mech_name) + 2);
+           sprintf (new_list, "%s %s", *list_of_mechs, m->plug->mech_name);
+           free (*list_of_mechs);
+           *list_of_mechs = new_list;
+       }
+    }
+}
+
+/* Produce a space separated list of installed mechanisms */
+static void
+list_installed_auxprop_mechanisms (
+  sasl_auxprop_plug_t *m,
+  sasl_info_callback_stage_t stage,
+  void *rock
+)
+{
+    char ** list_of_mechs = (char **) rock;
+    char * new_list;
+
+    if (stage == SASL_INFO_LIST_START || stage == SASL_INFO_LIST_END) {
+       return;
+    }
+
+    if (*list_of_mechs == NULL) {
+       *list_of_mechs = strdup(m->name);
+    } else {
+       /* This is suboptimal, but works */
+       new_list = malloc (strlen(*list_of_mechs) + strlen(m->name) + 2);
+       sprintf (new_list, "%s %s", *list_of_mechs, m->name);
+       free (*list_of_mechs);
+       *list_of_mechs = new_list;
+    }
+}
+
+int
+main(int argc, char *argv[])
+{
+  int c = 0;
+  int errflag = 0;
+  int result;
+  sasl_security_properties_t secprops;
+  sasl_ssf_t extssf = 0;
+  const char *ext_authid = NULL;
+  char *options, *value;
+  const char *available_mechs = NULL;
+  unsigned len;
+  unsigned count;
+  sasl_callback_t callbacks[N_CALLBACKS], *callback;
+  char *searchpath = NULL;
+  char *service = "test";
+  char * list_of_server_mechs = NULL;
+  char * list_of_client_mechs = NULL;
+  char * list_of_auxprop_mechs = NULL;
+  int list_all_plugins = 1;             /* By default we list all plugins */
+  int list_client_auth_plugins = 0;
+  int list_server_auth_plugins = 0;
+  int list_auxprop_plugins = 0;
+
+#ifdef WIN32
+  /* initialize winsock */
+    WSADATA wsaData;
+
+    result = WSAStartup( MAKEWORD(2, 0), &wsaData );
+    if ( result != 0) {
+       saslfail(SASL_FAIL, "Initializing WinSockets", NULL);
+    }
+#endif
+
+    progname = strrchr(argv[0], HIER_DELIMITER);
+    if (progname) {
+        progname++;
+    } else {
+        progname = argv[0];
+    }
+
+    /* Init defaults... */
+    memset(&secprops, 0L, sizeof(secprops));
+    secprops.maxbufsize = SAMPLE_SEC_BUF_SIZE;
+    secprops.max_ssf = UINT_MAX;
+
+    while ((c = getopt(argc, argv, "acshb:e:m:f:p:x:?")) != EOF)
+        switch (c) {
+        case 'a':
+           list_auxprop_plugins = 1;
+            list_all_plugins = 0;
+           break;
+
+        case 'x':
+            auxprop_mech = optarg;
+            break;
+
+        case 'c':
+           list_client_auth_plugins = 1;
+            list_all_plugins = 0;
+           break;
+
+        case 's':
+           list_server_auth_plugins = 1;
+            list_all_plugins = 0;
+           break;
+
+        case 'b':
+            options = optarg;
+            while (*options != '\0') {
+               switch(getsubopt(&options, (const char * const *)bit_subopts, &value)) {
+               case OPT_MIN:
+                    if (! value) {
+                       errflag = 1;
+                    } else {
+                       secprops.min_ssf = atoi(value);
+                    }
+                   break;
+               case OPT_MAX:
+                    if (! value) {
+                       errflag = 1;
+                    } else {
+                       secprops.max_ssf = atoi(value);
+                    }
+                   break;
+               default:
+                   errflag = 1;
+                   break;        
+               }
+            }
+            break;
+
+        case 'e':
+            options = optarg;
+            while (*options != '\0') {
+               switch(getsubopt(&options, (const char * const *)ext_subopts, &value)) {
+               case OPT_EXT_SSF:
+                    if (! value) {
+                       errflag = 1;
+                    } else {
+                       extssf = atoi(value);
+                    }
+                   break;
+               case OPT_MAX:
+                    if (! value) {
+                       errflag = 1;
+                    } else {
+                       ext_authid = value;
+                    }
+                   break;
+               default:
+                   errflag = 1;
+                   break;
+               }
+            }
+            break;
+
+        case 'm':
+            mech = optarg;
+            break;
+
+        case 'f':
+            options = optarg;
+            while (*options != '\0') {
+               switch(getsubopt(&options, (const char * const *)flag_subopts, &value)) {
+               case OPT_NOPLAIN:
+                   secprops.security_flags |= SASL_SEC_NOPLAINTEXT;
+                   break;
+               case OPT_NOACTIVE:
+                   secprops.security_flags |= SASL_SEC_NOACTIVE;
+                   break;
+               case OPT_NODICT:
+                   secprops.security_flags |= SASL_SEC_NODICTIONARY;
+                   break;
+               case OPT_FORWARDSEC:
+                   secprops.security_flags |= SASL_SEC_FORWARD_SECRECY;
+                   break;
+               case OPT_NOANONYMOUS:
+                   secprops.security_flags |= SASL_SEC_NOANONYMOUS;
+                   break;
+               case OPT_PASSCRED:
+                   secprops.security_flags |= SASL_SEC_PASS_CREDENTIALS;
+                   break;
+               default:
+                   errflag = 1;
+                   break;
+               }
+               if (value) errflag = 1;
+           }
+            break;
+
+        case 'p':
+            searchpath = optarg;
+            break;
+
+        default:                       /* unknown flag */
+            errflag = 1;
+            break;
+        }
+
+    if (optind != argc) {
+        /* We don't *have* extra arguments */
+        errflag = 1;
+    }
+
+    if (errflag) {
+        fprintf(stderr, "%s: Usage: %s [-a] [-s] [-c] [-b min=N,max=N] [-e ssf=N,id=ID] [-m MECHS] [-x AUXPROP_MECH] [-f FLAGS] [-i local=IP,remote=IP] [-p PATH]\n"
+               "\t-a\tlist auxprop plugins\n"
+                "\t-s\tlist server authentication (SASL) plugins\n"
+                "\t-s\tlist client authentication (SASL) plugins\n"
+               "\t-b ...\t#bits to use for encryption\n"
+               "\t\tmin=N\tminumum #bits to use (1 => integrity)\n"
+               "\t\tmax=N\tmaximum #bits to use\n"
+               "\t-e ...\tassume external encryption\n"
+               "\t\tssf=N\texternal mech provides N bits of encryption\n"
+               "\t\tid=ID\texternal mech provides authentication id ID\n"
+               "\t-m MECHS\tforce to use one of MECHS SASL mechanism\n"
+               "\t-x AUXPROP_MECHS\tforce to use one of AUXPROP_MECHS auxprop plugins\n"
+               "\t-f ...\tset security flags\n"
+               "\t\tnoplain\t\tno plaintext password send during authentication\n"
+               "\t\tnoactive\trequire security vs. active attacks\n"
+               "\t\tnodict\t\trequire security vs. passive dictionary attacks\n"
+               "\t\tforwardsec\trequire forward secrecy\n"
+               "\t\tmaximum\t\trequire all security flags\n"
+               "\t\tpasscred\tattempt to pass client credentials\n"
+#ifdef WIN32
+               "\t-p PATH\tsemicolon-separated search path for mechanisms\n",
+#else
+               "\t-p PATH\tcolon-seperated search path for mechanisms\n",
+#endif
+               progname, progname);
+        exit(EXIT_FAILURE);
+    }
+
+    /* Fill in the callbacks that we're providing... */
+    callback = callbacks;
+
+    /* log */
+    callback->id = SASL_CB_LOG;
+    callback->proc = &sasl_my_log;
+    callback->context = NULL;
+    ++callback;
+      
+    /* getpath */
+    if (searchpath) {
+        callback->id = SASL_CB_GETPATH;
+        callback->proc = &getpath;
+        callback->context = searchpath;
+        ++callback;
+    }
+
+    /* getopt */
+    callback->id = SASL_CB_GETOPT;
+    callback->proc = &sasl_getopt;
+    callback->context = NULL;
+    ++callback;
+
+    /* The following callbacks are for a client connection only.
+    We reuse the same callbacks variable and the server side doesn't like
+    proc == NULL. So we just put something there, != NULL! */
+    callback->id = SASL_CB_AUTHNAME;
+    callback->proc = NOT_NULL;
+    callback->context = NULL;
+    ++callback;
+
+
+    callback->id = SASL_CB_PASS;
+    callback->proc = NOT_NULL;
+    callback->context = NULL;
+    ++callback;
+
+    /* termination */
+    callback->id = SASL_CB_LIST_END;
+    callback->proc = NULL;
+    callback->context = NULL;
+    ++callback;
+
+    /* FIXME: In general case this is not going to work of course,
+       as some plugins will need more callbacks then others. */
+    if (N_CALLBACKS < callback - callbacks) {
+        fail("Out of callback space; recompile with larger N_CALLBACKS");
+    }
+
+    result = sasl_client_init(callbacks);
+    if (result != SASL_OK) {
+        saslfail(result, "Initializing client side of libsasl", NULL);
+    }
+
+    result = sasl_server_init(callbacks, "pluginviewer");
+    if (result != SASL_OK) {
+        saslfail(result, "Initializing server side of libsasl", NULL);
+    }
+
+    if (list_all_plugins || list_server_auth_plugins) {
+
+        /* SASL server plugins */
+        result = sasl_server_new(service,
+                               /* Has to be any non NULL value */
+                               "test.example.com",     /* localdomain */
+                               NULL,                   /* userdomain */
+                               NULL,                   /* iplocal */
+                               NULL,                   /* ipremote */
+                               NULL,
+                               0,
+                               &server_conn);
+        if (result != SASL_OK) {
+            saslfail(result, "Allocating sasl connection state (server side)", NULL);
+        }
+
+        /* The following two options are required for SSF */
+        if (extssf) {
+            result = sasl_setprop(server_conn,
+                               SASL_SSF_EXTERNAL,
+                               &extssf);
+
+            if (result != SASL_OK) {
+               saslfail(result, "Setting external SSF", NULL);
+            }
+        }
+          
+        if (ext_authid) {
+            result = sasl_setprop(server_conn,
+                               SASL_AUTH_EXTERNAL,
+                               &ext_authid);
+
+            if (result != SASL_OK) {
+               saslfail(result, "Setting external authid", NULL);
+            }
+        }
+          
+        result = sasl_setprop(server_conn,
+                           SASL_SEC_PROPS,
+                           &secprops);
+
+        if (result != SASL_OK) {
+            saslfail(result, "Setting security properties", NULL);
+        }
+
+        /* This will use getopt callback, which is using the "mech" global variable */
+        result = sasl_listmech(server_conn,
+                           ext_authid,
+                           NULL,
+                           " ",
+                           NULL,
+                           &available_mechs,
+                           &len,
+                           &count);
+        if (result != SASL_OK) {
+            saslfail(result, "Setting security properties", NULL);
+        }
+
+        if (count > 0) {
+            list_of_server_mechs = NULL;
+
+            sasl_server_plugin_info (NULL,  /* list all SASL mechanisms */
+                                   &list_installed_server_mechanisms,
+                                   (void *) &list_of_server_mechs);
+
+            printf ("Installed SASL (server side) mechanisms are:\n%s\n", list_of_server_mechs);
+
+            free (list_of_server_mechs);
+
+           /* Dump information about the requested SASL mechanism */
+               /* NOTE - available_mechs must not be freed */
+           sasl_server_plugin_info (available_mechs, NULL, NULL);
+        } else {
+           printf ("No server side SASL mechanisms installed\n");
+        }
+    }
+
+    if (list_all_plugins || list_auxprop_plugins) {
+       list_of_auxprop_mechs = NULL;
+
+       auxprop_plugin_info (NULL,  /* list all auxprop mechanisms */
+                           &list_installed_auxprop_mechanisms,
+                           (void *) &list_of_auxprop_mechs);
+
+       printf ("Installed auxprop mechanisms are:\n%s\n", list_of_auxprop_mechs);
+
+       free (list_of_auxprop_mechs);
+
+        
+        auxprop_plugin_info (auxprop_mech, NULL, NULL);
+    }
+
+    /* TODO: add listing of canonicalization plugins, if needed. */
+
+    if (list_all_plugins || list_client_auth_plugins) {
+        /* SASL client plugins */
+        result = sasl_client_new(service,
+                               /* Has to be any non NULL value */
+                               "test.example.com",     /* fqdn */
+                               NULL,                   /* iplocal */
+                               NULL,                   /* ipremote */
+                               NULL,
+                               0,
+                               &client_conn);
+
+        if (result != SASL_OK) {
+            saslfail(result, "Allocating sasl connection state (client side)", NULL);
+        }
+
+        /* The following two options are required for SSF */
+        if (extssf) {
+            result = sasl_setprop(client_conn,
+                               SASL_SSF_EXTERNAL,
+                               &extssf);
+
+            if (result != SASL_OK) {
+               saslfail(result, "Setting external SSF", NULL);
+            }
+        }
+          
+        if (ext_authid) {
+            result = sasl_setprop(client_conn,
+                               SASL_AUTH_EXTERNAL,
+                               &ext_authid);
+
+            if (result != SASL_OK) {
+               saslfail(result, "Setting external authid", NULL);
+            }
+        }
+          
+        result = sasl_setprop(client_conn,
+                           SASL_SEC_PROPS,
+                           &secprops);
+
+        if (result != SASL_OK) {
+            saslfail(result, "Setting security properties", NULL);
+        }
+
+        /* This will use getopt callback, which is using the "mech" global variable */
+        result = sasl_listmech(client_conn,
+                           ext_authid,
+                           NULL,
+                           " ",
+                           NULL,
+                           &available_mechs,
+                           &len,
+                           &count);
+        if (result != SASL_OK) {
+            saslfail(result, "Setting security properties", NULL);
+        }
+
+        if (count > 0) {
+           list_of_client_mechs = NULL;
+
+           sasl_client_plugin_info (NULL,  /* list all SASL mechanisms */
+                               &list_installed_client_mechanisms,
+                               (void *) &list_of_client_mechs);
+
+           printf ("Installed SASL (client side) mechanisms are:\n%s\n", list_of_client_mechs);
+
+           free (list_of_client_mechs);
+
+
+           /* Dump information about the requested SASL mechanism */
+               /* NOTE - available_mechs must not be freed */
+           sasl_client_plugin_info (available_mechs, NULL, NULL);
+        } else {
+           printf ("No client side SASL mechanisms installed\n");
+        }
+    }
+
+    free_conn();
+    /* Call sasl_done twice - one for the client side SASL and
+       one for the server side. */
+    sasl_done();
+    sasl_done();
+
+#ifdef WIN32
+    WSACleanup();
+#endif
+
+    return (EXIT_SUCCESS);
+}
diff --git a/utils/sasldblistusers.c b/utils/sasldblistusers.c
new file mode 100644 (file)
index 0000000..a28bc84
--- /dev/null
@@ -0,0 +1,198 @@
+/* sasldblistusers.c -- list users in sasldb
+ * $Id: sasldblistusers.c,v 1.22 2003/10/03 20:30:14 rjs3 Exp $
+ * Rob Siemborski
+ * Tim Martin
+ */
+/* 
+ * 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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sasl.h>
+#include "../sasldb/sasldb.h"
+
+#ifdef WIN32
+#include <saslutil.h>
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+#endif
+
+/* Cheating to make the utils work out right */
+LIBSASL_VAR const sasl_utils_t *sasl_global_utils;
+
+char *sasldb_path = SASL_DB_PATH;
+const char *progname = NULL;
+
+int good_getopt(void *context __attribute__((unused)), 
+               const char *plugin_name __attribute__((unused)), 
+               const char *option,
+               const char **result,
+               unsigned *len)
+{
+    if (sasldb_path && !strcmp(option, "sasldb_path")) {
+       *result = sasldb_path;
+       if (len)
+           *len = strlen(sasldb_path);
+       return SASL_OK;
+    }
+
+    return SASL_FAIL;
+}
+
+static struct sasl_callback goodsasl_cb[] = {
+    { SASL_CB_GETOPT, &good_getopt, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int main(int argc, char **argv)
+{
+    int c;
+    int result;
+    sasl_conn_t *conn;
+    int bad_option = 0;
+    int display_usage = 0;
+    const char *sasl_implementation;
+    int libsasl_version;
+    int libsasl_major;
+    int libsasl_minor;
+    int libsasl_step;
+
+    if (! argv[0])
+       progname = "sasldblistusers2";
+    else {
+       progname = strrchr(argv[0], HIER_DELIMITER);
+       if (progname)
+           progname++;
+       else
+           progname = argv[0];
+    }
+
+    /* A single parameter not starting with "-" denotes sasldb to use */
+    if ((argc == 2) && argv[1][0] != '-') {
+       sasldb_path = argv[1];
+       goto START_WORK;
+    }
+
+    while ((c = getopt(argc, argv, "vf:h?")) != EOF) {
+       switch (c) {
+         case 'f':
+          sasldb_path = optarg;
+          break;
+         case 'h':
+           bad_option = 0;
+            display_usage = 1;
+           break;
+        case 'v':
+          sasl_version (&sasl_implementation, &libsasl_version);
+          libsasl_major = libsasl_version >> 24;
+          libsasl_minor = (libsasl_version >> 16) & 0xFF;
+          libsasl_step = libsasl_version & 0xFFFF;
+
+          (void)fprintf(stderr, "\nThis product includes software developed by Computing Services\n"
+               "at Carnegie Mellon University (http://www.cmu.edu/computing/).\n\n"
+               "Built against SASL API version %u.%u.%u\n"
+               "LibSasl version %u.%u.%u by \"%s\"\n",
+               SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
+               libsasl_major, libsasl_minor, libsasl_step, sasl_implementation);
+          exit(0);
+          break;
+
+         default:
+           bad_option = 1;
+            display_usage = 1;
+            break;
+       }
+    }
+
+    if (optind != argc)
+       display_usage = 1;
+
+    if (display_usage) {
+           fprintf(stderr,
+             "\nThis product includes software developed by Computing Services\n"
+             "at Carnegie Mellon University (http://www.cmu.edu/computing/).\n\n");
+
+           fprintf(stderr, "%s: usage: %s [-v] [[-f] sasldb]\n",
+                  progname, progname);
+           fprintf(stderr, "\t-f sasldb\tuse given file as sasldb\n"
+                           "\t-v\tprint version numbers and exit\n");
+       if (bad_option) {
+           fprintf(stderr, "Unrecognized command line option\n");
+       }
+       return 1;
+    }
+START_WORK:
+    result = sasl_server_init(goodsasl_cb, "sasldblistusers");
+    if(result != SASL_OK) {
+       fprintf(stderr, "Couldn't initialize server API\n");
+       return 1;
+    }
+    
+    result = sasl_server_new("sasldb",
+                            "localhost",
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            0,
+                            &conn);
+
+    if(_sasl_check_db(sasl_global_utils, conn) != SASL_OK) {
+       fprintf(stderr, "check_db unsuccessful\n");
+       return 1;
+    }
+
+    if(_sasldb_listusers (sasl_global_utils, conn, NULL, NULL) != SASL_OK) {
+       fprintf(stderr, "listusers failed\n");
+    }
+
+    sasl_dispose(&conn);
+    sasl_done();
+
+    return 0;
+}
diff --git a/utils/sasldblistusers2.8 b/utils/sasldblistusers2.8
new file mode 100644 (file)
index 0000000..a6bedd7
--- /dev/null
@@ -0,0 +1,68 @@
+.\" sasldblistusers - List users in sasldb file
+.\" Tim Martin 3/8/00
+.\"
+
+.\" Copyright (c) 2000 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.
+
+.\"
+.TH SASLDBLISTUSERS2 8 "March 7, 2005" "CMU SASL"
+.SH NAME
+sasldblistusers2 \- list users in sasldb
+.SH SYNOPSIS
+.B sasldblistusers2
+.RB [ -f\ file ]
+.RB [ -v ]
+.SH DESCRIPTION
+.I sasldblistusers2
+is used to list the users in the SASL password database (usually
+/etc/sasldb2). This will NOT list all the users in /etc/passwd, shadow,
+PAM, etc. only those created by SASL (via \fIsaslpasswd2\fR).
+.SH OPTIONS
+.TP
+.B -f file
+use
+.B file
+for sasldb
+.TP
+.B -v
+Print libsasl2 version number and exit.
+.SH SEE ALSO
+saslpasswd2(8)
+.TP
+rfc2222 \- Simple Authentication and Security Layer (SASL)
diff --git a/utils/saslpasswd.c b/utils/saslpasswd.c
new file mode 100644 (file)
index 0000000..6afe425
--- /dev/null
@@ -0,0 +1,454 @@
+/* saslpasswd.c -- SASL password setting program
+ * Rob Earhart
+ */
+/* 
+ * 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.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <assert.h>
+
+#ifndef WIN32
+#include <termios.h>
+#include <unistd.h>
+
+/* perror can't be used on Windows system calls, so we define a new macro to underline this */
+#define        p_oserror(str)      perror(str)
+
+#else /* WIN32 */
+
+#include <stdio.h>
+#include <io.h>
+
+#include <saslutil.h>
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+
+/* perror can't be used on Windows system calls, so we define a new macro to underline this */
+void p_oserror (const char *string);
+#endif /*WIN32*/
+
+#include <sasl.h>
+#include <saslplug.h>
+
+char myhostname[1025];
+
+#define PW_BUF_SIZE 2048
+
+static const char build_ident[] = "$Build: saslpasswd " PACKAGE "-" VERSION " $";
+
+const char *progname = NULL;
+char *sasldb_path = NULL;
+
+#ifdef WIN32
+
+/* This is almost like _plug_get_error_message(), but uses malloc */
+char * _get_error_message (
+   DWORD error
+)
+{
+    char * return_value;
+    LPVOID lpMsgBuf;
+
+    FormatMessage( 
+       FORMAT_MESSAGE_ALLOCATE_BUFFER | 
+       FORMAT_MESSAGE_FROM_SYSTEM | 
+       FORMAT_MESSAGE_IGNORE_INSERTS,
+       NULL,
+       error,
+       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+       (LPTSTR) &lpMsgBuf,
+       0,
+       NULL 
+    );
+
+    return_value = strdup (lpMsgBuf);
+
+    LocalFree( lpMsgBuf );
+    return (return_value);
+}
+
+/* perror() like function that works on OS error codes returned by GetLastError() */
+void p_oserror (
+    const char *message
+)
+{
+/* Try to match perror() behaviour:
+    string is printed first, followed by a colon, then by the system error message
+    for the last library call that produced the error, and finally by a newline
+    character. If string is a null pointer or a pointer to a null string, perror
+    prints only the system error message.
+ */
+    if (message && *message) {
+       fprintf (stderr, "%s: %s\n", message, _get_error_message(GetLastError()));
+    } else {
+       fprintf (stderr, "%s\n", _get_error_message(GetLastError()));
+    }
+}
+#endif /* WIN32 */
+
+void read_password(const char *prompt,
+                  int flag_pipe,
+                  char ** password,
+                  unsigned *passlen)
+{
+  char buf[PW_BUF_SIZE];
+#ifndef WIN32
+  struct termios ts, nts;
+  ssize_t n_read;
+#else
+  HANDLE hStdin;
+  DWORD n_read, fdwMode, fdwOldMode;
+  hStdin = GetStdHandle(STD_INPUT_HANDLE);
+  if (hStdin == INVALID_HANDLE_VALUE) {
+         p_oserror(progname);
+         exit(-(SASL_FAIL));
+  }
+#endif /*WIN32*/
+
+  if (! flag_pipe) {
+    fputs(prompt, stdout);
+    fflush(stdout);
+#ifndef WIN32
+    tcgetattr(STDIN_FILENO, &ts);
+    nts = ts;
+    nts.c_lflag &= ~(ECHO | ECHOE | ECHOK
+#ifdef ECHOCTL
+    | ECHOCTL
+#endif
+#ifdef ECHOPRT
+    | ECHOPRT
+#endif
+#ifdef ECHOKE
+    | ECHOKE
+#endif
+    );
+    nts.c_lflag |= ICANON | ECHONL;
+    tcsetattr(STDIN_FILENO, TCSAFLUSH, &nts);
+#else
+  if (! GetConsoleMode(hStdin, &fdwOldMode)) {
+         p_oserror(progname);
+         exit(-(SASL_FAIL));
+  }
+  fdwMode = fdwOldMode & ~ENABLE_ECHO_INPUT;
+  if (! SetConsoleMode(hStdin, fdwMode)) {
+         p_oserror(progname);
+         exit(-(SASL_FAIL));
+  }
+#endif /*WIN32*/
+  }
+
+#ifndef WIN32
+  n_read = read(STDIN_FILENO, buf, PW_BUF_SIZE);
+  if (n_read < 0) {
+#else
+  if (! ReadFile(hStdin, buf, PW_BUF_SIZE, &n_read, NULL)) {
+#endif /*WIN32*/
+
+    p_oserror(progname);
+    exit(-(SASL_FAIL));
+  }
+
+  if (! flag_pipe) {
+#ifndef WIN32
+    tcsetattr(STDIN_FILENO, TCSANOW, &ts);
+    if (0 < n_read && buf[n_read - 1] != '\n') {
+      /* if we didn't end with a \n, echo one */
+      putchar('\n');
+      fflush(stdout);
+    }
+#else
+       SetConsoleMode(hStdin, fdwOldMode);
+    putchar('\n');
+    fflush(stdout);
+#endif /*WIN32*/
+  }
+
+  if (0 < n_read && buf[n_read - 1] == '\n') /* if we ended with a \n */
+    n_read--;                               /* remove it */
+
+#ifdef WIN32
+  /*WIN32 will have a CR in the buffer also*/
+  if (0 < n_read && buf[n_read - 1] == '\r') /* if we ended with a \r */
+    n_read--;                               /* remove it */
+#endif /*WIN32*/
+
+  *password = malloc(n_read + 1);
+  if (! *password) {
+/* Can use perror() here even on Windows, as malloc is in std C library */
+    perror(progname);
+    exit(-(SASL_FAIL));
+  }
+
+  memcpy(*password, buf, n_read);
+  (*password)[n_read] = '\0';  /* be nice... */
+  *passlen = n_read;
+}
+
+void exit_sasl(int result, const char *errstr) __attribute__((noreturn));
+
+void
+exit_sasl(int result, const char *errstr)
+{
+  (void)fprintf(stderr, errstr ? "%s: %s: %s\n" : "%s: %s\n",
+               progname,
+               sasl_errstring(result, NULL, NULL),
+               errstr);
+  exit(result < 0 ? -result : result);
+}
+
+int good_getopt(void *context __attribute__((unused)), 
+               const char *plugin_name __attribute__((unused)), 
+               const char *option,
+               const char **result,
+               unsigned *len)
+{
+    if (sasldb_path && !strcmp(option, "sasldb_path")) {
+       *result = sasldb_path;
+       if (len)
+           *len = strlen(sasldb_path);
+       return SASL_OK;
+    }
+
+    return SASL_FAIL;
+}
+
+static struct sasl_callback goodsasl_cb[] = {
+    { SASL_CB_GETOPT, &good_getopt, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int
+main(int argc, char *argv[])
+{
+  int flag_pipe = 0, flag_create = 0, flag_disable = 0, flag_error = 0;
+  int flag_nouserpass = 0;
+  int c;
+  char *userid, *password, *verify;
+  unsigned passlen, verifylen;
+  const char *errstr = NULL;
+  int result;
+  sasl_conn_t *conn;
+  char *user_domain = NULL;
+  char *appname = "saslpasswd";
+  const char *sasl_implementation;
+  int libsasl_version;
+  int libsasl_major;
+  int libsasl_minor;
+  int libsasl_step;
+
+#ifdef WIN32
+  /* initialize winsock */
+  WSADATA wsaData;
+
+  result = WSAStartup( MAKEWORD(2, 0), &wsaData );
+  if ( result != 0) {
+    exit_sasl(SASL_FAIL, "WSAStartup");
+  }
+#endif
+
+  memset(myhostname, 0, sizeof(myhostname));
+  result = gethostname(myhostname, sizeof(myhostname)-1);
+  if (result == -1) exit_sasl(SASL_FAIL, "gethostname");
+
+  if (! argv[0])
+    progname = "saslpasswd";
+  else {
+    progname = strrchr(argv[0], HIER_DELIMITER);
+    if (progname)
+      progname++;
+    else
+      progname = argv[0];
+  }
+
+  while ((c = getopt(argc, argv, "vpcdnf:u:a:h?")) != EOF)
+    switch (c) {
+    case 'p':
+      flag_pipe = 1;
+      break;
+    case 'c':
+      if (flag_disable)
+       flag_error = 1;
+      else
+       flag_create = 1;
+      break;
+    case 'd':
+      if (flag_create)
+       flag_error = 1;
+      else
+       flag_disable = 1;
+      break;
+    case 'n':
+       flag_nouserpass = 1;
+       break;
+    case 'u':
+      user_domain = optarg;
+      break;
+    case 'f':
+      sasldb_path = optarg;
+      break;
+    case 'a':
+      appname = optarg;
+      if (strchr(optarg, '/') != NULL) {
+        (void)fprintf(stderr, "appname must not contain /\n");
+        exit(-(SASL_FAIL));
+      }
+      break;
+    case 'v':
+      sasl_version (&sasl_implementation, &libsasl_version);
+      libsasl_major = libsasl_version >> 24;
+      libsasl_minor = (libsasl_version >> 16) & 0xFF;
+      libsasl_step = libsasl_version & 0xFFFF;
+
+      (void)fprintf(stderr, "\nThis product includes software developed by Computing Services\n"
+        "at Carnegie Mellon University (http://www.cmu.edu/computing/).\n\n"
+        "Built against SASL API version %u.%u.%u\n"
+        "LibSasl version %u.%u.%u by \"%s\"\n",
+        SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
+        libsasl_major, libsasl_minor, libsasl_step, sasl_implementation);
+      exit(0);
+      break;
+    default:
+      flag_error = 1;
+      break;
+    }
+
+  if (optind != argc - 1)
+    flag_error = 1;
+
+  if (flag_error) {
+    (void)fprintf(stderr,
+       "\nThis product includes software developed by Computing Services\n"
+        "at Carnegie Mellon University (http://www.cmu.edu/computing/).\n\n"
+       "%s: usage: %s [-v] [-c [-p] [-n]] [-d] [-a appname] [-f sasldb] [-u DOM] userid\n"
+                 "\t-p\tpipe mode -- no prompt, password read on stdin\n"
+                 "\t-c\tcreate -- ask mechs to create the account\n"
+                 "\t-d\tdisable -- ask mechs to disable/delete the account\n"
+                 "\t-n\tno userPassword -- don't set plaintext userPassword property\n"
+                 "\t  \t                   (only set mechanism-specific secrets)\n"
+                 "\t-f sasldb\tuse given file as sasldb\n"
+                 "\t-a appname\tuse appname as application name\n"
+                 "\t-u DOM\tuse DOM for user domain\n"
+                 "\t-v\tprint version numbers and exit\n",
+                 progname, progname);
+    exit(-(SASL_FAIL));
+  }
+
+  userid = argv[optind];
+
+  result = sasl_server_init(goodsasl_cb, appname);
+  if (result != SASL_OK)
+    exit_sasl(result, NULL);
+
+  result = sasl_server_new("sasldb",
+                          myhostname,
+                          user_domain,
+                          NULL,
+                          NULL,
+                          NULL,
+                          0,
+                          &conn);
+  if (result != SASL_OK)
+    exit_sasl(result, NULL);
+#ifndef WIN32
+  if (! flag_pipe && ! isatty(STDIN_FILENO))
+    flag_pipe = 1;
+#endif /*WIN32*/
+
+  if (!flag_disable) {
+      read_password("Password: ", flag_pipe, &password, &passlen);
+
+      if (! flag_pipe) {
+         read_password("Again (for verification): ", flag_pipe, &verify,
+                 &verifylen);
+         if (passlen != verifylen
+             || memcmp(password, verify, verifylen)) {
+             fprintf(stderr, "%s: passwords don't match; aborting\n", 
+                     progname);
+             exit(-(SASL_BADPARAM));
+         }
+      }
+  }
+
+  result = sasl_setpass(conn,
+                       userid,
+                       password,
+                       passlen,
+                       NULL, 0,
+                       (flag_create ? SASL_SET_CREATE : 0)
+                       | (flag_disable ? SASL_SET_DISABLE : 0)
+                       | (flag_nouserpass ? SASL_SET_NOPLAIN : 0));
+
+  if (result != SASL_OK && !flag_disable)
+      exit_sasl(result, NULL);
+  else {
+      struct propctx *propctx = NULL;
+      const char *delete_request[] = { "cmusaslsecretCRAM-MD5",
+                                      "cmusaslsecretDIGEST-MD5",
+                                      "cmusaslsecretPLAIN",
+                                      NULL };
+      int ret = SASL_OK;
+      /* Either we were setting and succeeded or we were disabling and
+        failed.  In either case, we want to wipe old entries */
+
+      /* Delete the possibly old entries */
+      /* We don't care if these fail */
+      propctx = prop_new(0);
+      if (!propctx) ret = SASL_FAIL;
+      if (!ret) ret = prop_request(propctx, delete_request);
+      if (!ret) {
+         ret = prop_set(propctx, "cmusaslsecretCRAM-MD5", NULL, 0);
+         ret = prop_set(propctx, "cmusaslsecretDIGEST-MD5", NULL, 0);
+         ret = prop_set(propctx, "cmusaslsecretPLAIN", NULL, 0);
+         ret = sasl_auxprop_store(conn, propctx, userid);
+      }
+      if (propctx) prop_dispose(&propctx);
+  }
+      
+  if (result != SASL_OK)
+/* errstr is currently always NULL */
+    exit_sasl(result, errstr);
+
+  sasl_dispose(&conn);
+  sasl_done();
+
+  return 0;
+}
diff --git a/utils/saslpasswd2.8 b/utils/saslpasswd2.8
new file mode 100644 (file)
index 0000000..8b0a8d1
--- /dev/null
@@ -0,0 +1,105 @@
+.\" saslpasswd.8 -- saslpasswd man page
+.\" Rob Earhart
+.\"
+
+.\" Copyright (c) 2000 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.
+
+.\"
+.TH SASLPASSWD2 8 "Mar 7, 2005" "CMU SASL"
+.SH NAME
+saslpasswd2 \- set a user's sasl password
+.SH SYNOPSIS
+.B saslpasswd2
+.RB [ -p ]
+.RB [ -d ]
+.RB [ -c ]
+.RB [ -n ]
+.RB [ -f\ file ]
+.RB [ -u\ domain ]
+.RB [ -a\ appname ]
+.RB [ -v ]
+.B userid
+.SH DESCRIPTION
+.I saslpasswd2
+is used by a server administrator to set a user's sasl password for
+server programs and SASL mechanisms which use the standard libsasl
+database of user secrets.
+.SH OPTIONS
+.TP
+.B -p
+Pipe mode \- saslpasswd2 will neither prompt for the password nor
+verify that it was entered correctly.  This is the default when
+standard input is not a terminal.
+.TP
+.B -c
+Creates an entry for the user if the user doesn't already exist.  This
+is mutually exclusive with the
+.B -d
+(delete user) flag.
+.TP
+.B -d
+Deletes the entry for the user.  This is mutually exclusive with the
+.B -c
+(create user) flag.
+.TP
+.B -n
+Don't set the plaintext \fIuserPassword\fR property for the user.  Only
+mechanism-specific secrets will be set (e.g. OTP, SRP)
+.TP
+.B -u domain
+use
+.B domain
+for user domain (realm).
+.TP
+.B -f file
+use
+.B file
+for sasldb
+.TP
+.B -a appname
+use
+.B appname
+as application name.
+.TP
+.B -v
+Print libsasl2 version number and exit.
+.SH SEE ALSO
+sasldblistusers2(8)
+.TP
+rfc2222 \- Simple Authentication and Security Layer (SASL)
diff --git a/utils/sfsasl.c b/utils/sfsasl.c
new file mode 100644 (file)
index 0000000..431b06c
--- /dev/null
@@ -0,0 +1,129 @@
+#include <config.h>
+#include <stdlib.h>
+#include <sasl.h>
+#include <sfio.h>
+
+/* 
+ * 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.
+ */
+
+
+/* sf discipline to add sasl
+ */
+
+typedef struct _sasldisc
+{
+    Sfdisc_t   disc;
+    sasl_conn_t *conn;
+} Sasldisc_t;
+
+ssize_t sasl_read(Sfio_t *f, Void_t *buf, size_t size, Sfdisc_t *disc)
+{
+    int len, result;
+    const char *outbuf;
+    int outlen;
+    Sasldisc_t *sd = (Sasldisc_t *) disc;
+
+    len = sfrd(f, buf, size, disc);
+
+    if (len <= 0)
+       return len;
+
+    result = sasl_decode(sd->conn, buf, len, &outbuf, &outlen);
+
+    if (result != SASL_OK) {
+       /* eventually, we'll want an exception here */
+       return -1;
+    }
+
+    if (outbuf != NULL) {
+       memcpy(buf, outbuf, outlen);
+    }
+
+    return outlen;
+}
+
+ssize_t sasl_write(Sfio_t *f, const Void_t *buf, size_t size, Sfdisc_t *disc)
+{
+    int result;
+    const char *outbuf;
+    int outlen;
+    Sasldisc_t *sd = (Sasldisc_t *) disc;
+
+    result = sasl_encode(sd->conn, buf, size, &outbuf, &outlen);
+
+    if (result != SASL_OK) {
+       return -1;
+    }
+
+    if (outbuf != NULL) {
+       sfwr(f, outbuf, outlen, disc);
+    }
+
+    return size;
+}
+
+int sfdcsasl(Sfio_t *f, sasl_conn_t *conn)
+{
+    Sasldisc_t *sasl;
+    
+    if (conn == NULL) {
+       /* no need to do anything */
+       return 0;
+    }
+
+    if(!(sasl = (Sasldisc_t*)malloc(sizeof(Sasldisc_t))) )
+       return -1;
+    
+    sasl->disc.readf = sasl_read;
+    sasl->disc.writef = sasl_write;
+    sasl->disc.seekf = NULL;
+    sasl->disc.exceptf = NULL;
+
+    sasl->conn = conn;
+
+    if (sfdisc(f, (Sfdisc_t *) sasl) != (Sfdisc_t *) sasl) {
+       free(sasl);
+       return -1;
+    }
+    
+    return 0;
+}
+
+
diff --git a/utils/sfsasl.h b/utils/sfsasl.h
new file mode 100644 (file)
index 0000000..284ac58
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef SFSASL_H
+#define SFSASL_H
+
+/* 
+ * 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.
+ */
+
+
+#include <sfio.h>
+
+int sfdcsasl(Sfio_t *f, sasl_conn_t *conn);
+
+#endif
diff --git a/utils/smtptest.c b/utils/smtptest.c
new file mode 100644 (file)
index 0000000..6ab7096
--- /dev/null
@@ -0,0 +1,592 @@
+/* smtpauth.c -- authenticate to SMTP server, then give normal protocol
+ *
+ * uses sfio
+ *
+ */
+
+#include <config.h>
+
+#include <sfio.h>
+#include <sfio/stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include <sasl.h>
+#include <saslutil.h>
+
+#include "sfsasl.h"
+
+/* from OS: */
+extern char *getpass();
+extern struct hostent *gethostbyname();
+
+static char *authname = NULL;
+static char *username = NULL;
+static char *realm = NULL;
+
+extern char *optarg;
+extern int optind;
+
+int verbose = 0;
+int emacs = 0;
+
+int iptostring(const struct sockaddr *addr, socklen_t addrlen,
+                    char *out, unsigned outlen) {
+    char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
+    int niflags;
+
+    if(!addr || !out) return SASL_BADPARAM;
+
+    niflags = (NI_NUMERICHOST | NI_NUMERICSERV);
+#ifdef NI_WITHSCOPEID
+    if (addr->sa_family == AF_INET6)
+       niflags |= NI_WITHSCOPEID;
+#endif
+    if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf),
+                   niflags) != 0)
+       return SASL_BADPARAM;
+
+    if(outlen < strlen(hbuf) + strlen(pbuf) + 2)
+       return SASL_BUFOVER;
+
+    snprintf(out, outlen, "%s;%s", hbuf, pbuf);
+
+    return SASL_OK;
+}
+
+void usage(char *p)
+{
+    fprintf(stderr, "%s [-v] [-l] [-u username] [-a authname] [-s ssf] [-m mech] host[:port]\n", p);
+    fprintf(stderr, " -v\tVerbose Output\n");
+    fprintf(stderr, " -l\tLMTP semantics\n");
+    exit(EX_USAGE);
+}
+
+#define ISGOOD(r) (((r) / 100) == 2)
+#define TEMPFAIL(r) (((r) / 100) == 4)
+#define PERMFAIL(r) (((r) / 100) == 5)
+#define ISCONT(s) (s && (s[3] == '-'))
+
+static int ask_code(const char *s)
+{
+    int ret = 0;
+    
+    if (s==NULL) return -1;
+
+    if (strlen(s) < 3) return -1;
+
+    /* check to make sure 0-2 are digits */
+    if ((isdigit((int) s[0])==0) ||
+       (isdigit((int) s[1])==0) ||
+       (isdigit((int) s[2])==0))
+    {
+       return -1;
+    }
+
+    ret = ((s[0]-'0')*100)+((s[1]-'0')*10)+(s[2]-'0');
+    
+    return ret;
+}
+
+static void chop(char *s)
+{
+    char *p;
+
+    assert(s);
+    p = s + strlen(s) - 1;
+    if (p[0] == '\n') {
+       *p-- = '\0';
+    }
+    if (p >= s && p[0] == '\r') {
+       *p-- = '\0';
+    }
+}
+
+void interaction (int id, const char *prompt,
+                 char **tresult, unsigned int *tlen)
+{
+    char result[1024];
+    
+    if (id==SASL_CB_PASS) {
+       fprintf(stderr, "%s: ", prompt);
+       *tresult = strdup(getpass("")); /* leaks! */
+       *tlen=   strlen(*tresult);
+       return;
+    } else if (id==SASL_CB_USER) {
+       if (username != NULL) {
+           strcpy(result, username);
+       } else {
+           strcpy(result, getpwuid(getuid())->pw_name);
+       }
+    } else if (id==SASL_CB_AUTHNAME) {
+       if (authname != NULL) {
+           strcpy(result, authname);
+       } else {
+           strcpy(result, getpwuid(getuid())->pw_name);
+       }
+    } else if ((id==SASL_CB_GETREALM) && (realm != NULL)) {
+      strcpy(result, realm);
+    } else {
+       int c;
+       
+       fprintf(stderr, "%s: ",prompt);
+       fgets(result, sizeof(result) - 1, stdin);
+       c = strlen(result);
+       result[c - 1] = '\0';
+    }
+
+    *tlen = strlen(result);
+    *tresult = (char *) malloc(*tlen+1); /* leaks! */
+    memset(*tresult, 0, *tlen+1);
+    memcpy((char *) *tresult, result, *tlen);
+}
+
+void fillin_interactions(sasl_interact_t *tlist)
+{
+    while (tlist->id != SASL_CB_LIST_END)
+    {
+       interaction(tlist->id, tlist->prompt,
+                   (void *) &(tlist->result), 
+                   &(tlist->len));
+       tlist++;
+    }
+}
+
+static sasl_callback_t callbacks[] = {
+    { SASL_CB_GETREALM, NULL, NULL }, 
+    { SASL_CB_USER, NULL, NULL }, 
+    { SASL_CB_AUTHNAME, NULL, NULL }, 
+    { SASL_CB_PASS, NULL, NULL }, 
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+static sasl_security_properties_t *make_secprops(int min,int max)
+{
+    sasl_security_properties_t *ret=(sasl_security_properties_t *)
+       malloc(sizeof(sasl_security_properties_t));
+
+    ret->maxbufsize = 8192;
+    ret->min_ssf = min;
+    ret->max_ssf = max;
+
+    ret->security_flags = 0;
+    ret->property_names = NULL;
+    ret->property_values = NULL;
+
+    return ret;
+}
+
+Sfio_t *debug;
+
+int main(int argc, char **argv)
+{
+    char *mechlist = NULL;
+    const char *mechusing = NULL;
+    int minssf = 0, maxssf = 128;
+    char *p;
+    Sfio_t *server_in, *server_out;
+    sasl_conn_t *conn = NULL;
+    sasl_interact_t *client_interact = NULL;
+    char in[4096];
+    const char *out;
+    unsigned int inlen, outlen;
+    char out64[4096];
+    int c;
+
+    char *host;
+    struct servent *service;
+    int port;
+    struct hostent *hp;
+    struct sockaddr_in addr;
+    char remote_ip[64], local_ip[64];
+    int sock;
+
+    char buf[1024];
+    int sz;
+    char greeting[1024];
+    int code;
+    int do_lmtp=0;
+    int r = 0;
+
+    debug = stderr;
+
+    while ((c = getopt(argc, argv, "vElm:s:u:a:d:")) != EOF) {
+       switch (c) {
+       case 'm':
+           mechlist = optarg;
+           break;
+
+       case 'l':
+           do_lmtp = 1;
+           break;
+
+       case 's':
+           maxssf = atoi(optarg);
+           break;
+           
+       case 'u':
+           username = optarg;
+           break;
+
+       case 'a':
+           authname = optarg;
+           break;
+
+       case 'v':
+           verbose++;
+           break;
+           
+       case 'E':
+           emacs++;
+           break;
+
+       case 'd':
+           sprintf(buf, "%s-%d", optarg, getpid());
+           debug = sfopen(NULL, buf, "w");
+           sfsetbuf(debug, NULL, 0);
+           break;
+
+       case '?':
+       default:
+           usage(argv[0]);
+           break;
+       }
+    }
+
+    if (optind != argc - 1) {
+       usage(argv[0]);
+    }
+
+    host = argv[optind];
+    p = strchr(host, ':');
+    if (p) {
+       *p++ = '\0';
+    } else {
+       if(do_lmtp) {
+           p = "lmtp";
+       } else {
+           p = "smtp";
+       }
+    }
+    service = getservbyname(p, "tcp");
+    if (service) {
+       port = service->s_port;
+    } else {
+       port = atoi(p);
+       if (!port) usage(argv[0]);
+       port = htons(port);
+    }
+
+    if ((hp = gethostbyname(host)) == NULL) {
+       perror("gethostbyname");
+       exit(EX_NOHOST);
+    }
+
+    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+       perror("socket");
+       exit(EX_OSERR);
+    }
+
+    addr.sin_family = AF_INET;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = port;
+
+    if (connect(sock, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
+       perror("connect");
+       exit(EX_NOHOST);
+    }
+
+    server_in = sfnew(NULL, NULL, SF_UNBOUND, sock, SF_READ);
+    server_out = sfnew(NULL, NULL, SF_UNBOUND, sock, SF_WRITE);
+
+    /* read greeting */
+    greeting[0] = '\0';
+    for (;;) {
+       sfsync(server_out);
+       if (fgets(buf, sizeof(buf)-1, server_in)) {
+           if (greeting[0] == '\0') {
+               strncpy(greeting, buf, sizeof(greeting) - 1);
+           }
+
+           if (verbose) fprintf(debug, "%s", buf);
+           code = ask_code(buf);
+           if (ISCONT(buf) && ISGOOD(code)) continue;
+       } else {
+           code = 400;
+       }
+       break;
+    }
+
+    if (!ISGOOD(code)) goto done;
+
+    /* EHLO */
+    gethostname(buf, sizeof(buf)-1);
+    if(do_lmtp) {
+       if(verbose) fprintf(debug, "LHLO %s\r\n", buf);
+       fprintf(server_out, "LHLO %s\r\n", buf);
+    } else {
+       if (verbose) fprintf(debug, "EHLO %s\r\n", buf);
+       fprintf(server_out, "EHLO %s\r\n", buf);
+    }
+    
+    /* read responses */
+    for (;;) {
+       sfsync(server_out);
+       if (!fgets(buf, sizeof(buf)-1, server_in)) {
+           code = 400;
+           goto done;
+       }
+       if (verbose) fprintf(debug, "%s", buf);
+       code = ask_code(buf);
+       if (code == 250) {
+           /* we're only looking for AUTH */
+           if (!strncasecmp(buf + 4, "AUTH ", 5)) {
+               chop(buf);
+               if (!mechlist) mechlist = strdup(buf + 9);
+           }
+       }
+       if (ISCONT(buf) && ISGOOD(code)) {
+           continue;
+       } else {
+           break;
+       }
+    }
+    if (!ISGOOD(code)) goto done;
+
+    /* attempt authentication */
+    if (!mechlist) {
+       if (verbose > 2) fprintf(debug, "no authentication\n");
+       goto doneauth;
+    }
+
+    if (!r) r = sasl_client_init(callbacks);
+    if (!r) {
+       struct sockaddr_in saddr_r;
+       int addrsize = sizeof(struct sockaddr_in);
+
+       if (getpeername(sock, (struct sockaddr *) &saddr_r, &addrsize) < 0) {
+           perror("getpeername");
+           exit(EX_NOHOST);
+       }
+       r = iptostring((struct sockaddr *)&saddr_r,
+                      sizeof(struct sockaddr_in), remote_ip, 64);
+    }
+    if (!r) {
+       struct sockaddr_in saddr_l;
+       int addrsize = sizeof(struct sockaddr_in);
+
+       if (getsockname(sock, (struct sockaddr *) &saddr_l, &addrsize) < 0) {
+           perror("getsockname");
+           exit(EX_OSERR);
+       }
+       r = iptostring((struct sockaddr *)&saddr_l,
+                      sizeof(struct sockaddr_in), local_ip, 64);
+    }
+
+    if (!r) {
+       if(do_lmtp) {
+           r = sasl_client_new("lmtp", host, local_ip, remote_ip,
+                               NULL, 0, &conn);
+       } else {
+           r = sasl_client_new("smtp", host, local_ip, remote_ip,
+                               NULL, 0, &conn);
+       }
+    }
+    
+    if (!r) {
+       sasl_security_properties_t *secprops = make_secprops(minssf, maxssf);
+       r = sasl_setprop(conn, SASL_SEC_PROPS, secprops);
+       free(secprops);
+    }
+    
+    if (!r) {
+       do {
+           r = sasl_client_start(conn, mechlist,
+                                 &client_interact, &out, &outlen, &mechusing);
+           if (r == SASL_INTERACT) {
+               fillin_interactions(client_interact);
+           }
+       } while (r == SASL_INTERACT);
+
+       if (r == SASL_OK || r == SASL_CONTINUE) {
+           if (outlen > 0) {
+               r = sasl_encode64(out, outlen, out64, sizeof out64, NULL);
+               if (!r) {
+                   if (verbose) 
+                       fprintf(debug, "AUTH %s %s\r\n", mechusing, out64);
+                   fprintf(server_out, "AUTH %s %s\r\n", mechusing, out64);
+               }
+           } else {
+               if (verbose) fprintf(debug, "AUTH %s\r\n", mechusing);
+               fprintf(server_out, "AUTH %s\r\n", mechusing);
+           }
+       } else {
+           fprintf(debug, "\nclient start failed: %s\n", sasl_errdetail(conn));
+       }
+       
+    }
+
+    /* jump to doneauth if we succeed */
+    while (r == SASL_OK || r == SASL_CONTINUE) {
+       sfsync(server_out);
+       if (!fgets(buf, sizeof(buf)-1, server_in)) {
+           code = 400;
+           goto done;
+       }
+       if (verbose) fprintf(debug, "%s", buf);
+       code = ask_code(buf);
+       if (ISCONT(buf)) continue;
+       if (ISGOOD(code)) {
+           if (code != 235) {
+               /* weird! */
+           }
+           /* yay, we won! */
+           sfdcsasl(server_in, conn);
+           sfdcsasl(server_out, conn);
+           goto doneauth;
+       } else if (code != 334) {
+           /* unexpected response */
+           break;
+       }
+       r = sasl_decode64(buf + 4, strlen(buf) - 6, in, 4096, &inlen);
+       if (r != SASL_OK) break;
+       
+       do {
+           r = sasl_client_step(conn, in, inlen, &client_interact,
+                                &out, &outlen);
+           if (r == SASL_INTERACT) {
+               fillin_interactions(client_interact);
+           }
+       } while (r == SASL_INTERACT);
+
+       if (r == SASL_OK || r == SASL_CONTINUE) {
+           r = sasl_encode64(out, outlen, out64, sizeof out64, NULL);
+       }
+       if (r == SASL_OK) {
+           if (verbose) fprintf(debug, "%s\r\n", out64);
+           fprintf(server_out, "%s\r\n", out64);
+       }
+    }
+
+    /* auth failed! */
+    if (!r) {
+       fprintf(debug, "%d authentication failed\n", code);
+    } else {
+       fprintf(debug, "400 authentication failed: %s\n", 
+               sasl_errstring(r, NULL, NULL));
+    }
+    exit(EX_SOFTWARE);
+
+ doneauth:
+    /* ready for application */
+    greeting[3] = '-';
+    printf("%s", greeting);
+    printf("220 %s %s\r\n", host, conn ? "authenticated" : "no auth");
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+    fcntl(sock, F_SETFL, O_NONBLOCK);
+    sfset(stdin, SF_SHARE, 0);
+
+    /* feed data back 'n forth */
+    for (;;) {
+       Sfio_t *flist[3];
+
+    top:
+       flist[0] = stdin;
+       flist[1] = server_in;
+
+       /* sfpoll */
+       if (verbose > 5) fprintf(debug, "poll\n");
+       r = sfpoll(flist, 2, -1);
+       if (verbose > 5) fprintf(debug, "poll 2\n");
+
+       while (r--) {
+           if (flist[r] == server_in) {
+               do {
+                   if (verbose > 5) fprintf(debug, "server!\n");
+                   errno = 0;
+                   sz = sfread(server_in, buf, sizeof(buf)-1);
+                   if (sz == 0 && (errno == EAGAIN)) goto top;
+                   if (sz <= 0) goto out;
+                   buf[sz] = '\0';
+                   if (verbose > 5) fprintf(debug, "server 2 '%s'!\n", buf);
+                   sfwrite(stdout, buf, sz);
+               } while (sfpoll(&server_in, 1, 0));
+               sfsync(stdout);
+           } else if (flist[r] == stdin) {
+               Sfio_t *p[1];
+
+               p[0] = stdin;
+               do {
+                   if (verbose > 5) fprintf(debug, "stdin!\n");
+                   errno = 0;
+                   sz = sfread(stdin, buf, sizeof(buf)-1);
+                   if (sz == 0 && (errno == EAGAIN)) goto top;
+                   if (sz <= 0) goto out;
+                   buf[sz] = '\0';
+                   if (verbose > 5) fprintf(debug, "stdin 2 '%s'!\n", buf);
+                   if (emacs) {
+                       int i;
+
+                       /* fix emacs stupidness */
+                       for (i = 0; i < sz - 1; i++) {
+                           if (buf[i] == '\n' && buf[i+1] == '\n')
+                               buf[i++] = '\r';
+                       }
+                       if (buf[sz-2] != '\r' && buf[sz-1] == '\n') {
+                           sfungetc(stdin, buf[sz--]);
+                           buf[sz] = '\0';
+                       }
+
+                       if (verbose > 5) fprintf(debug, "emacs '%s'!\n", buf);
+                   }
+                   sfwrite(server_out, buf, sz);
+                   if (verbose > 7) fprintf(debug, "stdin 3!\n");
+               } while (sfpoll(p, 1, 0));
+               sfsync(server_out);
+           } else {
+               abort();
+           }
+       }
+    }
+ out:
+    if (verbose > 3) fprintf(debug, "exiting! %d %s\n", sz, strerror(errno));
+    exit(EX_OK);
+
+ done:
+    if (ISGOOD(code)) {
+       if (verbose > 1) fprintf(debug, "ok\n");
+       exit(EX_OK);
+    }
+    if (TEMPFAIL(code)) {
+       if (verbose > 1) fprintf(debug, "tempfail\n");
+       exit(EX_TEMPFAIL);
+    }
+    if (PERMFAIL(code)) {
+       if (verbose > 1) fprintf(debug, "permfail\n");
+       exit(EX_UNAVAILABLE);
+    }
+    
+    if (verbose > 1) fprintf(debug, "unknown failure\n");
+    exit(EX_TEMPFAIL);
+}
diff --git a/utils/testsuite.c b/utils/testsuite.c
new file mode 100644 (file)
index 0000000..68aa342
--- /dev/null
@@ -0,0 +1,3128 @@
+/* testsuite.c -- Stress the library a little
+ * Rob Siemborski
+ * Tim Martin
+ * $Id: testsuite.c,v 1.46 2006/04/25 14:39:04 mel 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.
+ */
+
+/*
+ * To create a krb5 srvtab file given a krb4 srvtab
+ *
+ * ~/> ktutil
+ * ktutil:  rst /etc/srvtab
+ * ktutil:  wkt /etc/krb5.keytab
+ * ktutil:  q
+ */
+
+/*
+ * TODO [FIXME]:
+ *  put in alloc() routines that fail occasionally.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sasl.h>
+#include <saslutil.h>
+#include <prop.h>
+#include <md5global.h>
+#include <md5.h>
+#include <hmac-md5.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <time.h>
+#include <string.h>
+#include <ctype.h>
+#ifndef WIN32
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/file.h>
+#endif
+
+#ifdef WIN32
+__declspec(dllimport) char *optarg;
+__declspec(dllimport) int optind;
+__declspec(dllimport) int getsubopt(char **optionp, char * const *tokens, char **valuep);
+#endif
+
+char myhostname[1024+1];
+#define MAX_STEPS 7 /* maximum steps any mechanism takes */
+
+#define CLIENT_TO_SERVER "Hello. Here is some stuff"
+
+#define REALLY_LONG_LENGTH  32000
+#define REALLY_LONG_BACKOFF  2000
+
+const char *username = "murch";
+const char *nonexistant_username = "ABCDEFGHIJ";
+const char *authname = "murch";
+const char *proxyasname = "murchproxy";
+const char *password = "1234";
+sasl_secret_t * g_secret = NULL;
+const char *cu_plugin = "INTERNAL";
+char other_result[1024];
+
+int proxyflag = 0;
+
+static const char *gssapi_service = "host";
+
+/* our types of failures */
+typedef enum {
+    NOTHING = 0,
+    ONEBYTE_RANDOM,            /* replace one byte with something random */
+    ONEBYTE_NULL,              /* replace one byte with a null */
+    ONEBYTE_QUOTES,            /* replace one byte with a double quote 
+                                  (try to fuck with digest-md5) */
+    ONLY_ONE_BYTE,             /* send only one byte */
+    ADDSOME,                   /* add some random bytes onto the end */
+    SHORTEN,                   /* shorten the string some */
+    REASONABLE_RANDOM,         /* send same size but random */
+    REALLYBIG,                 /* send something absurdly large all random */
+    NEGATIVE_LENGTH,           /* send negative length */
+    CORRUPT_SIZE               /* keep this one last */
+} corrupt_type_t;
+
+const char *corrupt_types[] = {
+    "NOTHING",
+    "ONEBYTE_RANDOM",
+    "ONEBYTE_NULL",
+    "ONEBYTE_QUOTES",
+    "ONLY_ONE_BYTE",
+    "ADDSOME",
+    "SHORTEN",
+    "REASONABLE_RANDOM",
+    "REALLYBIG",
+    "NEGATIVE_LENGTH",
+    "CORRUPT_SIZE"
+};
+
+void fatal(char *str)
+{
+    printf("Failed with: %s\n",str);
+    exit(3);
+}
+
+/* interactions we support */
+static sasl_callback_t client_interactions[] = {
+  {
+    SASL_CB_GETREALM, NULL, NULL
+  }, {
+    SASL_CB_USER, NULL, NULL
+  }, {
+    SASL_CB_AUTHNAME, NULL, NULL
+  }, {
+    SASL_CB_PASS, NULL, NULL    
+  }, {
+    SASL_CB_LIST_END, NULL, NULL
+  }
+};
+
+int test_getrealm(void *context __attribute__((unused)), int id,
+                 const char **availrealms __attribute__((unused)),
+                 const char **result) 
+{
+    if(id != SASL_CB_GETREALM) fatal("test_getrealm not looking for realm");
+    if(!result) return SASL_BADPARAM;
+    *result = myhostname;
+    return SASL_OK;
+}
+
+int test_getsecret(sasl_conn_t *conn __attribute__((unused)),
+                  void *context __attribute__((unused)), int id,
+                  sasl_secret_t **psecret) 
+{
+    if(id != SASL_CB_PASS) fatal("test_getsecret not looking for pass");
+    if(!psecret) return SASL_BADPARAM;
+
+    *psecret = g_secret;
+
+    return SASL_OK;
+}
+
+int test_getsimple(void *context __attribute__((unused)), int id,
+                  const char **result, unsigned *len) 
+{
+    if(!result) return SASL_BADPARAM;
+    
+    if (id==SASL_CB_USER && proxyflag == 0) {
+       *result=(char *) username;
+    } else if (id==SASL_CB_USER && proxyflag == 1) {
+       *result=(char *) proxyasname;
+    } else if (id==SASL_CB_AUTHNAME) {
+       *result=(char *) authname;
+    } else {
+       printf("I want %d\n", id);
+       fatal("unknown callback in test_getsimple");
+    }
+
+    if (len) *len = (unsigned) strlen(*result);
+    return SASL_OK;
+}
+
+/* callbacks we support */
+static sasl_callback_t client_callbacks[] = {
+  {
+    SASL_CB_GETREALM, test_getrealm, NULL
+  }, {
+    SASL_CB_USER, test_getsimple, NULL
+  }, {
+    SASL_CB_AUTHNAME, test_getsimple, NULL
+  }, {
+    SASL_CB_PASS, test_getsecret, NULL    
+  }, {
+    SASL_CB_LIST_END, NULL, NULL
+  }
+};
+
+typedef void *foreach_t(char *mech, void *rock);
+
+typedef struct tosend_s {
+    corrupt_type_t type; /* type of corruption to make */
+    int step; /* step it should send bogus data on */
+    sasl_callback_t *client_callbacks; /* which client callbacks to use */
+} tosend_t;
+
+typedef struct mem_info 
+{
+    void *addr;
+    size_t size;
+    struct mem_info *next;
+} mem_info_t;
+
+int DETAILED_MEMORY_DEBUGGING = 0;
+
+mem_info_t *head = NULL;
+
+#ifndef WITH_DMALLOC
+
+void *test_malloc(size_t size)
+{
+    void *out;
+    mem_info_t *new_data;
+    
+    out = malloc(size);
+
+    if(DETAILED_MEMORY_DEBUGGING)
+       fprintf(stderr, "  %X = malloc(%u)\n", (unsigned)out, (unsigned) size);
+    
+    if(out) {
+       new_data = malloc(sizeof(mem_info_t));
+       if(!new_data) return out;
+
+       new_data->addr = out;
+       new_data->size = size;
+       new_data->next = head;
+       head = new_data;
+    }
+
+    return out;
+}
+
+void *test_realloc(void *ptr, size_t size)
+{
+    void *out;
+    mem_info_t **prev, *cur;
+    
+    out = realloc(ptr, size);
+    
+    if(DETAILED_MEMORY_DEBUGGING)
+       fprintf(stderr, "  %X = realloc(%X,%d)\n",
+               (unsigned)out, (unsigned)ptr, size);
+
+    prev = &head; cur = head;
+    
+    while(cur) {
+       if(cur->addr == ptr) {
+           cur->addr = out;
+           cur->size = size;
+           return out;
+       }
+       
+       prev = &cur->next;
+       cur = cur->next;
+    }
+    
+    if(DETAILED_MEMORY_DEBUGGING && cur == NULL) {
+       fprintf(stderr,
+               "  MEM WARNING: reallocing something we never allocated!\n");
+
+       cur = malloc(sizeof(mem_info_t));
+       if(!cur) return out;
+
+       cur->addr = out;
+       cur->size = size;
+       cur->next = head;
+       head = cur;
+    }
+
+    return out;
+}
+
+void *test_calloc(size_t nmemb, size_t size)
+{
+    void *out;
+    mem_info_t *new_data;
+    
+    out = calloc(nmemb, size);
+
+    if(DETAILED_MEMORY_DEBUGGING)    
+       fprintf(stderr, "  %X = calloc(%d, %d)\n",
+               (unsigned)out, nmemb, size);
+
+    if(out) {
+       new_data = malloc(sizeof(mem_info_t));
+       if(!new_data) return out;
+
+       new_data->addr = out;
+       new_data->size = size;
+       new_data->next = head;
+       head = new_data;
+    }
+    
+    return out;
+}
+
+
+void test_free(void *ptr)
+{
+    mem_info_t **prev, *cur;
+
+    if(DETAILED_MEMORY_DEBUGGING)
+       fprintf(stderr, "  free(%X)\n",
+               (unsigned)ptr);
+
+    prev = &head; cur = head;
+    
+    while(cur) {
+       if(cur->addr == ptr) {
+           *prev = cur->next;
+           free(cur);
+           break;
+       }
+       
+       prev = &cur->next;
+       cur = cur->next;
+    }
+
+    if(DETAILED_MEMORY_DEBUGGING && cur == NULL) {
+       fprintf(stderr,
+               "  MEM WARNING: Freeing something we never allocated!\n");
+    }
+
+    free(ptr);
+}
+
+#endif /* WITH_DMALLOC */
+
+int mem_stat() 
+{
+#ifndef WITH_DMALLOC
+    mem_info_t *cur;
+    size_t n;
+    unsigned char *data;
+
+    if(!head) {
+       fprintf(stderr, "  All memory accounted for!\n");
+       return SASL_OK;
+    }
+    
+    fprintf(stderr, "  Currently Still Allocated:\n");
+    for(cur = head; cur; cur = cur->next) {
+       fprintf(stderr, "    %X (%5d)\t", (unsigned)cur->addr, cur->size);
+       for(data = (unsigned char *) cur->addr,
+               n = 0; n < (cur->size > 12 ? 12 : cur->size); n++) {
+           if (isprint((int) data[n]))
+               fprintf(stderr, "'%c' ", (char) data[n]);
+           else
+               fprintf(stderr, "%02X  ", data[n] & 0xff);
+       }
+       if (n < cur->size)
+           fprintf(stderr, "...");
+       fprintf(stderr, "\n");
+    }
+    return SASL_FAIL;
+#else
+    return SASL_OK;
+#endif /* WITH_DMALLOC */
+}
+
+
+/************* End Memory Allocation functions ******/
+
+/* my mutex functions */
+int g_mutex_cnt = 0;
+
+typedef struct my_mutex_s {
+
+    int num;
+    int val;
+    
+} my_mutex_t;
+
+void *my_mutex_new(void)
+{
+    my_mutex_t *ret = (my_mutex_t *)malloc(sizeof(my_mutex_t));
+    ret->num = g_mutex_cnt;
+    g_mutex_cnt++;
+
+    ret->val = 0;
+
+    return ret;
+}
+
+int my_mutex_lock(my_mutex_t *m)
+{
+    if (m->val != 0)
+    {
+       fatal("Trying to lock a mutex already locked [single-threaded app]");
+    }
+
+    m->val = 1;
+    return SASL_OK;
+}
+
+int my_mutex_unlock(my_mutex_t *m)
+{
+    if (m->val != 1)
+    {
+       fatal("Unlocking mutex that isn't locked");
+    }
+
+    m->val = 0;
+
+    return SASL_OK;
+}
+
+void my_mutex_dispose(my_mutex_t *m)
+{
+    if (m==NULL) return;
+
+    free(m);
+
+    return;
+}
+
+int good_getopt(void *context __attribute__((unused)), 
+               const char *plugin_name __attribute__((unused)), 
+               const char *option,
+               const char **result,
+               unsigned *len)
+{
+    if (strcmp(option,"pwcheck_method")==0)
+    {
+       *result = "auxprop";
+       if (len)
+           *len = (unsigned) strlen("auxprop");
+       return SASL_OK;
+    } else if (!strcmp(option, "auxprop_plugin")) {
+       *result = "sasldb";
+       if (len)
+           *len = (unsigned) strlen("sasldb");
+       return SASL_OK;
+    } else if (!strcmp(option, "sasldb_path")) {
+       *result = "./sasldb";
+       if (len)
+           *len = (unsigned) strlen("./sasldb");
+       return SASL_OK;
+    } else if (!strcmp(option, "canon_user_plugin")) {
+       *result = cu_plugin;
+       if (len)
+           *len = (unsigned) strlen(*result);
+       return SASL_OK;
+    }
+
+    return SASL_FAIL;
+}
+
+static struct sasl_callback goodsasl_cb[] = {
+    { SASL_CB_GETOPT, &good_getopt, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int givebadpath(void * context __attribute__((unused)), 
+               char ** path)
+{
+    int lup;
+    *path = malloc(10000);    
+    strcpy(*path,"/tmp/is/not/valid/path/");
+
+    for (lup = 0;lup<1000;lup++)
+       strcat(*path,"a/");
+
+    return SASL_OK;
+}
+
+static struct sasl_callback withbadpathsasl_cb[] = {
+    { SASL_CB_GETPATH, &givebadpath, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int giveokpath(void * context __attribute__((unused)), 
+               const char ** path)
+{
+    *path = "/tmp/";
+
+    return SASL_OK;
+}
+
+static struct sasl_callback withokpathsasl_cb[] = {
+    { SASL_CB_GETPATH, &giveokpath, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+static struct sasl_callback emptysasl_cb[] = {
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+static int proxy_authproc(sasl_conn_t *conn,
+                          void *context __attribute__((unused)),
+                          const char *requested_user,
+                          unsigned rlen __attribute__((unused)),
+                          const char *auth_identity,
+                          unsigned alen __attribute__((unused)),
+                          const char *def_realm __attribute__((unused)),
+                          unsigned urlen __attribute__((unused)),
+                          struct propctx *propctx __attribute__((unused)))
+{
+    if(!strcmp(auth_identity, authname)
+       && !strcmp(requested_user, proxyasname)) return SASL_OK;
+
+    if(!strcmp(auth_identity, requested_user)) {
+       printf("Warning: Authenticated name but DID NOT proxy (%s/%s)\n",
+              requested_user, auth_identity);
+       return SASL_OK;
+    }
+
+    sasl_seterror(conn, SASL_NOLOG, "authorization failed: %s by %s",
+                 requested_user, auth_identity);
+    return SASL_BADAUTH;
+}
+
+static struct sasl_callback goodsaslproxy_cb[] = {
+    { SASL_CB_PROXY_POLICY, &proxy_authproc, NULL },
+    { SASL_CB_GETOPT, &good_getopt, NULL },
+    { SASL_CB_LIST_END, NULL, NULL }
+};
+
+char really_long_string[REALLY_LONG_LENGTH];
+
+/*
+ * Setup some things for test
+ */
+void init(unsigned int seed)
+{
+    int lup;
+    int result;
+
+    srand(seed);    
+
+    for (lup=0;lup<REALLY_LONG_LENGTH;lup++)
+       really_long_string[lup] = '0' + (rand() % 10);
+
+    really_long_string[REALLY_LONG_LENGTH - rand() % REALLY_LONG_BACKOFF] = '\0';
+
+    result = gethostname(myhostname, sizeof(myhostname)-1);
+    if (result == -1) fatal("gethostname");
+
+    sasl_set_mutex((sasl_mutex_alloc_t *) &my_mutex_new,
+                  (sasl_mutex_lock_t *) &my_mutex_lock,
+                  (sasl_mutex_unlock_t *) &my_mutex_unlock,
+                  (sasl_mutex_free_t *) &my_mutex_dispose);
+
+#ifndef WITH_DMALLOC
+    sasl_set_alloc((sasl_malloc_t *)test_malloc,
+                  (sasl_calloc_t *)test_calloc,
+                  (sasl_realloc_t *)test_realloc,
+                  (sasl_free_t *)test_free);
+#endif
+
+}
+
+/*
+ * Tests for sasl_server_init
+ */
+
+void test_init(void)
+{
+    int result;
+
+    /* sasl_done() before anything */
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after sasl_done test");
+
+    /* Try passing appname a really long string (just see if it crashes it)*/
+
+    result = sasl_server_init(NULL,really_long_string);
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after long appname test");
+
+    /* this calls sasl_done when it wasn't inited */
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after null appname test");
+
+    /* try giving it a different path for where the plugins are */
+    result = sasl_server_init(withokpathsasl_cb, "Tester");
+    if (result!=SASL_OK) fatal("Didn't deal with ok callback path very well");
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after callback path test");
+
+    /* and the client */
+    result = sasl_client_init(withokpathsasl_cb);
+
+    if (result!=SASL_OK)
+       fatal("Client didn't deal with ok callback path very well");
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after client test");
+
+#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
+    /* try giving it an invalid path for where the plugins are */
+    result = sasl_server_init(withbadpathsasl_cb, NULL);
+    if (result==SASL_OK) fatal("Allowed invalid path");
+    sasl_done();
+    if(mem_stat() != SASL_OK) fatal("memory error after bad path test");
+#endif
+
+    /* and the client - xxx is this necessary?*/
+#if 0
+    result = sasl_client_init(withbadpathsasl_cb);
+
+    if (result==SASL_OK)
+       fatal("Client allowed invalid path");
+    sasl_done();
+#endif
+
+    /* Now try to break all the sasl_server_* functions for not returning
+       SASL_NOTINIT */
+
+    if(sasl_global_listmech())
+       fatal("sasl_global_listmech did not return NULL with no library initialized");
+
+    if(sasl_server_new(NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_server_new did not return SASL_NOTINIT");
+
+/* Can't check this validly without a server conn, so this would be
+   a hard one to tickle anyway */
+#if 0    
+    if(sasl_listmech(NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_listmech did not return SASL_NOTINIT");
+#endif
+
+    if(sasl_server_start(NULL, NULL, NULL, 0, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_server_start did not return SASL_NOTINIT");
+
+    if(sasl_server_step(NULL, NULL, 0, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_server_step did not return SASL_NOTINIT");
+    
+#ifdef DO_SASL_CHECKAPOP
+    if(sasl_checkapop(NULL, NULL, 0, NULL, 0)
+       != SASL_NOTINIT)
+       fatal("sasl_checkapop did not return SASL_NOTINIT");
+#endif    
+
+    if(sasl_checkpass(NULL, NULL, 0, NULL, 0)
+       != SASL_NOTINIT)
+       fatal("sasl_checkpass did not return SASL_NOTINIT");
+    
+    if(sasl_user_exists(NULL, NULL, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_user_exists did not return SASL_NOTINIT");
+
+    if(sasl_setpass(NULL, NULL, NULL, 0, NULL, 0, 0)
+       != SASL_NOTINIT)
+       fatal("sasl_setpass did not return SASL_NOTINIT");
+
+    /* And sasl_client_*... */
+
+    if(sasl_client_new(NULL, NULL, NULL, NULL, NULL, 0, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_client_new did not return SASL_NOTINIT");
+
+    if(sasl_client_start(NULL, NULL, NULL, NULL, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_client_start did not return SASL_NOTINIT");
+
+    if(sasl_client_step(NULL, NULL, 0, NULL, NULL, NULL)
+       != SASL_NOTINIT)
+       fatal("sasl_client_step did not return SASL_NOTINIT");
+
+}
+
+
+/* 
+ * Tests sasl_listmech command
+ */
+
+void test_listmech(void)
+{
+    sasl_conn_t *saslconn, *cconn;
+    int result;
+    const char *str = NULL;
+    unsigned int plen;
+    unsigned lup, flag, pcount;
+    const char **list;
+
+    /* test without initializing library */
+    result = sasl_listmech(NULL, /* conn */
+                          NULL,
+                          "[",
+                          "-",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    /*    printf("List mech without library initialized: %s\n",sasl_errstring(result,NULL,NULL));*/
+    if (result == SASL_OK) fatal("Failed sasl_listmech() with NULL saslconn");
+
+    if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
+       fatal("can't sasl_server_init");
+    if (sasl_client_init(client_interactions)!=SASL_OK)
+       fatal("can't sasl_client_init");
+
+    if (sasl_server_new("rcmd", myhostname,
+                       NULL, NULL, NULL, NULL, 0, 
+                       &saslconn) != SASL_OK)
+       fatal("can't sasl_server_new");
+
+    if (sasl_setprop(saslconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
+       fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
+
+    /* client new connection */
+    if (sasl_client_new("rcmd",
+                       myhostname,
+                       NULL, NULL, NULL,
+                       0,
+                       &cconn)!= SASL_OK)
+       fatal("sasl_client_new() failure");
+
+    if (sasl_setprop(cconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
+       fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
+
+    /* try both sides */
+    list = sasl_global_listmech();
+    if(!list) fatal("sasl_global_listmech failure");
+
+    printf(" [");
+    flag = 0;
+    for(lup = 0; list[lup]; lup++) {
+       if(flag) printf(",");
+       else flag++;
+       printf("%s",list[lup]);
+    }
+    printf("]\n");
+
+    /* try client side */
+    result = sasl_listmech(cconn,
+                          NULL,
+                          " [",
+                          ",",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+    if(result == SASL_OK) {
+       printf("Client mechlist:\n%s\n", str);
+    } else {
+       fatal("client side sasl_listmech failed");
+    }
+
+    /* Test with really long user */
+
+    result = sasl_listmech(saslconn,
+                          really_long_string,
+                          "[",
+                          "-",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result != SASL_OK) fatal("Failed sasl_listmech() with long user");
+
+    if (str[0]!='[') fatal("Failed sasl_listmech() with long user (didn't start with '['");
+
+    result = sasl_listmech(saslconn,
+                          really_long_string,
+                          "[",
+                          ",",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result != SASL_OK) fatal("Failed sasl_listmech() with different params");
+
+    printf("We have the following mechs:\n %s\n",str);
+
+    /* Test with really long prefix */
+
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          really_long_string,
+                          "-",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result != SASL_OK) fatal("failed sasl_listmech() with long prefix");
+
+    if (str[0]!=really_long_string[0]) fatal("failed sasl_listmech() with long prefix (str is suspect)");
+
+    /* Test with really long suffix */
+
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          "[",
+                          "-",
+                          really_long_string,
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result != SASL_OK) fatal("Failed sasl_listmech() with long suffix");
+
+    /* Test with really long seperator */
+
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          "[",
+                          really_long_string,
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result != SASL_OK) fatal("Failed sasl_listmech() with long seperator");
+
+    /* Test contents of output string is accurate */
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          "",
+                          "%",
+                          "",
+                          &str,
+                          &plen,
+                          &pcount);
+
+    if (result != SASL_OK) fatal("Failed sasl_listmech()");
+
+    if (strlen(str)!=plen) fatal("Length of string doesn't match what we were told");
+    
+    for (lup=0;lup<plen;lup++)
+       if (str[lup]=='%')
+           pcount--;
+
+    pcount--;
+    if (pcount != 0)
+    {
+       printf("mechanism string = %s\n",str);
+       printf("Mechs left = %d\n",pcount);
+       fatal("Number of mechs received doesn't match what we were told");
+    }
+
+    /* Call sasl done then make sure listmech doesn't work anymore */
+    sasl_dispose(&saslconn);
+    sasl_dispose(&cconn);
+    sasl_done();
+
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          "[",
+                          "-",
+                          "]",
+                          &str,
+                          NULL,
+                          NULL);
+
+    if (result == SASL_OK) fatal("Called sasl_done but listmech still works\n");
+
+}
+
+/*
+ * Perform tests on the random utilities
+ */
+
+void test_random(void)
+{
+    sasl_rand_t *rpool;
+    int lup;
+    char buf[4096];
+
+    /* make sure it works consistantly */
+
+    for (lup = 0;lup<10;lup++)
+    {
+       if (sasl_randcreate(&rpool) != SASL_OK) fatal("sasl_randcreate failed");
+       sasl_randfree(&rpool);
+    }
+
+    /* try seeding w/o calling rand_create first */
+    rpool = NULL;
+    sasl_randseed(rpool, "seed", 4);
+
+    /* try seeding with bad values */
+    sasl_randcreate(&rpool);
+    sasl_randseed(rpool, "seed", 0);
+    sasl_randseed(rpool, NULL, 0);
+    sasl_randseed(rpool, NULL, 4);    
+    sasl_randfree(&rpool);
+
+    /* try churning with bad values */
+    sasl_randcreate(&rpool);
+    sasl_churn(rpool, "seed", 0);
+    sasl_churn(rpool, NULL, 0);
+    sasl_churn(rpool, NULL, 4);    
+    sasl_randfree(&rpool);
+
+    /* try seeding with a lot of crap */
+    sasl_randcreate(&rpool);
+    
+    for (lup=0;lup<(int) sizeof(buf);lup++)
+    {
+       buf[lup] = (rand() % 256);      
+    }
+    sasl_randseed(rpool, buf, sizeof(buf));
+    sasl_churn(rpool, buf, sizeof(buf));
+
+    sasl_randfree(&rpool);
+}
+
+/*
+ * Test SASL base64 conversion routines
+ */
+
+void test_64(void)
+{
+    char orig[4096];
+    char enc[8192];
+    unsigned encsize;
+    int lup;
+
+    /* make random crap and see if enc->dec produces same as original */
+    for (lup=0;lup<(int) sizeof(orig);lup++)
+       orig[lup] = (char) (rand() % 256);
+    
+    if (sasl_encode64(orig, sizeof(orig), enc, sizeof(enc), &encsize)!=SASL_OK) 
+       fatal("encode64 failed when we didn't expect it to");
+
+    if (sasl_decode64(enc, encsize, enc, 8192, &encsize)!=SASL_OK)
+       fatal("decode64 failed when we didn't expect it to");
+    
+    if (encsize != sizeof(orig)) fatal("Now has different size");
+    
+    for (lup=0;lup<(int) sizeof(orig);lup++)
+       if (enc[lup] != orig[lup])
+           fatal("enc64->dec64 doesn't match");
+
+    /* try to get a SASL_BUFOVER */
+    
+    if (sasl_encode64(orig, sizeof(orig)-1, enc, 10, &encsize)!=SASL_BUFOVER)
+       fatal("Expected SASL_BUFOVER");
+
+
+    /* pass some bad params */
+    if (sasl_encode64(NULL, 10, enc, sizeof(enc), &encsize)==SASL_OK)
+       fatal("Said ok to null data");
+
+    if (sasl_encode64(orig, sizeof(orig), enc, sizeof(enc), NULL)!=SASL_OK)
+       fatal("Didn't allow null return size");
+
+    /* New tests in 2.1.22 */
+    for (lup=0;lup<(int) sizeof(orig);lup++) {
+       enc[lup] = 'A';
+    }
+
+    if (sasl_decode64(enc, 3, orig, 8192, &encsize) != SASL_CONTINUE)
+       fatal("decode64 succeded on a 3 byte buffer when it shouldn't have");
+
+    enc[3] = '\r';
+    enc[4] = '\n';
+
+    if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
+       fatal("decode64 succeded on a 4 byte buffer with a bare CR");
+
+    if (sasl_decode64(enc, 5, orig, 8192, &encsize) == SASL_OK)
+       fatal("decode64 succeded on a 5 byte buffer with CRLF");
+
+    enc[2] = '=';
+    enc[3] = '=';
+    enc[4] = '=';
+
+    if (sasl_decode64(enc, 4, orig, 8192, &encsize) != SASL_OK)
+       fatal("decode64 failed on a 4 byte buffer with a terminating =");
+
+    if (sasl_decode64(enc, 5, orig, 8192, &encsize) != SASL_BADPROT)
+       fatal("decode64 did not return SASL_CONTINUE on a 5 byte buffer with a terminating =");
+
+    /* Test for invalid character after the terminating '=' */
+    enc[3] = '*';
+
+    if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
+       fatal("decode64 failed on a 4 byte buffer with invalid character a terminating =");
+
+    /* Test for '=' in the middle of an encoded string */
+    enc[3] = 'B';
+
+    if (sasl_decode64(enc, 4, orig, 8192, &encsize) == SASL_OK)
+       fatal("decode64 succeed on a 4 byte buffer with a data after a terminating =");
+
+    if (sasl_decode64(enc, 0, orig, 8192, &encsize) != SASL_OK)
+       fatal("decode64 should have succeeded on an empty buffer");
+}
+
+/* This isn't complete, but then, what in the testsuite is? */
+void test_props(void) 
+{
+    int result;
+    struct propval foobar[3];
+    struct propctx *ctx, *dupctx;
+
+    const char *requests[] = {
+       "userPassword",
+        "userName",
+       "homeDirectory",
+        "uidNumber",
+        "gidNumber",
+        NULL
+    };
+
+    const char *more_requests[] = {
+       "a",
+       "b",
+       "c",
+       "defghijklmnop",
+       NULL
+    };
+
+    const char *short_requests[] = {
+       "userPassword",
+       "userName",
+       "BAD",
+       NULL
+    };
+
+    ctx = prop_new(2);
+    if(!ctx) {
+       fatal("no new prop context");
+    }
+
+    if(prop_request(NULL, requests) == SASL_OK)
+       fatal("prop_request w/NULL context succeeded");
+    if(prop_request(ctx, NULL) == SASL_OK)
+       fatal("prop_request w/NULL request list succeeded");
+    
+    result = prop_request(ctx, requests);
+    if(result != SASL_OK)
+       fatal("prop request failed");
+
+    /* set some values */
+    prop_set(ctx, "uidNumber", really_long_string, 0);
+    prop_set(ctx, "userPassword", "pw1", 0);
+    prop_set(ctx, "userPassword", "pw2", 0);
+    prop_set(ctx, "userName", "rjs3", 0);
+    prop_set(ctx, NULL, "tmartin", 0);
+
+    /* and request some more (this resets values) */
+    prop_request(ctx, more_requests);
+
+    /* and set some more... */
+    prop_set(ctx, "c", really_long_string, 0);
+    prop_set(ctx, "b", really_long_string, 0);
+    prop_set(ctx, "userPassword", "pw1b", 0);
+    prop_set(ctx, "userPassword", "pw2b", 0);
+    prop_set(ctx, "userName", "rjs3b", 0);
+    prop_set(ctx, NULL, "tmartinagain", 0);
+
+    if(prop_set(ctx, "gah", "ack", 0) == SASL_OK) {
+       printf("setting bad property name succeeded\n");
+       exit(1);
+    }
+
+    result = prop_getnames(ctx, short_requests, foobar);
+    if(result < 0)
+       fatal("prop_getnames failed");
+
+    if(strcmp(foobar[0].name, short_requests[0]))
+       fatal("prop_getnames item 0 wrong name");
+    if(strcmp(foobar[1].name, short_requests[1]))
+       fatal("prop_getnames item 1 wrong name");
+    if(foobar[2].name)
+       fatal("prop_getnames returned an item 2");
+
+    if(strcmp(foobar[0].values[0], "pw1b"))
+       fatal("prop_getnames item 1a wrong value");
+    if(strcmp(foobar[0].values[1], "pw2b"))
+       fatal("prop_getnames item 1b wrong value");
+    if(strcmp(foobar[1].values[0], "rjs3b"))
+       fatal("prop_getnames item 2a wrong value");
+    if(strcmp(foobar[1].values[1], "tmartinagain"))
+       fatal("prop_getnames item 2b wrong value");
+
+    result = prop_dup(ctx, &dupctx);
+    if(result != SASL_OK)
+       fatal("could not duplicate");
+
+    prop_clear(ctx, 1);
+    
+    result = prop_getnames(ctx, short_requests, foobar);
+    if(result < 0)
+       fatal("prop_getnames failed second time");
+
+    if(foobar[0].name)
+       fatal("it appears that prop_clear failed");
+    
+    result = prop_getnames(dupctx, short_requests, foobar);
+    if(result < 0)
+       fatal("prop_getnames failed second time");
+
+    if(!foobar[0].name)
+       fatal("prop_clear appears to have affected dup'd context");
+    
+    prop_clear(dupctx, 0);
+
+    result = prop_getnames(dupctx, short_requests, foobar);
+    if(result < 0)
+       fatal("prop_getnames failed second time");
+
+    if(!foobar[0].name || strcmp(foobar[0].name, short_requests[0]))
+       fatal("prop_clear appears to have cleared too much");
+
+    prop_dispose(&ctx);
+    prop_dispose(&dupctx);
+    if(ctx != NULL)
+       fatal("ctx not null after prop_dispose");
+}
+
+void interaction (int id, const char *prompt,
+                 const char **tresult, unsigned int *tlen)
+{
+    if (id==SASL_CB_PASS) {
+       *tresult=(char *) password;
+    } else if (id==SASL_CB_USER && proxyflag == 0) {
+       *tresult=(char *) username;
+    } else if (id==SASL_CB_USER && proxyflag == 1) {
+       *tresult=(char *) proxyasname;
+    } else if (id==SASL_CB_AUTHNAME) {
+       *tresult=(char *) authname;
+    } else if ((id==SASL_CB_GETREALM)) {
+       *tresult=(char *) myhostname;
+    } else {
+       size_t c;
+       
+       printf("%s: ",prompt);
+       fgets(other_result, sizeof(other_result) - 1, stdin);
+       c = strlen(other_result);
+       other_result[c - 1] = '\0';
+       *tresult=other_result;
+    }
+
+    *tlen = (unsigned int) strlen(*tresult);
+}
+
+void fillin_correctly(sasl_interact_t *tlist)
+{
+  while (tlist->id!=SASL_CB_LIST_END)
+  {
+    interaction(tlist->id, tlist->prompt,
+               (void *) &(tlist->result), 
+               &(tlist->len));
+    tlist++;
+  }
+
+}
+
+const sasl_security_properties_t security_props = {
+    0,
+    256,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+void set_properties(sasl_conn_t *conn, const sasl_security_properties_t *props)
+{
+    if(!props) {
+       if (sasl_setprop(conn, SASL_SEC_PROPS, &security_props) != SASL_OK)
+           fatal("sasl_setprop() failed - default properties");
+    } else {
+               if (sasl_setprop(conn, SASL_SEC_PROPS, props) != SASL_OK)
+           fatal("sasl_setprop() failed");
+    }
+
+    if (sasl_setprop(conn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
+       fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
+}
+
+/*
+ * This corrupts the string for us
+ */
+void corrupt(corrupt_type_t type, char *in, int inlen,
+            char **out, unsigned *outlen)
+{
+    unsigned lup;
+    
+
+    switch (type)
+       {
+       case NOTHING:
+           *out = in;
+           *outlen = inlen;
+           break;
+       case ONEBYTE_RANDOM: /* corrupt one byte */
+
+           if (inlen>0)
+               in[ (rand() % inlen) ] = (char) (rand() % 256);
+
+           *out = in;
+           *outlen = inlen;
+
+           break;
+       case ONEBYTE_NULL:
+           if (inlen>0)
+               in[ (rand() % inlen) ] = '\0';
+
+           *out = in;
+           *outlen = inlen;
+           break;
+       case ONEBYTE_QUOTES:
+           if (inlen>0)
+               in[ (rand() % inlen) ] = '"';
+
+           *out = in;
+           *outlen = inlen;
+           break;
+       case ONLY_ONE_BYTE:
+           *out = (char *) malloc(1);
+           (*out)[0] = (char) (rand() % 256);
+           *outlen = 1;
+           break;
+
+       case ADDSOME:
+           *outlen = inlen+ (rand() % 100);
+           *out = (char *) malloc(*outlen);
+           memcpy( *out, in, inlen);
+           
+           for (lup=inlen;lup<*outlen;lup++)
+               (*out)[lup] = (char) (rand() %256);
+
+           break;
+
+       case SHORTEN:
+           if (inlen > 0)
+           {
+               *outlen = 0;
+               while(*outlen == 0)
+                   *outlen = (rand() % inlen);
+               *out = (char *) malloc(*outlen);
+               memcpy(*out, in, *outlen);
+           } else {
+               *outlen = inlen;
+               *out = in;
+           }
+           break;
+       case REASONABLE_RANDOM:
+           *outlen = inlen;
+           if(*outlen != 0)
+               *out = (char *) malloc(*outlen);
+           else
+               *out = malloc(1);
+
+           for (lup=0;lup<*outlen;lup++)
+               (*out)[lup] = (char) (rand() % 256);
+
+           break;
+       case REALLYBIG:
+           *outlen = rand() % 50000;
+           *out = (char *) malloc( *outlen);
+           
+           for (lup=0;lup<*outlen;lup++)
+               (*out)[lup] = (char) (rand() % 256);
+           
+           break;
+       case NEGATIVE_LENGTH:
+
+           *out = in;
+           if (inlen == 0) inlen = 10;
+           *outlen = -1 * (rand() % inlen);
+           
+           break;
+       default:
+           fatal("Invalid corruption type");
+           break;
+       }
+}
+
+void sendbadsecond(char *mech, void *rock)
+{
+    int result, need_another_client = 0;
+    sasl_conn_t *saslconn;
+    sasl_conn_t *clientconn;
+    const char *out, *dec, *out2;
+    char *tmp;
+    unsigned outlen, declen, outlen2;
+    sasl_interact_t *client_interact=NULL;
+    const char *mechusing;
+    const char *service = "rcmd";
+    int mystep = 0; /* what step in the authentication are we on */
+    int mayfail = 0; /* we did some corruption earlier so it's likely to fail now */
+    
+    tosend_t *send = (tosend_t *)rock;
+
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+    int reauth = 1;
+
+    printf("%s --> start\n",mech);
+    
+    if (strcmp(mech,"GSSAPI")==0) service = gssapi_service;
+
+    if (sasl_client_init(client_interactions)!=SASL_OK) fatal("Unable to init client");
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK) fatal("unable to init server");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+       perror("gethostbyname");
+       fatal("can't gethostbyname");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+ reauth: /* loop back for reauth testing */
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 23);
+
+    /* client new connection */
+    if (sasl_client_new(service,
+                       myhostname,
+                       buf, buf, NULL,
+                       0,
+                       &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
+
+    set_properties(clientconn, NULL);
+
+    if (sasl_server_new(service, myhostname, NULL,
+                       buf, buf, NULL, 0, 
+                       &saslconn) != SASL_OK) {
+       fatal("can't sasl_server_new");
+    }
+    set_properties(saslconn, NULL);
+
+    do {
+       result = sasl_client_start(clientconn, mech,
+                                  &client_interact,
+                                  &out, &outlen,
+                                  &mechusing);
+
+       if (result == SASL_INTERACT) fillin_correctly(client_interact);
+       else if(result == SASL_CONTINUE) need_another_client = 1;
+       else if(result == SASL_OK) need_another_client = 0;
+    } while (result == SASL_INTERACT);
+                              
+    if (result < 0)
+    {
+       printf("%s - \n",sasl_errdetail(clientconn));
+       fatal("sasl_client_start() error");
+    }
+
+    if (mystep == send->step && outlen)
+    {
+       memcpy(buf, out, outlen);
+       corrupt(send->type, buf, outlen, &tmp, &outlen);
+       out = tmp;
+       mayfail = 1;
+    }
+
+    result = sasl_server_start(saslconn,
+                              mech,
+                              out,
+                              outlen,
+                              &out,
+                              &outlen);
+
+    if (mayfail)
+    {
+       if (result >= SASL_OK)
+           printf("WARNING: We did a corruption but it still worked\n");
+       else {
+           goto done;
+       }
+    } else {
+       if (result < 0) 
+       {
+           printf("%s\n",sasl_errstring(result,NULL,NULL));
+           fatal("sasl_server_start() error");
+       }
+    }
+    mystep++;
+
+    while (result == SASL_CONTINUE) {
+
+       if (mystep == send->step)
+       {
+           memcpy(buf,out,outlen);
+           corrupt(send->type, buf, outlen, &tmp, &outlen);
+           out = tmp;
+           mayfail = 1;
+       }
+
+       do {
+           result = sasl_client_step(clientconn,
+                                     out, outlen,
+                                     &client_interact,
+                                     &out2, &outlen2);
+           
+           if (result == SASL_INTERACT)
+               fillin_correctly(client_interact);
+           else if (result == SASL_CONTINUE)
+               need_another_client = 1;
+           else if (result == SASL_OK)
+               need_another_client = 0;
+       } while (result == SASL_INTERACT);
+
+       if (mayfail == 1)
+       {
+           if (result >= 0)
+               printf("WARNING: We did a corruption but it still worked\n");
+           else {
+               goto done;
+           }
+       } else {
+           if (result < 0) 
+           {
+               printf("%s\n",sasl_errstring(result,NULL,NULL));
+               fatal("sasl_client_step() error");
+           }
+       }
+       out=out2;
+       outlen=outlen2;
+       mystep++;
+
+       if (mystep == send->step)
+       {
+           memcpy(buf, out, outlen);
+           corrupt(send->type, buf, outlen, &tmp, &outlen);
+           out = tmp;
+           mayfail = 1;
+       }
+
+       result = sasl_server_step(saslconn,
+                                 out,
+                                 outlen,
+                                 &out,
+                                 &outlen);
+       
+       if (mayfail == 1)
+       {
+           if (result >= 0)
+               printf("WARNING: We did a corruption but it still worked\n");
+           else {
+               goto done;
+           }
+       } else {
+           if (result < 0) 
+           {
+               printf("%s\n",sasl_errstring(result,NULL,NULL));
+               fatal("sasl_server_step() error");
+           }
+       }
+       mystep++;
+
+    }
+
+    if(need_another_client) {
+       result = sasl_client_step(clientconn,
+                                 out, outlen,
+                                 &client_interact,
+                                 &out2, &outlen2);
+       if(result != SASL_OK)
+           fatal("client was not ok on last server step");
+    }
+    
+    if (reauth) {
+       sasl_dispose(&clientconn);
+       sasl_dispose(&saslconn);
+       reauth = 0;
+       goto reauth;
+    }
+
+    /* client to server */
+    result = sasl_encode(clientconn, CLIENT_TO_SERVER,
+                        (unsigned) strlen(CLIENT_TO_SERVER), &out, &outlen);
+    if (result != SASL_OK) fatal("Error encoding");
+
+    if (mystep == send->step)
+    {
+       memcpy(buf, out, outlen);
+       corrupt(send->type, buf, outlen, &tmp, &outlen);
+       out = tmp;
+       mayfail = 1;
+    }
+
+    result = sasl_decode(saslconn, out, outlen, &dec, &declen);
+
+    if (mayfail == 1)
+    {
+       if (result >= 0)
+           printf("WARNING: We did a corruption but it still worked\n");
+       else {
+           goto done;
+       }
+    } else {
+       if (result < 0) 
+       {
+           printf("%s\n",sasl_errstring(result,NULL,NULL));
+           fatal("sasl_decode() failure");
+       }
+    }
+    mystep++;
+
+    /* no need to do other direction since symetric */
+
+    /* Just verify oparams */
+    if(sasl_getprop(saslconn, SASL_USERNAME, (const void **)&out)
+       != SASL_OK) {
+       fatal("couldn't get server username");
+       goto done;
+    }
+    if(sasl_getprop(clientconn, SASL_USERNAME, (const void **)&out2)
+       != SASL_OK) {
+       fatal("couldn't get client username");
+       goto done;
+    }
+    if(strcmp(out,out2)) {
+       fatal("client username does not match server username");
+       goto done;
+    }
+
+    printf("%s --> %s (as %s)\n",mech,sasl_errstring(result,NULL,NULL),out);
+
+ done:
+    sasl_dispose(&clientconn);
+    sasl_dispose(&saslconn);
+    sasl_done();
+}
+
+/* Authenticate two sasl_conn_t's to eachother, validly.
+ * used to test the security layer */
+int doauth(char *mech, sasl_conn_t **server_conn, sasl_conn_t **client_conn,
+           const sasl_security_properties_t *props,
+          sasl_callback_t *c_calls, int fail_ok)
+{
+    int result, need_another_client = 0;
+    sasl_conn_t *saslconn;
+    sasl_conn_t *clientconn;
+    const char *out, *out2;
+    unsigned outlen, outlen2;
+    sasl_interact_t *client_interact=NULL;
+    const char *mechusing;
+    const char *service = "rcmd";
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+
+    if(!server_conn || !client_conn) return SASL_BADPARAM;
+    
+    if (strcmp(mech,"GSSAPI")==0) service = gssapi_service;
+
+    result = sasl_client_init((c_calls ? c_calls : client_interactions));
+    if (result!=SASL_OK) {
+       if(!fail_ok) fatal("Unable to init client");
+       else return result;
+    }
+
+    if(proxyflag == 0) {
+        result = sasl_server_init(goodsasl_cb,"TestSuite");
+    } else {
+        result = sasl_server_init(goodsaslproxy_cb,"TestSuite");
+    }
+    if(result != SASL_OK) {
+       if(!fail_ok) fatal("unable to init server");
+       else return result;
+    }
+           
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+       perror("gethostbyname");
+       if(!fail_ok) fatal("can't gethostbyname");
+       else return SASL_FAIL;
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    /* client new connection */
+    result = sasl_client_new(service,
+                            myhostname,
+                            buf, buf, NULL,
+                            0,
+                            &clientconn);
+    if(result != SASL_OK) {
+       if(!fail_ok) fatal("sasl_client_new() failure");
+       else return result;
+    }
+
+    /* Set the security properties */
+    set_properties(clientconn, props);
+
+    result = sasl_server_new(service, myhostname, NULL,
+                            buf, buf, NULL, 0, 
+                            &saslconn);
+    if(result != SASL_OK) {
+       if(!fail_ok) fatal("can't sasl_server_new");
+       else return result;
+    }
+    set_properties(saslconn, props);
+
+    do {
+       result = sasl_client_start(clientconn, mech,
+                                  &client_interact,
+                                  &out, &outlen,
+                                  &mechusing);
+
+       if (result == SASL_INTERACT) fillin_correctly(client_interact);
+       else if(result == SASL_CONTINUE) need_another_client = 1;
+       else if(result == SASL_OK) need_another_client = 0;
+    } while (result == SASL_INTERACT);
+                              
+    if (result < 0)
+    {
+       if(!fail_ok) fatal("sasl_client_start() error");
+       else return result;
+    }
+
+    result = sasl_server_start(saslconn,
+                              mech,
+                              out,
+                              outlen,
+                              &out,
+                              &outlen);
+
+    if (result < 0) 
+    {
+       if(!fail_ok) fatal("sasl_server_start() error");
+       else return result;
+    }
+
+    while (result == SASL_CONTINUE) {
+       do {
+           result = sasl_client_step(clientconn,
+                                     out, outlen,
+                                     &client_interact,
+                                     &out2, &outlen2);
+           
+           if (result == SASL_INTERACT)
+               fillin_correctly(client_interact);
+           else if (result == SASL_CONTINUE)
+               need_another_client = 1;
+           else if (result == SASL_OK)
+               need_another_client = 0;
+       } while (result == SASL_INTERACT);
+
+       if (result < 0) 
+       {
+           if(!fail_ok) fatal("sasl_client_step() error");
+           else return result;
+       }
+
+       out=out2;
+       outlen=outlen2;
+
+       result = sasl_server_step(saslconn,
+                                 out,
+                                 outlen,
+                                 &out,
+                                 &outlen);
+       
+       if (result < 0) 
+       {
+           if(!fail_ok) fatal("sasl_server_step() error");
+           else return result;
+       }
+
+    }
+
+    if(need_another_client) {
+       if(!fail_ok) fatal("server-last not allowed, but need another client call");
+       else return SASL_BADPROT;
+    }
+
+    *server_conn = saslconn;
+    *client_conn = clientconn;
+    
+    return SASL_OK;
+}
+
+/* Authenticate two sasl_conn_t's to eachother, validly.
+ * without allowing client-send-first */
+int doauth_noclientfirst(char *mech, sasl_conn_t **server_conn,
+                        sasl_conn_t **client_conn,
+                        const sasl_security_properties_t *props,
+                        sasl_callback_t *c_calls)
+{
+    int result, need_another_client = 0;
+    sasl_conn_t *saslconn;
+    sasl_conn_t *clientconn;
+    const char *out, *out2;
+    unsigned outlen, outlen2;
+    sasl_interact_t *client_interact=NULL;
+    const char *mechusing;
+    const char *service = "rcmd";
+
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+
+    if(!server_conn || !client_conn) return SASL_BADPARAM;
+    
+    if (strcmp(mech,"GSSAPI")==0) service = gssapi_service;
+
+
+    if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
+       fatal("Unable to init client");
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
+        fatal("unable to init server");  
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+       perror("gethostbyname");
+       fatal("can't gethostbyname");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    /* client new connection */
+    if (sasl_client_new(service,
+                       myhostname,
+                       buf, buf, NULL,
+                       0,
+                       &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
+
+    /* Set the security properties */
+    set_properties(clientconn, props);
+
+    if (sasl_server_new(service, myhostname, NULL,
+                       buf, buf, NULL, 0, 
+                       &saslconn) != SASL_OK) {
+       fatal("can't sasl_server_new");
+    }
+    set_properties(saslconn, props);
+
+    do {
+       result = sasl_client_start(clientconn, mech,
+                                  &client_interact,
+                                  NULL, NULL,
+                                  &mechusing);
+
+       if (result == SASL_INTERACT) fillin_correctly(client_interact);
+       else if(result == SASL_CONTINUE) need_another_client = 1;
+       else if(result == SASL_OK) need_another_client = 0;
+    } while (result == SASL_INTERACT);
+
+    if (result < 0)
+    {
+       fatal("sasl_client_start() error");
+    }  
+
+    result = sasl_server_start(saslconn,
+                              mech,
+                              NULL,
+                              0,
+                              &out,
+                              &outlen);
+
+    if (result < 0) 
+    {
+       fatal("sasl_server_start() error");
+    }
+
+    while (result == SASL_CONTINUE) {
+       do {
+           result = sasl_client_step(clientconn,
+                                     out, outlen,
+                                     &client_interact,
+                                     &out2, &outlen2);
+           
+           if (result == SASL_INTERACT)
+               fillin_correctly(client_interact);
+           else if (result == SASL_CONTINUE)
+               need_another_client = 1;
+           else if (result == SASL_OK)
+               need_another_client = 0;
+       } while (result == SASL_INTERACT);
+
+       if (result < 0) 
+       {
+           fatal("sasl_client_step() error");
+       }
+
+       out=out2;
+       outlen=outlen2;
+
+       result = sasl_server_step(saslconn,
+                                 out,
+                                 outlen,
+                                 &out,
+                                 &outlen);
+       
+       if (result < 0) 
+       {
+           fatal("sasl_server_step() error");
+       }
+
+    }
+
+    if(need_another_client) {
+       fatal("server-last not allowed, but need another client call");
+    }
+
+    *server_conn = saslconn;
+    *client_conn = clientconn;
+    
+    return SASL_OK;
+}
+
+/* Authenticate two sasl_conn_t's to eachother, validly.
+ * used to test the security layer */
+int doauth_serverlast(char *mech, sasl_conn_t **server_conn,
+                     sasl_conn_t **client_conn,
+                     const sasl_security_properties_t *props,
+                     sasl_callback_t *c_calls)
+{
+    int result, need_another_client = 0;
+    sasl_conn_t *saslconn;
+    sasl_conn_t *clientconn;
+    const char *out, *out2;
+    unsigned outlen, outlen2;
+    sasl_interact_t *client_interact=NULL;
+    const char *mechusing;
+    const char *service = "rcmd";
+
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+
+    if(!server_conn || !client_conn) return SASL_BADPARAM;
+    
+    if (strcmp(mech,"GSSAPI")==0) service = gssapi_service;
+
+    if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
+       fatal("unable to init client");
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
+       fatal("unable to init server");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+       perror("gethostbyname");
+       fatal("can't gethostbyname");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    /* client new connection */
+    if (sasl_client_new(service,
+                       myhostname,
+                       buf, buf, NULL,
+                       SASL_SUCCESS_DATA,
+                       &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
+
+    /* Set the security properties */
+    set_properties(clientconn, props);
+
+    if (sasl_server_new(service, myhostname, NULL,
+                       buf, buf, NULL, SASL_SUCCESS_DATA, 
+                       &saslconn) != SASL_OK) {
+       fatal("can't sasl_server_new");
+    }
+    set_properties(saslconn, props);
+
+    do {
+       result = sasl_client_start(clientconn, mech,
+                                  &client_interact,
+                                  &out, &outlen,
+                                  &mechusing);
+
+       if (result == SASL_INTERACT) fillin_correctly(client_interact);
+       else if(result == SASL_CONTINUE) need_another_client = 1;
+       else if(result == SASL_OK) need_another_client = 0;
+    } while (result == SASL_INTERACT);
+       
+
+    if (result < 0)
+    {
+       fatal("sasl_client_start() error");
+    }                         
+
+    result = sasl_server_start(saslconn,
+                              mech,
+                              out,
+                              outlen,
+                              &out,
+                              &outlen);
+
+    if (result < 0) 
+    {
+       fatal("sasl_server_start() error");
+    }
+
+    while (result == SASL_CONTINUE) {
+       do {
+           result = sasl_client_step(clientconn,
+                                     out, outlen,
+                                     &client_interact,
+                                     &out2, &outlen2);
+           
+           if (result == SASL_INTERACT)
+               fillin_correctly(client_interact);
+           else if (result == SASL_CONTINUE)
+               need_another_client = 1;
+           else if (result == SASL_OK)
+               need_another_client = 0;
+       } while (result == SASL_INTERACT);
+
+       if (result < 0) 
+       {
+           fatal("sasl_client_step() error");
+       }
+
+       out=out2;
+       outlen=outlen2;
+
+       result = sasl_server_step(saslconn,
+                                 out,
+                                 outlen,
+                                 &out,
+                                 &outlen);
+       
+       if (result < 0) 
+       {
+           fatal("sasl_server_step() error");
+       }
+
+    }
+
+    if(need_another_client) {
+       result = sasl_client_step(clientconn,
+                                 out, outlen,
+                                 &client_interact,
+                                 &out2, &outlen2);
+       if(result != SASL_OK)
+           fatal("client was not ok on last server step");
+    }
+
+    *server_conn = saslconn;
+    *client_conn = clientconn;
+    
+    return SASL_OK;
+}
+
+/* Authenticate two sasl_conn_t's to eachother, validly.
+ * without allowing client-send-first */
+int doauth_noclientfirst_andserverlast(char *mech, sasl_conn_t **server_conn,
+                                      sasl_conn_t **client_conn,
+                                      const sasl_security_properties_t *props,
+                                      sasl_callback_t *c_calls)
+{
+    int result, need_another_client = 0;
+    sasl_conn_t *saslconn;
+    sasl_conn_t *clientconn;
+    const char *out, *out2;
+    unsigned outlen, outlen2;
+    sasl_interact_t *client_interact=NULL;
+    const char *mechusing;
+    const char *service = "rcmd";
+
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+
+    if(!server_conn || !client_conn) return SASL_BADPARAM;
+    
+    if (strcmp(mech,"GSSAPI")==0) service = gssapi_service;
+
+    if (sasl_client_init((c_calls ? c_calls : client_interactions))!=SASL_OK)
+       fatal("unable to init client");
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
+       fatal("unable to init server");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+       perror("gethostbyname");
+       fatal("can't gethostbyname");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    /* client new connection */
+    if (sasl_client_new(service,
+                       myhostname,
+                       buf, buf, NULL,
+                       SASL_SUCCESS_DATA,
+                       &clientconn)!= SASL_OK) fatal("sasl_client_new() failure");
+
+    /* Set the security properties */
+    set_properties(clientconn, props);
+
+    if (sasl_server_new(service, myhostname, NULL,
+                       buf, buf, NULL, SASL_SUCCESS_DATA, 
+                       &saslconn) != SASL_OK) {
+       fatal("can't sasl_server_new");
+    }
+    set_properties(saslconn, props);
+
+    do {
+       result = sasl_client_start(clientconn, mech,
+                                  &client_interact,
+                                  NULL, NULL,
+                                  &mechusing);
+
+       if (result == SASL_INTERACT) fillin_correctly(client_interact);
+       else if(result == SASL_CONTINUE) need_another_client = 1;
+       else if(result == SASL_OK) need_another_client = 0;
+    } while (result == SASL_INTERACT);
+
+    if (result < 0)
+    {
+       fatal("sasl_client_start() error");
+    }                                 
+
+    result = sasl_server_start(saslconn,
+                              mech,
+                              NULL,
+                              0,
+                              &out,
+                              &outlen);
+
+    if (result < 0) 
+    {
+       fatal("sasl_server_start() error");
+    }
+
+    while (result == SASL_CONTINUE) {
+       do {
+           result = sasl_client_step(clientconn,
+                                     out, outlen,
+                                     &client_interact,
+                                     &out2, &outlen2);
+           
+           if (result == SASL_INTERACT)
+               fillin_correctly(client_interact);
+           else if (result == SASL_CONTINUE)
+               need_another_client = 1;
+           else if (result == SASL_OK)
+               need_another_client = 0;
+       } while (result == SASL_INTERACT);
+
+       if (result < 0) 
+       {
+           fatal("sasl_client_step() error");
+       }
+
+       out=out2;
+       outlen=outlen2;
+
+       result = sasl_server_step(saslconn,
+                                 out,
+                                 outlen,
+                                 &out,
+                                 &outlen);
+       
+       if (result < 0) 
+       {
+           fatal("sasl_server_step() error");
+       }
+
+    }
+
+    if(need_another_client) {
+       result = sasl_client_step(clientconn,
+                                 out, outlen,
+                                 &client_interact,
+                                 &out2, &outlen2);
+       if(result != SASL_OK)
+           fatal("client was not ok on last server step");
+    }
+
+    *server_conn = saslconn;
+    *client_conn = clientconn;
+    
+    return SASL_OK;
+}
+
+void cleanup_auth(sasl_conn_t **client, sasl_conn_t **server) 
+{
+    sasl_dispose(client);
+    sasl_dispose(server);
+    sasl_done();
+}
+
+
+const sasl_security_properties_t int_only = {
+    0,
+    1,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+const sasl_security_properties_t force_des = {
+    0,
+    55,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+const sasl_security_properties_t force_rc4_56 = {
+    0,
+    56,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+const sasl_security_properties_t force_3des = {
+    0,
+    112,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+
+const sasl_security_properties_t no_int = {
+    2,
+    256,
+    8192,
+    0,
+    NULL,
+    NULL           
+};
+
+const sasl_security_properties_t disable_seclayer = {
+    0,
+    256,
+    0,
+    0,
+    NULL,
+    NULL           
+};
+
+void do_proxypolicy_test(char *mech, void *rock __attribute__((unused))) 
+{
+    sasl_conn_t *sconn, *cconn;
+    const char *username;
+    
+    printf("%s --> start\n", mech);
+    proxyflag = 1;
+    if(doauth(mech, &sconn, &cconn, &security_props, NULL, 0) != SASL_OK) {
+       fatal("doauth failed in do_proxypolicy_test");
+    }
+
+    if(sasl_getprop(sconn, SASL_USERNAME, (const void **)&username) != SASL_OK)
+    {
+       fatal("getprop failed in do_proxypolicy_test");
+    }
+    
+    if(strcmp(username, proxyasname)) {
+       printf("Warning: Server Authorization Name != proxyasuser\n");
+    }
+
+    cleanup_auth(&cconn, &sconn);
+    proxyflag = 0;
+    printf("%s --> successful result\n",mech);
+}
+
+void test_clientfirst(char *mech, void *rock) 
+{
+    sasl_conn_t *sconn, *cconn;
+    tosend_t *tosend = (tosend_t *)rock;
+    
+    printf("%s --> start\n", mech);
+
+    /* Basic crash-tests (none should cause a crash): */
+    if(doauth(mech, &sconn, &cconn, &security_props, tosend->client_callbacks,
+             0) != SASL_OK) {
+       fatal("doauth failed in test_clientfirst");
+    }
+
+    cleanup_auth(&cconn, &sconn);
+
+    printf("%s --> successful result\n", mech);
+}
+
+void test_noclientfirst(char *mech, void *rock) 
+{
+    sasl_conn_t *sconn, *cconn;
+    tosend_t *tosend = (tosend_t *)rock;
+    
+    printf("%s --> start\n", mech);
+
+    /* Basic crash-tests (none should cause a crash): */
+    if(doauth_noclientfirst(mech, &sconn, &cconn, &security_props,
+       tosend->client_callbacks) != SASL_OK) {
+       fatal("doauth failed in test_noclientfirst");
+    }
+
+    cleanup_auth(&cconn, &sconn);
+
+    printf("%s --> successful result\n", mech);
+}
+
+void test_serverlast(char *mech, void *rock) 
+{
+    sasl_conn_t *sconn, *cconn;
+    tosend_t *tosend = (tosend_t *)rock;
+    
+    printf("%s --> start\n", mech);
+
+    /* Basic crash-tests (none should cause a crash): */
+    if(doauth_serverlast(mech, &sconn, &cconn, &security_props,
+                        tosend->client_callbacks) != SASL_OK) {
+       fatal("doauth failed in test_serverlast");
+    }
+
+    cleanup_auth(&cconn, &sconn);
+
+    printf("%s --> successful result\n", mech);
+}
+
+
+void test_noclientfirst_andserverlast(char *mech, void *rock) 
+{
+    sasl_conn_t *sconn, *cconn;
+    tosend_t *tosend = (tosend_t *)rock;
+    
+    printf("%s --> start\n", mech);
+
+    /* Basic crash-tests (none should cause a crash): */
+    if(doauth_noclientfirst_andserverlast(mech, &sconn, &cconn,
+                                         &security_props,
+                                         tosend->client_callbacks)
+       != SASL_OK) {
+       fatal("doauth failed in test_noclientfirst_andserverlast");
+    }
+
+    cleanup_auth(&cconn, &sconn);
+
+    printf("%s --> successful result\n", mech);
+}
+
+void testseclayer(char *mech, void *rock __attribute__((unused))) 
+{
+    sasl_conn_t *sconn, *cconn;
+    int result;
+    char buf[8192], buf2[8192];
+    const char *txstring = "THIS IS A TEST";
+    const char *out, *out2;
+    char *tmp;
+    const sasl_security_properties_t *test_props[7] =
+                                          { &security_props,
+                                           &force_3des,
+                                           &force_rc4_56,
+                                           &force_des,
+                                           &int_only,
+                                           &no_int,
+                                           &disable_seclayer };
+    const unsigned num_properties = 7;
+    unsigned i;
+    const sasl_ssf_t *this_ssf;
+    unsigned outlen = 0, outlen2 = 0, totlen = 0;
+    
+    printf("%s --> security layer start\n", mech);
+
+    for(i=0; i<num_properties; i++) {
+        
+    /* Basic crash-tests (none should cause a crash): */
+    result = doauth(mech, &sconn, &cconn, test_props[i], NULL, 1);
+    if(result == SASL_NOMECH && test_props[i]->min_ssf > 0) {
+       printf("  Testing SSF: SKIPPED (requested minimum > 0: %d)\n",
+              test_props[i]->min_ssf);
+       cleanup_auth(&sconn, &cconn);
+       continue;
+    } else if(result != SASL_OK) {
+       fatal("doauth failed in testseclayer");
+    }
+
+    if(sasl_getprop(cconn, SASL_SSF, (const void **)&this_ssf) != SASL_OK) {
+       fatal("sasl_getprop in testseclayer");
+    }
+
+    if(*this_ssf != 0 && !test_props[i]->maxbufsize) {
+       fatal("got nonzero SSF with zero maxbufsize");
+    }
+
+    printf("  SUCCESS Testing SSF: %d (requested %d/%d with maxbufsize: %d)\n",
+          (unsigned)(*this_ssf),
+          test_props[i]->min_ssf, test_props[i]->max_ssf,
+          test_props[i]->maxbufsize);
+
+    if(!test_props[i]->maxbufsize) {
+       result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                            &out, &outlen);
+       if(result == SASL_OK) {
+           fatal("got OK when encoding with zero maxbufsize");
+       }
+       result = sasl_decode(sconn, "foo", 3, &out, &outlen);
+       if(result == SASL_OK) {
+           fatal("got OK when decoding with zero maxbufsize");
+       }
+       cleanup_auth(&sconn, &cconn);
+       continue;
+    }
+    
+    sasl_encode(NULL, txstring, (unsigned) strlen(txstring), &out, &outlen);
+    sasl_encode(cconn, NULL, (unsigned) strlen(txstring), &out, &outlen);
+    sasl_encode(cconn, txstring, 0, &out, &outlen);
+    sasl_encode(cconn, txstring, (unsigned) strlen(txstring), NULL, &outlen);
+    sasl_encode(cconn, txstring, (unsigned) strlen(txstring), &out, NULL);
+    
+    sasl_decode(NULL, txstring, (unsigned) strlen(txstring), &out, &outlen);
+    sasl_decode(cconn, NULL, (unsigned) strlen(txstring), &out, &outlen);
+    sasl_decode(cconn, txstring, 0, &out, &outlen);
+    sasl_decode(cconn, txstring, (unsigned)-1, &out, &outlen);
+    sasl_decode(cconn, txstring, (unsigned) strlen(txstring), NULL, &outlen);
+    sasl_decode(cconn, txstring, (unsigned) strlen(txstring), &out, NULL);
+    
+    cleanup_auth(&sconn, &cconn);
+
+    /* Basic I/O Test */
+    if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
+       fatal("doauth failed in testseclayer");
+    }
+
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure");
+    }
+
+    result = sasl_decode(sconn, out, outlen, &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_decode failure");
+    }    
+    
+    cleanup_auth(&sconn, &cconn);
+
+    /* Split one block and reassemble */
+    if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
+       fatal("doauth failed in testseclayer");
+    }
+
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure (2)");
+    }
+
+    memcpy(buf, out, 5);
+    buf[5] = '\0';
+    
+    out += 5;
+
+    result = sasl_decode(sconn, buf, 5, &out2, &outlen2);
+    if(result != SASL_OK) {
+       printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
+       fatal("sasl_decode failure part 1/2");
+    }    
+
+    memset(buf2, 0, 8192);
+    if(outlen2) 
+        memcpy(buf2, out2, outlen2);
+
+    result = sasl_decode(sconn, out, outlen - 5, &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("sasl_decode failure part 2/2");
+    }
+
+    strcat(buf2, out);
+    if(strcmp(buf2, txstring)) {
+       printf("Exptected '%s' but got '%s'\n", txstring, buf2);
+       fatal("did not get correct string back after 2 sasl_decodes");
+    }
+
+    cleanup_auth(&sconn, &cconn);
+
+    /* Combine 2 blocks */
+    if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
+       fatal("doauth failed in testseclayer");
+    }
+
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure (3)");
+    }
+
+    memcpy(buf, out, outlen);
+
+    tmp = buf + outlen;
+    totlen = outlen;
+    
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure (4)");
+    }
+
+    memcpy(tmp, out, outlen);
+    totlen += outlen;
+
+    result = sasl_decode(sconn, buf, totlen, &out, &outlen);
+    if(result != SASL_OK) {
+       printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
+       fatal("sasl_decode failure (2 blocks)");
+    }    
+
+    sprintf(buf2, "%s%s", txstring, txstring);
+
+    if(strcmp(out, buf2)) {
+       fatal("did not get correct string back (2 blocks)");
+    }
+
+    cleanup_auth(&sconn, &cconn);
+
+    /* Combine 2 blocks with 1 split */
+    if(doauth(mech, &sconn, &cconn, test_props[i], NULL, 0) != SASL_OK) {
+       fatal("doauth failed in testseclayer");
+    }
+
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out, &outlen);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure (3)");
+    }
+
+    memcpy(buf, out, outlen);
+
+    tmp = buf + outlen;
+
+    result = sasl_encode(cconn, txstring, (unsigned) strlen(txstring),
+                        &out2, &outlen2);
+    if(result != SASL_OK) {
+       fatal("basic sasl_encode failure (4)");
+    }
+
+    memcpy(tmp, out2, 5);
+    tmp[5] = '\0';
+    outlen += 5;
+
+    outlen2 -= 5;
+    out2 += 5;
+
+    result = sasl_decode(sconn, buf, outlen, &out, &outlen);
+    if(result != SASL_OK) {
+       printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
+       fatal("sasl_decode failure 1/2 (2 blocks, 1 split)");
+    }    
+
+    memset(buf2, 0, 8192);
+    memcpy(buf2, out, outlen);
+
+    tmp = buf2 + outlen;
+
+    result = sasl_decode(sconn, out2, outlen2, &out, &outlen);
+    if(result != SASL_OK) {
+       printf("Failed with: %s\n", sasl_errstring(result, NULL, NULL));
+       fatal("sasl_decode failure 2/2 (2 blocks, 1 split)");
+    }
+
+    memcpy(tmp, out, outlen);
+
+    sprintf(buf, "%s%s", txstring, txstring);
+    if(strcmp(buf, buf2)) {
+       fatal("did not get correct string back (2 blocks, 1 split)");
+    }
+
+    cleanup_auth(&sconn, &cconn);
+    
+    } /* for each properties type we want to test */
+     
+    printf("%s --> security layer OK\n", mech);
+    
+}
+
+
+/*
+ * Apply the given function to each machanism 
+ */
+
+void foreach_mechanism(foreach_t *func, void *rock)
+{
+    const char *out;
+    char *str, *start;
+    sasl_conn_t *saslconn;
+    int result;
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    unsigned len;
+    char buf[8192];
+
+    /* Get the list of mechanisms */
+    sasl_done();
+
+    if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
+       fatal("sasl_server_init failed in foreach_mechanism");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+        perror("gethostbyname");
+        fatal("can't gethostbyname");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    if (sasl_server_new("rcmd", myhostname, NULL,
+                       buf, buf, NULL, 0,
+                       &saslconn) != SASL_OK) {
+       fatal("sasl_server_new in foreach_mechanism");
+    }
+
+    if (sasl_setprop(saslconn, SASL_AUTH_EXTERNAL, authname)!=SASL_OK)
+       fatal("sasl_setprop(SASL_AUTH_EXTERNAL) failed");
+
+    result = sasl_listmech(saslconn,
+                          NULL,
+                          "",
+                          "\n",
+                          "",
+                          &out,
+                          &len,
+                          NULL);
+
+    if(result != SASL_OK) {
+       fatal("sasl_listmech in foreach_mechanism");
+    }
+    
+    memcpy(buf, out, len + 1);
+
+    sasl_dispose(&saslconn);
+    sasl_done();
+
+    /* call the function for each mechanism */
+    start = str = buf;
+    while (*start != '\0')
+    {
+       while ((*str != '\n') && (*str != '\0'))
+           str++;
+
+       if (*str == '\n')
+       {
+           *str = '\0';
+           str++;
+       }
+
+       func(start, rock);
+
+       start = str;
+    }
+}
+
+void test_serverstart()
+{
+    int result;
+    sasl_conn_t *saslconn;
+    const char *out;
+    unsigned outlen;
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+
+    if (sasl_server_init(emptysasl_cb,"TestSuite")!=SASL_OK)
+       fatal("can't sasl_server_init in test_serverstart");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+        perror("gethostbyname");
+        fatal("can't gethostbyname in test_serverstart");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    if (sasl_server_new("rcmd", myhostname, NULL,
+                       buf, buf, NULL, 0, 
+                       &saslconn) != SASL_OK) {
+       fatal("can't sasl_server_new in test_serverstart");
+    }
+
+
+    /* Test null connection */
+    result = sasl_server_start(NULL,
+                              "foobar",
+                              NULL,
+                              0,
+                              NULL,
+                              NULL);
+    
+    if (result == SASL_OK) fatal("Said ok to null sasl_conn_t in sasl_server_start()");
+
+    /* send plausible but invalid mechanism */
+    result = sasl_server_start(saslconn,
+                              "foobar",
+                              NULL,
+                              0,
+                              &out,
+                              &outlen);
+
+    if (result == SASL_OK) fatal("Said ok to invalid mechanism");
+
+    /* send really long and invalid mechanism */
+    result = sasl_server_start(saslconn,
+                              really_long_string,
+                              NULL,
+                              0,
+                              &out,
+                              &outlen);
+
+    if (result == SASL_OK) fatal("Said ok to invalid mechanism");
+
+    sasl_dispose(&saslconn);
+    sasl_done();
+}
+
+void test_rand_corrupt(unsigned steps) 
+{
+    unsigned lup;
+    tosend_t tosend;
+    
+    for (lup=0;lup<steps;lup++)
+    {
+       tosend.type = rand() % CORRUPT_SIZE;
+       tosend.step = lup % MAX_STEPS;
+       tosend.client_callbacks = NULL;
+
+       printf("RANDOM TEST: (%s in step %d) (%d of %d)\n",corrupt_types[tosend.type],tosend.step,lup+1,steps);
+       foreach_mechanism((foreach_t *) &sendbadsecond,&tosend);
+    }
+}
+
+void test_proxypolicy() 
+{
+    foreach_mechanism((foreach_t *) &do_proxypolicy_test,NULL);
+}
+
+void test_all_corrupt() 
+{
+    tosend_t tosend;
+    tosend.client_callbacks = NULL;
+
+    /* Start just beyond NOTHING */
+    for(tosend.type=1; tosend.type<CORRUPT_SIZE; tosend.type++) {
+       for(tosend.step=0; tosend.step<MAX_STEPS; tosend.step++) {
+           printf("TEST: %s in step %d:\n", corrupt_types[tosend.type],
+                  tosend.step);
+           foreach_mechanism((foreach_t *) &sendbadsecond, &tosend);
+       }
+    }
+}
+
+void test_seclayer() 
+{
+    foreach_mechanism((foreach_t *) &testseclayer, NULL);
+}
+
+void create_ids(void)
+{
+    sasl_conn_t *saslconn;
+    int result;
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    char buf[8192];
+#ifdef DO_SASL_CHECKAPOP
+    int i;
+    const char challenge[] = "<1896.697170952@cyrus.andrew.cmu.edu>";
+    MD5_CTX ctx;
+    unsigned char digest[16];
+    char digeststr[32];
+#endif
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
+       fatal("can't sasl_server_init in create_ids");
+
+    if ((hp = gethostbyname(myhostname)) == NULL) {
+        perror("gethostbyname");
+        fatal("can't gethostbyname in create_ids");
+    }
+
+    addr.sin_family = 0;
+    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
+    addr.sin_port = htons(0);
+
+    sprintf(buf,"%s;%d", inet_ntoa(addr.sin_addr), 0);
+
+    if (sasl_server_new("rcmd", myhostname, NULL,
+                       buf, buf, NULL, 0,
+                       &saslconn) != SASL_OK)
+       fatal("can't sasl_server_new in create_ids");
+    
+    /* Try to set password then check it */
+
+    result = sasl_setpass(saslconn, username, password,
+                         (unsigned) strlen(password),
+                         NULL, 0, SASL_SET_CREATE);
+    if (result != SASL_OK) {
+       printf("error was %s (%d)\n",sasl_errstring(result,NULL,NULL),result);
+       fatal("Error setting password. Do we have write access to sasldb?");
+    }    
+    
+    result = sasl_checkpass(saslconn, username,
+                           (unsigned) strlen(username),
+                           password, (unsigned) strlen(password));
+    if (result != SASL_OK) {
+       fprintf(stderr, "%s\n", sasl_errdetail(saslconn));
+       fatal("Unable to verify password we just set");
+    }
+    result = sasl_user_exists(saslconn, "imap", NULL, username);
+    if(result != SASL_OK)
+       fatal("sasl_user_exists did not find user");
+
+    result = sasl_user_exists(saslconn, "imap", NULL,
+                             nonexistant_username);
+    if(result == SASL_OK)
+       fatal("sasl_user_exists found nonexistant username");
+
+    /* Test sasl_checkapop */
+#ifdef DO_SASL_CHECKAPOP
+    _sasl_MD5Init(&ctx);
+    _sasl_MD5Update(&ctx,challenge,strlen(challenge));
+    _sasl_MD5Update(&ctx,password,strlen(password));
+    _sasl_MD5Final(digest, &ctx);
+                            
+    /* convert digest from binary to ASCII hex */
+    for (i = 0; i < 16; i++)
+      sprintf(digeststr + (i*2), "%02x", digest[i]);
+
+    sprintf(buf, "%s %s", username, digeststr);
+    
+    result = sasl_checkapop(saslconn,
+                            challenge, strlen(challenge),
+                            buf, strlen(buf));
+    if(result != SASL_OK)
+        fatal("Unable to checkapop password we just set");
+    /* End checkapop test */
+#else /* Just check that checkapop is really turned off */
+    if(sasl_checkapop(saslconn, NULL, 0, NULL, 0) == SASL_OK)
+       fatal("sasl_checkapop seems to work but was disabled at compile time");
+#endif
+
+    /* now delete user and make sure can't find him anymore */
+    result = sasl_setpass(saslconn, username, password,
+                         (unsigned) strlen(password),
+                         NULL, 0, SASL_SET_DISABLE);
+    if (result != SASL_OK)
+       fatal("Error disabling password. Do we have write access to sasldb?");
+
+    result = sasl_checkpass(saslconn, username,
+                           (unsigned) strlen(username),
+                           password, (unsigned) strlen(password));
+    if (result == SASL_OK) {
+       printf("\n  WARNING: sasl_checkpass got SASL_OK after disableing\n");
+       printf("           This is generally ok, just an artifact of sasldb\n");
+       printf("           being an external verifier\n");
+    }
+
+#ifdef DO_SASL_CHECKAPOP
+    /* And checkapop... */
+    result = sasl_checkapop(saslconn,
+                            challenge, strlen(challenge), 
+                            buf, strlen(buf));
+    if (result == SASL_OK) {
+       printf("\n  WARNING: sasl_checkapop got SASL_OK after disableing\n");
+       printf("           This is generally ok, just an artifact of sasldb\n");
+       printf("           being an external verifier\n");
+    }
+#endif
+
+    /* try bad params */
+    if (sasl_setpass(NULL,username, password,
+                    (unsigned) strlen(password),
+                    NULL, 0, SASL_SET_CREATE)==SASL_OK)
+       fatal("Didn't specify saslconn");
+    if (sasl_setpass(saslconn,username, password, 0, NULL, 0, SASL_SET_CREATE)==SASL_OK)
+       fatal("Allowed password of zero length");
+    if (sasl_setpass(saslconn,username, password,
+                    (unsigned) strlen(password), NULL, 0, 43)==SASL_OK)
+       fatal("Gave weird code");
+
+#ifndef SASL_NDBM
+    if (sasl_setpass(saslconn,really_long_string,
+                    password, (unsigned)strlen(password), 
+                    NULL, 0, SASL_SET_CREATE)!=SASL_OK)
+       fatal("Didn't allow really long username");
+#else
+    printf("WARNING: skipping sasl_setpass() on really_long_string with NDBM\n");
+#endif
+
+    if (sasl_setpass(saslconn,"bob",really_long_string,
+                    (unsigned) strlen(really_long_string),NULL, 0,
+                    SASL_SET_CREATE)!=SASL_OK)
+       fatal("Didn't allow really long password");
+
+    result = sasl_setpass(saslconn,"frank",
+                         password, (unsigned) strlen(password), 
+                         NULL, 0, SASL_SET_DISABLE);
+
+    if ((result!=SASL_NOUSER) && (result!=SASL_OK))
+       {
+           printf("error = %d\n",result);
+           fatal("Disabling non-existant didn't return SASL_NOUSER");
+       }
+    
+    /* Now set the user again (we use for rest of program) */
+    result = sasl_setpass(saslconn, username,
+                         password, (unsigned) strlen(password),
+                         NULL, 0, SASL_SET_CREATE);
+    if (result != SASL_OK)
+       fatal("Error setting password. Do we have write access to sasldb?");
+
+    /* cleanup */
+    sasl_dispose(&saslconn);
+    sasl_done();
+}
+
+/*
+ * Test the checkpass routine
+ */
+
+void test_checkpass(void)
+{
+    sasl_conn_t *saslconn;
+
+    /* try without initializing anything */
+    if(sasl_checkpass(NULL,
+                     username,
+                     (unsigned) strlen(username),
+                     password,
+                     (unsigned) strlen(password)) != SASL_NOTINIT) {
+       fatal("sasl_checkpass() when library not initialized");
+    }    
+
+    if (sasl_server_init(goodsasl_cb,"TestSuite")!=SASL_OK)
+       fatal("can't sasl_server_init in test_checkpass");
+
+    if (sasl_server_new("rcmd", myhostname,
+                       NULL, NULL, NULL, NULL, 0, 
+                       &saslconn) != SASL_OK)
+       fatal("can't sasl_server_new in test_checkpass");
+
+    /* make sure works for general case */
+
+    if (sasl_checkpass(saslconn, username, (unsigned) strlen(username),
+                      password, (unsigned) strlen(password))!=SASL_OK)
+       fatal("sasl_checkpass() failed on simple case");
+
+    /* NULL saslconn */
+    if (sasl_checkpass(NULL, username, (unsigned) strlen(username),
+                  password, (unsigned) strlen(password)) == SASL_OK)
+       fatal("Suceeded with NULL saslconn");
+
+    /* NULL username -- should be OK if sasl_checkpass enabled */
+    if (sasl_checkpass(saslconn, NULL, (unsigned) strlen(username),
+                  password, (unsigned) strlen(password)) != SASL_OK)
+       fatal("failed check if sasl_checkpass is enabled");
+
+    /* NULL password */
+    if (sasl_checkpass(saslconn, username, (unsigned) strlen(username),
+                  NULL, (unsigned) strlen(password)) == SASL_OK)
+       fatal("Suceeded with NULL password");
+
+    sasl_dispose(&saslconn);
+    sasl_done();
+}
+
+
+
+void notes(void)
+{
+    printf("NOTE:\n");
+    printf("-For KERBEROS_V4 must be able to read srvtab file (usually /etc/srvtab)\n");
+    printf("-For GSSAPI must be able to read srvtab (/etc/krb5.keytab)\n");
+    printf("-For both KERBEROS_V4 and GSSAPI you must have non-expired tickets\n");
+    printf("-For OTP (w/OPIE) must be able to read/write opiekeys (/etc/opiekeys)\n");
+    printf("-For OTP you must have a non-expired secret\n");
+    printf("-Must be able to read sasldb, which needs to be setup with a\n");
+    printf(" username and a password (see top of testsuite.c)\n");
+    printf("\n\n");
+}
+
+void usage(void)
+{
+    printf("Usage:\n" \
+           " testsuite [-g name] [-s seed] [-r tests] -a -M\n" \
+           "    g -- gssapi service name to use (default: host)\n" \
+          "    r -- # of random tests to do (default: 25)\n" \
+          "    a -- do all corruption tests (and ignores random ones unless -r specified)\n" \
+          "    n -- skip the initial \"do correctly\" tests\n"
+          "    h -- show this screen\n" \
+           "    s -- random seed to use\n" \
+          "    M -- detailed memory debugging ON\n" \
+           );
+}
+
+int main(int argc, char **argv)
+{
+    char c;
+    int random_tests = -1;
+    int do_all = 0;
+    int skip_do_correct = 0;
+    unsigned int seed = (unsigned int) time(NULL);
+#ifdef WIN32
+  /* initialize winsock */
+    int result;
+    WSADATA wsaData;
+
+    result = WSAStartup( MAKEWORD(2, 0), &wsaData );
+    if ( result != 0) {
+       fatal("Windows sockets initialization failure");
+    }
+#endif
+
+    while ((c = getopt(argc, argv, "Ms:g:r:han")) != EOF)
+       switch (c) {
+       case 'M':
+           DETAILED_MEMORY_DEBUGGING = 1;
+           break;
+       case 's':
+           seed = atoi(optarg);
+           break;
+       case 'g':
+           gssapi_service = optarg;
+           break;
+       case 'r':
+           random_tests = atoi(optarg);
+           break;
+       case 'a':
+           random_tests = 0;
+           do_all = 1;
+           break;
+       case 'n':
+           skip_do_correct = 1;
+           break;
+       case 'h':
+           usage();
+           exit(0);
+           break;
+       default:
+           usage();
+           fatal("Invalid parameter\n");
+           break;
+    }
+
+    g_secret = malloc(sizeof(sasl_secret_t) + strlen(password));
+    g_secret->len = (unsigned) strlen(password);
+    strcpy(g_secret->data, password);
+
+    if(random_tests < 0) random_tests = 25;
+
+    notes();
+
+    init(seed);
+
+#if 0 /* Disabled because it is borked */
+    printf("Creating id's in mechanisms (not in sasldb)...\n");
+    create_ids();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("Creating id's in mechanisms (not in sasldb)... ok\n");
+#endif
+
+    printf("Checking plaintext passwords... ");
+    test_checkpass();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+
+    printf("Random number functions... ");
+    test_random();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+
+    printf("Testing base64 functions... ");
+    test_64();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+
+    printf("Testing auxprop functions... ");
+    test_props();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+
+    printf("Tests of sasl_{server|client}_init()... ");
+    test_init();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+    
+    printf("Testing sasl_listmech()... \n");
+    test_listmech();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("Testing sasl_listmech()... ok\n");
+
+    printf("Testing serverstart...");
+    test_serverstart();
+    if(mem_stat() != SASL_OK) fatal("memory error");
+    printf("ok\n");
+
+    if(!skip_do_correct) {
+       tosend_t tosend;
+       
+       tosend.type = NOTHING;
+       tosend.step = 500;
+       tosend.client_callbacks = client_interactions;
+       
+       printf("Testing client-first/no-server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_clientfirst,&tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of client-first/no-server-last...ok\n");
+
+       printf("Testing no-client-first/no-server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_noclientfirst, &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of no-client-first/no-server-last...ok\n");
+       
+       printf("Testing no-client-first/server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_noclientfirst_andserverlast,
+                         &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of no-client-first/server-last...ok\n");
+
+       printf("Testing client-first/server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_serverlast, &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of client-first/server-last...ok\n");
+
+       tosend.client_callbacks = client_callbacks;
+       printf("-=-=-=-=- And now using the callbacks interface -=-=-=-=-\n");
+
+       printf("Testing client-first/no-server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_clientfirst,&tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of client-first/no-server-last...ok\n");
+
+       printf("Testing no-client-first/no-server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_noclientfirst, &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of no-client-first/no-server-last...ok\n");
+       
+       printf("Testing no-client-first/server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_noclientfirst_andserverlast,
+                         &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of no-client-first/server-last...ok\n");
+
+       printf("Testing client-first/server-last correctly...\n");
+       foreach_mechanism((foreach_t *) &test_serverlast, &tosend);
+       if(mem_stat() != SASL_OK) fatal("memory error");
+       printf("Test of client-first/server-last...ok\n");
+    } else {
+       printf("Testing client-first/no-server-last correctly...skipped\n");
+       printf("Testing no-client-first/no-server-last correctly...skipped\n");
+       printf("Testing no-client-first/server-last correctly...skipped\n");
+       printf("Testing client-first/server-last correctly...skipped\n");
+       printf("Above tests with callbacks interface...skipped\n");
+    }
+    
+    /* FIXME: do memory tests below here on the things
+     * that are MEANT to fail sometime. */
+    if(do_all) {       
+       printf("All corruption tests...\n");
+       test_all_corrupt();
+       printf("All corruption tests... ok\n");
+    }
+    
+    if(random_tests) {
+       printf("Random corruption tests...\n");
+       test_rand_corrupt(random_tests);
+       printf("Random tests... ok\n");
+    } else {
+       printf("Random tests... skipped\n");
+    }
+
+    printf("Testing Proxy Policy...\n");
+    test_proxypolicy();
+    printf("Tests of Proxy Policy...ok\n");
+
+    printf("Testing security layer...\n");
+    test_seclayer();
+    printf("Tests of security layer... ok\n");
+
+    printf("All tests seemed to go ok (i.e. we didn't crash)\n");
+
+    free(g_secret);
+
+    exit(0);
+}
diff --git a/win32/.cvsignore b/win32/.cvsignore
new file mode 100644 (file)
index 0000000..13bb78d
--- /dev/null
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+.deps
+.libs
+*.l[ao]
diff --git a/win32/.cvswrappers b/win32/.cvswrappers
new file mode 100644 (file)
index 0000000..a604af4
--- /dev/null
@@ -0,0 +1,5 @@
+# VC++ Files are BINARY
+
+*.dsp -k 'b'
+*.dsw -k 'b'
+*.reg -k 'b'
diff --git a/win32/common.mak b/win32/common.mak
new file mode 100644 (file)
index 0000000..4e11e4a
--- /dev/null
@@ -0,0 +1,173 @@
+#Can this be autogenerated?
+#Keep in sync with include/sasl.h and win32/include/config.h
+SASL_VERSION_MAJOR=2
+SASL_VERSION_MINOR=1
+SASL_VERSION_STEP=23
+
+# Uncomment the following line, if you want to use Visual Studio 6
+#VCVER=6
+
+# Define compiler/linker/etc.
+
+CPP=cl.exe /nologo
+LINK32=link.exe /nologo
+LINK32DLL=$(LINK32) /dll
+LINK32EXE=$(LINK32)
+
+SYS_LIBS=ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib
+
+# Define the minimal Windows OS you want to run on:40 (NT), 50 (W2K), 51 (XP)
+# Default is no restrictions. Currently we only check for 51 or later.
+#TARGET_WIN_SYSTEM=51
+
+!IF "$(TARGET_WIN_SYSTEM)" == ""
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Applications and libraries should run on any Win32 system.
+!ENDIF
+TARGET_WIN_SYSTEM=0
+!ENDIF
+
+# prefix variable is currently only being used by install target
+!IF "$(prefix)" == ""
+prefix=C:\CMU
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Default installation directory is $(prefix).
+!ENDIF 
+!ENDIF
+
+!IF "$(CFG)" == ""
+CFG=Release
+!IF "$(VERBOSE)" != "0"
+!MESSAGE No configuration specified. Defaulting to $(CFG).
+!ENDIF
+!ENDIF 
+
+!IF "$(DB_LIB)" == ""
+DB_LIB=libdb41s.lib
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting SleepyCat library name to $(DB_LIB).
+!ENDIF
+!ENDIF
+
+!IF "$(DB_INCLUDE)" == ""
+DB_INCLUDE=c:\work\isode\db\build_win32
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting SleepyCat include path to $(DB_INCLUDE).
+!ENDIF
+!ENDIF
+
+!IF "$(DB_LIBPATH)" == ""
+DB_LIBPATH=c:\work\isode\db\build_win32\Release_static
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting SleepyCat library path to $(DB_LIBPATH).
+!ENDIF
+!ENDIF
+
+!IF "$(OPENSSL_INCLUDE)" == ""
+OPENSSL_INCLUDE="D:\openssl\engine-0.9.6g-md3\include"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting OpenSSL Include path to $(OPENSSL_INCLUDE).
+!ENDIF
+!ENDIF
+
+!IF "$(OPENSSL_LIBPATH)" == ""
+OPENSSL_LIBPATH="D:\openssl\engine-0.9.6g-md3\lib"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting OpenSSL library path to $(OPENSSL_LIBPATH).
+!ENDIF
+!ENDIF
+
+!IF "$(GSSAPI_INCLUDE)" == ""
+GSSAPI_INCLUDE="C:\Program Files\CyberSafe\Developer Pack\ApplicationSecuritySDK\include"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting GSSAPI Include path to $(GSSAPI_INCLUDE).
+!ENDIF
+!ENDIF
+
+!IF "$(GSSAPI_LIBPATH)" == ""
+GSSAPI_LIBPATH="C:\Program Files\CyberSafe\Developer Pack\ApplicationSecuritySDK\lib"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting GSSAPI library path to $(GSSAPI_LIBPATH).
+!ENDIF
+!ENDIF
+
+!IF "$(SQLITE_INCLUDE)" == ""
+SQLITE_INCLUDES=/I"C:\work\open_source\sqllite\sqlite\src" /I"C:\work\open_source\sqllite\sqlite\win32"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting SQLITE_INCLUDES includes to $(SQLITE_INCLUDES).
+!ENDIF
+!ENDIF
+
+!IF "$(SQLITE_LIBPATH)" == ""
+SQLITE_LIBPATH="C:\work\open_source\sqllite\sqlite\objs"
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting SQLITE library path to $(SQLITE_LIBPATH).
+!ENDIF
+!ENDIF
+
+!IF "$(LDAP_LIB_BASE)" == ""
+LDAP_LIB_BASE = c:\work\open_source\openldap\openldap-head\ldap\Debug
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting LDAP library path to $(LDAP_LIB_BASE).
+!ENDIF
+!ENDIF
+
+!IF "$(LDAP_INCLUDE)" == ""
+LDAP_INCLUDE = c:\work\open_source\openldap\openldap-head\ldap\include
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Defaulting LDAP include path to $(LDAP_INCLUDE).
+!ENDIF
+!ENDIF
+
+!IF "$(OS)" == "Windows_NT"
+NULL=
+!ELSE 
+NULL=nul
+!ENDIF
+
+
+!IF  "$(CFG)" == "Release"
+
+!IF "$(CODEGEN)" == ""
+!IF "$(STATIC)" == "yes"
+CODEGEN=/MT
+!ELSE
+CODEGEN=/MD
+!ENDIF 
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Codegeneration defaulting to $(CODEGEN).
+!ENDIF 
+!ENDIF 
+
+!IF "$(VCVER)" != "6"
+ENABLE_WIN64_WARNINGS=/Wp64
+!ENDIF
+
+CPP_PROJ= $(CODEGEN) /W3 /GX /O2 $(ENABLE_WIN64_WARNINGS) /Zi /D "NDEBUG" $(CPPFLAGS) /FD /c 
+
+LINK32_FLAGS=/incremental:no /debug /machine:I386
+
+!ELSEIF  "$(CFG)" == "Debug"
+
+!IF "$(CODEGEN)" == ""
+!IF "$(STATIC)" == "yes"
+CODEGEN=/MTd
+!ELSE
+CODEGEN=/MDd
+!ENDIF 
+!IF "$(VERBOSE)" != "0"
+!MESSAGE Codegeneration defaulting to $(CODEGEN).
+!ENDIF 
+!ENDIF 
+
+CPP_PROJ=$(CODEGEN) /W3 /Gm /GX /ZI /Od /D "_DEBUG" $(CPPFLAGS) /FD /GZ /c 
+
+LINK32_FLAGS=/incremental:yes /debug /machine:I386 /pdbtype:sept 
+
+!ENDIF
+
+LINK32DLL_FLAGS=$(LINK32_FLAGS) $(SYS_LIBS) $(EXTRA_LIBS)
+
+# Assume we are only building console applications
+LINK32EXE_FLAGS=/subsystem:console $(LINK32_FLAGS) $(SYS_LIBS) $(EXTRA_LIBS)
+
diff --git a/win32/include/.cvsignore b/win32/include/.cvsignore
new file mode 100644 (file)
index 0000000..13bb78d
--- /dev/null
@@ -0,0 +1,5 @@
+Makefile.in
+Makefile
+.deps
+.libs
+*.l[ao]
diff --git a/win32/include/NTMakefile b/win32/include/NTMakefile
new file mode 100644 (file)
index 0000000..21bb47e
--- /dev/null
@@ -0,0 +1,65 @@
+# NTMakefile for SASL, win32\include directory\r
+# Alexey Melnikov\r
+#\r
+################################################################\r
+# Copyright (c) 2003 Carnegie Mellon University.  All rights reserved.\r
+#\r
+# Redistribution and use in source and binary forms, with or without\r
+# modification, are permitted provided that the following conditions\r
+# are met:\r
+#\r
+# 1. Redistributions of source code must retain the above copyright\r
+#    notice, this list of conditions and the following disclaimer. \r
+#\r
+# 2. Redistributions in binary form must reproduce the above copyright\r
+#    notice, this list of conditions and the following disclaimer in\r
+#    the documentation and/or other materials provided with the\r
+#    distribution.\r
+#\r
+# 3. The name "Carnegie Mellon University" must not be used to\r
+#    endorse or promote products derived from this software without\r
+#    prior written permission. For permission or any other legal\r
+#    details, please contact  \r
+#      Office of Technology Transfer\r
+#      Carnegie Mellon University\r
+#      5000 Forbes Avenue\r
+#      Pittsburgh, PA  15213-3890\r
+#      (412) 268-4387, fax: (412) 268-7395\r
+#      tech-transfer@andrew.cmu.edu\r
+#\r
+# 4. Redistributions of any form whatsoever must retain the following\r
+#    acknowledgment:\r
+#    "This product includes software developed by Computing Services\r
+#     at Carnegie Mellon University (http://www.cmu.edu/computing/)."\r
+#\r
+# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO\r
+# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r
+# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE\r
+# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\r
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN\r
+# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING\r
+# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\r
+#\r
+################################################################\r
+\r
+#Suppress verbose output from defaulting values\r
+VERBOSE=0\r
+\r
+!INCLUDE ..\common.mak\r
+\r
+includedir = $(prefix)\include\r
+\r
+saslincludedir = $(includedir)\sasl\\r
+\r
+saslinclude_HEADERS = md5global.h\r
+\r
+# The first target get executed by default. We don't want this to be "install"\r
+all:\r
+       @echo Nothing to be done for $@\r
+\r
+#\r
+# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels\r
+#\r
+install: $(saslinclude_HEADERS)\r
+       !xcopy md5global*.h $(saslincludedir) /I /F /Y\r
+       !xcopy $? $(saslincludedir) /I /F /Y\r
diff --git a/win32/include/config.h b/win32/include/config.h
new file mode 100644 (file)
index 0000000..4fb0241
--- /dev/null
@@ -0,0 +1,208 @@
+/* config.h--SASL configuration for win32
+ * Ryan Troll
+ */
+/* 
+ * Copyright (c) 1998-2004 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 <stddef.h>
+
+/* winsock2 includes windows.h.
+   Note that we can't include both winsock.h and winsock2.h as
+   they conflict */
+#include <winsock2.h>
+
+/* Our package */
+#define PACKAGE "cyrus-sasl"
+
+/* Our version */
+#define VERSION "2.1.23"
+
+/* Visual Studio supports prototypes */
+#define PROTOTYPES     1
+
+#ifndef HAVE_CADDR_T
+#ifndef        caddr_t
+typedef unsigned char   *caddr_t;
+#define HAVE_CADDR_T   1
+#endif
+#endif
+
+#ifndef _INTPTR_T_DEFINED
+
+#ifdef  _WIN64
+typedef __int64             intptr_t;
+#else
+typedef int                intptr_t;
+#endif
+
+#endif
+
+/* Registry key that contains the locations of the plugins */
+#define SASL_ROOT_KEY "SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library"
+#define SASL_PLUGIN_PATH_ATTR "SearchPath"
+#define SASL_CONF_PATH_ATTR "ConfFile"
+
+/* : This should probably be replaced with a call to a function
+   : that gets the proper value from Registry */
+#define SASL_DB_PATH "c:\\CMU\\sasldb2"
+
+/* what db package are we using? */
+/* #undef SASL_GDBM */
+/* #undef SASL_NDBM */
+#define SASL_BERKELEYDB 1
+
+/* which mechs can we link staticly? */
+#define STATIC_ANONYMOUS 1
+#define STATIC_CRAMMD5 1
+#define STATIC_DIGESTMD5 1
+#define STATIC_GSSAPIV2 1
+/* #undef STATIC_KERBEROS4 */
+#define STATIC_LOGIN 1
+/* #undef STATIC_MYSQL */
+#define STATIC_OTP 1
+#define STATIC_PLAIN 1
+#define STATIC_SASLDB 1
+#define STATIC_SRP 1
+
+/* ------------------------------------------------------------ */
+
+/* Things that are fetched via autoconf under Unix
+ */
+#define HAVE_MEMCPY 1
+
+#define PLUGINDIR "C:\\CMU\\bin\\sasl2"
+#define CONFIGDIR "C:\\CMU\\bin\\sasl2"
+
+/* Windows calls these functions something else
+ */
+#define strcasecmp   stricmp
+#define snprintf    _snprintf
+#define strncasecmp  strnicmp
+
+#define MAXHOSTNAMELEN 1024
+
+/* ------------------------------------------------------------ */
+
+#define WITHOUT_NANA
+#define L_DEFAULT_GUARD (0)
+#define I_DEFAULT_GUARD (0)
+#define I(foo)
+#define VL(foo)  printf foo;
+#define VLP(foo,bar)
+
+/* we're not gcc */
+#define __attribute__(foo)
+
+/* : Same as in tpipv6.h */
+#ifndef HAVE_SOCKLEN_T
+typedef int socklen_t;
+#endif /* HAVE_SOCKLEN_T */
+
+/* If we expect to run on XP and later, we have IPv6 support natively */
+#if TARGET_WIN_SYSTEM >= 51
+#if !defined(_WIN32_WINNT)
+/* This forces the inclusion of OS supported functions, with no fallback */
+#define _WIN32_WINNT   0x0510
+#endif
+#endif
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1300)
+/* The following two defines will prevent our own definitions below */
+#define HAVE_GETADDRINFO
+#define HAVE_GETNAMEINFO
+#define HAVE_STRUCT_SOCKADDR_STORAGE
+/* Unless _WIN32_WINNT > 0x0500, Ws2tcpip.h will try to find OS provided
+   getaddrinfo at runtime. It will fallback to Microsoft emulation,
+   if not found */
+#include <Ws2tcpip.h>
+#endif
+
+#if !defined(HAVE_STRUCT_SOCKADDR_STORAGE) && !defined(_SS_MAXSIZE)
+#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        gai_strerror    sasl_gai_strerror
+#endif
+
+#ifndef HAVE_GETNAMEINFO
+#define        getnameinfo     sasl_getnameinfo
+#endif
+
+#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO)
+#include "gai.h"
+#endif
+
+#ifndef AI_NUMERICHOST   /* support glibc 2.0.x */
+#define AI_NUMERICHOST  4
+#define NI_NUMERICHOST  2
+#define NI_NAMEREQD     4
+#define NI_NUMERICSERV  8
+#endif
+
+#include <time.h>
+
+typedef int ssize_t;
+
+#define HIER_DELIMITER '\\'
+
+#ifndef sleep
+#define sleep(seconds)         plug_sleep(seconds)
+unsigned int plug_sleep(unsigned int seconds);
+#endif
+
+#endif /* CONFIG_H */
diff --git a/win32/include/md5global.h b/win32/include/md5global.h
new file mode 100644 (file)
index 0000000..42af9a2
--- /dev/null
@@ -0,0 +1,38 @@
+/* GLOBAL.H - RSAREF types and constants\r
+ */\r
+#ifndef MD5GLOBAL_H\r
+#define MD5GLOBAL_H\r
+\r
+/* PROTOTYPES should be set to one if and only if the compiler supports\r
+  function argument prototyping.\r
+The following makes PROTOTYPES default to 0 if it has not already\r
+  been defined with C compiler flags.\r
+ */\r
+#ifndef PROTOTYPES\r
+#define PROTOTYPES 0\r
+#endif\r
+\r
+/* POINTER defines a generic pointer type */\r
+typedef unsigned char *POINTER;\r
+\r
+typedef signed char INT1;              /*  8 bits */\r
+typedef short INT2;                    /* 16 bits */\r
+typedef int INT4;                      /* 32 bits */\r
+/* There is no 64 bit type */\r
+typedef unsigned char UINT1;           /*  8 bits */\r
+typedef unsigned short UINT2;          /* 16 bits */\r
+typedef unsigned int UINT4;            /* 32 bits */\r
+/* There is no 64 bit type */\r
+\r
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.\r
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it\r
+returns an empty list.\r
+*/\r
+#if PROTOTYPES\r
+#define PROTO_LIST(list) list\r
+#else\r
+#define PROTO_LIST(list) ()\r
+#endif\r
+\r
+#endif /* MD5GLOBAL_H */\r
+\r